Cees-Jan

Deploying Sculpin to S3 with CircleCI

Until 10 minutes before the start of this month I had a VPS at Digital Ocean running with Jenkins and Gitolite on it for privately hosted repositories. With Github's recent move to unlimited repositories I really didn't have a need to host them myself anymore, and after playing with CircleCI's free tier it didn't make any sense anymore to keep that VPS up.

Deployment

Since porting git over to another remote is as more Github's domain we're focusing on deploying Sculpin to S3 using CircleCI in this post.

Prerequisites

  • A Sculpin blog on Github, in my case that was simple because I already put my blog on github a while ago so others could send PR's
  • A S3 bucket setup to use
  • A special IAM User and it's keys just for this project and deploying with CircleCI that has access to the S3 bucket containing the blog

To get started make sure your blog is on Github, and that you have create a new build/project in CircleCI.

IAM User

We need an IAM User to access the bucket securely. I'm leaving the correct permissions up to you as they might differ on a specific case basis. What we do need are the key and secret for the user. Enter those under Project Settings ->Permissions ->AWS Permissions.

AWS Permissions

circle.yml

Next up is creating a circle.yml file that will instruct CircleCI what to do when we push commits or create tag.

First we need to tell it that we use PHP, and since I prefer things to be bleeding edge we'll be using PHP 7 here:

machine:
  php:
    version: 7.0.4

Dependencies

We also cache the vendor directory for a quick composer install in case nothing changed and composer's cache directory in case we need to install new packages/updated/downgraded packages we might have in cache. CircleCI takes care of running composer install for us. Unless we like to add extra flags we have no need to overwrite that:

dependencies:
  cache_directories:
    - vendor
    - ~/.composer/cache

Tests

CircleCI assumes that every build runs tests. In case of PHP projects it will attempt to run phpunit but I'm using GrumPHP for my blog as very simple unit tests have been added and I'm working on a linter for Sculpin that ensure it catches issues before generation. Since all my posts these days are written using pull requests, so is this post, the linter will catch any issues while working on it.

test:
  pre:
    - mkdir -p $CIRCLE_TEST_REPORTS/phpunit
  override:
    - ./vendor/bin/grumphp run
  post:
    - cp /tmp/junit.xml $CIRCLE_TEST_REPORTS/phpunit/junit.xml

The pre and post are there to inform CircleCI of our tests results and show us information about it like this:

jUnit result

Deployment

Deployment settings are what controls when you publish changes. In my setup I tag releases for deployment. Another way would be a special deployment branch but I find this easier to manage. It is up to you how you prefer to deploy, CircleCI has you covered.

Once a tag has been created the commands kick into action. The first command will generate the blog or display an error when it fails. The second command syncs the generated site to S3. The interesting bit about the aws command is that it is installed by default in the build container and uses the credentials we set earlier in this post.

deployment:
  production:
    tag: /.*/
    commands:
      - vendor/bin/sculpin generate --env=prod
      - aws s3 sync output_prod/ s3://the-s3-bucket-name/

When combining that we come to the final result:

machine:
  php:
    version: 7.0.4
dependencies:
  cache_directories:
    - vendor
    - ~/.composer/cache
test:
  pre:
    - mkdir -p $CIRCLE_TEST_REPORTS/phpunit
  override:
    - ./vendor/bin/grumphp run
  post:
    - cp /tmp/junit.xml $CIRCLE_TEST_REPORTS/phpunit/junit.xml
deployment:
  production:
    tag: /.*/
    commands:
      - vendor/bin/sculpin generate --env=prod
      - aws s3 sync output_prod/ s3://the-s3-bucket-name/

Conclusion

CircleCI makes deploying to AWS S3 simple and easy with integrated option to set keys and pre-installed AWS command. This doesn't just work for a PHP based static site generator but with a few tweaks it works just as easy with generators for other languages.


Categories: PHP - Sculpin - CircleCITags: PHP - S3 - AWS - Sculpin - CircleCI - Deployment