I moved this blog from Tumblr, where it has been hosted for nine years now, to a static Jekyll site stored on Amazon S3. The site is generated and deployed automatically by Travis, and served through Amazon Cloudfront to allow SSL/HTTPS.
The setup is very simple, and I like how easy it is to add new posts by doing git push . There were a few steps and a little configuration to get it to work, however, so I thought I should write it down in case someone else (or future me) is interested in doing something similar.
Here’s a quick overview of what I will go through:
Change your current Jekyll setup. Assuming the site is using Jekyll already. Create an S3 bucket that will be used to serve the site. Add a Travis config that will build the Jenkins site and upload (deploy) the result to the S3 bucket. Create a Cloudfront distribution that serves the S3 bucket, enabling fast content delivery through HTTPS/HTTP2 and custom domain names. Changing your current DNS records to point to the Cloudfront distribution. Create a certificate for your domain through Let’s Encrypt, download it, and upload it to Amazon’s IAM service. Changing the Cloudfront distribution in step 4 to use the new certificate.It’s worth mentioning that if you are already hosting your site somewhere under the domain name that you will use in step 6 above, you can go ahead and create the certificate before doing anything else. It will save you some time since you can configure SSL (step 7) while you are creating the Cloudfront distribution (step 4).
JekyllYou don’t really need to change anything in your Jekyll setup. Travis should be able to build the site if your Gemfile is up to date.
The only thing to think of, if you are using Jekyll, is to make sure that your _config.yml contains this line:
include: - .well-knownThis allows Jekyll to include the Let’s Encrypt challenge when your site is generated. Otherwise, directories beginning with a . (period/dot) will not be included in the generated site.
S3Go into the S3 console and create a new S3 bucket to store your site. The bucket needs to have a bucket policy and to have static website hosting enabled.
Under bucket properties, permissions, click “Edit bucket policy” and enter the following:
{ "Version": "2012-10-17", "Id": "Policy1479987077386", "Statement": [ { "Sid": "Stmt1479987075203", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::[your bucket name]/*" } ] }Under the “Static Website Hosting” pane, enable static website hosting. Set index document to index.html . If you have a custom error document, you can update the error document setting now as well.
If you upload a document called index.html , your site should be accessible through a URL like [your-bucket-name].s3-website-[aws-region].amazonaws.com . Make sure it works now by opening this address in your browser. TravisEdit your .travis file to look like this:
language: ruby cache: bundler rvm: - 2.2.2 branches: only: - master script: - bundle exec jekyll build deploy: provider: s3 bucket: your-bucket-name # Update this skip_cleanup: true region: eu-west-1 # Or whatever region you use local_dir: _site on: branch: master # You can use another branch if you want dot_match: trueUpdate the rvm section to match the version of Ruby that you want to use. I’m building from the master branch, but you might want to change that to a different branch name too. The dot_match setting will make sure that files beginning with . (period/dot) are being uploaded to S3 as well.
Copy your access key id from Amazon (I created a new user for the purpose of serving this site, with access only to the S3 bucket), then paste it when the following command asks for input. Finish by pressing control-D :
travis encrypt --add deploy.access_key_id
Do the same for the secret access key:
travis encrypt --add deploy.secret_access_key
The above should have added two encrypted keys to your .travis file:
deploy: provider: s3 access_key_id: secure: secret_access_key: secure:Now Travis should be able to build and deploy your site when you push a commit to your remote repo (I use Github).
CloudfrontAWS Cloudfront is a CDN that you can use to serve any static content. In our case, it makes it possible to serve pages from S3 with HTTP, HTTPS and HTTP2.
We don’t have a certificate, so we can’t enable SSL/HTTPS yet, but we need to be able to access the site through the custom domain before we generate a Let’s Encrypt certificate. Otherwise the Let’s Encrypt verification won’t work.
If you are already hosting your site somewhere else, you can wait with this step until you have the Let’s Encrypt certificate.
Now that we have an S3 bucket with a static site, we can go into the Cloudfront console and create a new distribution. Make it a web distribution, and change the following values:
Origin Domain Name: [your-bucket-name].s3-website-[aws-region].amazonaws.comDon’t select the S3 bucket, directory indexing will not work if you do. Default Root Object: index.html
The AWS region should be on the format “eu-west-1”.
Wait a couple of minutes for the new distribution to be created. Check the status column to know when it’s active. According to Amazon, it should take less than 15 minutes.
Create or update your DNS records. Make a CNAME record that points to the cloudfront.net domain visible in the Cloudfront console. For example:
www.laszlo.nu. CNAME d19chveh49i9t2.cloudfront.net. Let’s EncryptIt’s probably easier to use AWS Certificate Manager , but I like Let’s Encrypt, so I generated a new certificate for my site using Certbot in manual mode. Then I uploaded the certificate to IAM using the AWS command line tool .
Get Certbot if you don’t have it installed. There are installation instructions for many OSes and distributions on the Certbot site.
Once you have Certbot, the following command will generate and download the new certificate to /tmp/certbot/config/live/example.com :
certbot certonly \ --manual \ --logs-dir=/tmp/certbot/logs \ --work-dir=/tmp/certbot/work \ --config-dir=/tmp/certbot/config Enter your domain name, or several domain names. To verify that you are the owner of the domain, you have to create files on your site under the /.well-known/acme-challenge/ directory. You will get one