Static sites with Middleman, Amazon S3 and HTTPS

Jan 29

At Trolley we love Middleman - it's what we use to build our own site for Trolley

And we host on Amazon S3 because It's almost free, very secure, fast and highly reliable - perfect for static sites.

Here's a quick guide to how we did it, and how you can do it too.

Overview & pre-requisites

You'll be using

So before you start, make sure you've got an Amazon AWS account (it's free / cheap if you haven't got one)

Creating a skeleton site with Middleman

I'm going to assume some basic familiarity with Middleman. If you haven't used it before, then follow the install guide and then go through the tutorial.

Once you understand the basics, and you're in a position where executing middleman --help shows you something useful, then we can create your new site.

mkdir my_new_site
cd my_new_site
middleman init

Middleman creates you a directory structure like this:

.
├── Gemfile
├── Gemfile.lock
├── config.rb
└── source
    ├── images
    ├── index.html.erb
    ├── javascripts
    │   └── site.js
    ├── layouts
    │   └── layout.erb
    └── stylesheets
        └── site.css.scss

Populating some basic content

The default index.html.erb from Middleman is just a placeholder. Replace the contents of the files with the following:

---
title: My New Site
---


<h1>My New Site</h1>

<p>This is the home page of my new website.</p>

<p>Later, I'd like to fill it with glorious, original, highly-converting content.</p>

Get the Amazon CLI tools

If you haven't got these already, you'll need them to be able to sync the built website to your S3 bucket.

pip install awscli --upgrade --user

And then set the contents of ~/.aws/credentials to be your AWS access key settings. It's best to create a new user in the AWS console just for this and give them appropriate permissions. Doing this is outside the scope of this post - but there are really good instructions here

If you want, you can skip the command line bit and just manually upload files to S3 through the web UI, but it's really slow - make the effort to set up the command line tools and it'll pay off.

AWS_DEFAULT_REGION=us-east-1
AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY
AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY

Setting up an S3 bucket for static site deployment

Back to the AWS web console again and head to the S3 section

Enable the Static Website Hosting option. Make sure to set the Index document to index.html

Static website hosting options

Now go to Properties -> Permissions and edit the bucket policy to something liek this (change the bucket name)

{
 "Version": "2012-10-17",
 "Id": "PublicBucketPolicy",
 "Statement": [
  {
   "Sid": "Stmt1482880670019",
   "Effect": "Allow",
   "Principal": "*",
   "Action": "s3:GetObject",
   "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
  }
 ]
}

Setting up CloudFront and SSL for your static site

Time to setup the caching CDN - CloudFront. This is also how you get SSL for free!

Go to the CloudFront console and hit the Create Distribution button, then "Get Started" under Web on the next screen.

CloudFront config

Set the Origin Domain Name to be the S3 bucket we're using.

Set Viewer Protocol Policy to be "Redirect HTTP to HTTPS"

If you wanted to use a custom domain, e.g. www.mydomain.com to host your site, you'd ensure you had a domain created in Route53 now, then fill in Alternate Domain Names with mydomain.com and www.mydomain.com. Right now we're just going to host from the default *.cloudfront.net domain to make things easy.

Scroll down and find Default Root Object. Enter index.html here.

Click the Create Distribution button at the bottom and wait til it reports it's finished.

Building and deploying your Middleman site to S3

Time to build your site for deployment. In your terminal, enter the root of the project (e.g. my_new_site) and execute:

bundle exec middleman build

If you have a look in the directory now, you'll find a subdirectory called dist, containing a fully built static site that you can load in a browser by opening index.html.

Now sync (copy) the files to the S3 bucket:

aws s3 sync build s3://BUCKET_NAME \
  --acl public-read --cache-control "public, max-age=86400"

Now open your web browser to the URL listed on the CloudFront console - it'll be something like d4l8iqw04z8zhn.cloudfront.net - and you should see your site, running fully secured on HTTPS.

The end result

Contact

We love questions, feedback and suggestion.

You can email us at rg@trolley.link

Or tweet us at @trolleypayments