Jeff Mesnil
Weblog · About

How to Host a Static Website on Amazon AWS

February 11, 2013

A few months ago, I updated my web site to use static content generated by Awestruct instead of a hosted WordPress instance. It is much simpler to maintain and tweak (something I am constantly doing), less expensive to host since it does not need any runtime or database and static content is fast, cacheable, etc.

At the same time, I moved the hosting from OVH to Amazon S3 which provides static web site hosting at a very competitive price.

More recently, I acquired a Retina MacBook Pro and updated my web site to display Retina-ready responsive images. This requires to server several JPEG files of the same image at various sizes. Retina images may be quite big and using a content delivery service improves the latency to serve these images. I decided to use Amazon CloudFront for content delivery of all my media assets.

This post is a quick reference of the different services and settings I have used to achieve this goal.

Web Site Generation

The source code of my web site is hosted at Github and uses Awestruct to generate its content. I write the posts (including this one) using Markdown syntax and Awestruct generates the whole web site for me (including an Atom feed, archive page, sitemap, etc.)

Deployment

The content is hosted in a S3 bucket named jmesnil.net and is deployed to S3 using Awestruct directly:

$ cat _config/site.yml
...
profiles:
  production:
    deploy:
      type: s3
      bucket: s3://jmesnil.net/
$ awestruct -P production --deploy
...
Syncing XXX/jmesnil.net/_site to bucket s3://jmesnil.net/

I contributed the S3 deployment to Awestruct recently and there is no release with that feature yet. Alternatively, you can use s3cmd.

Static Website Hosting

I use Amazon S3 to host the static content in a bucket jmesnil.net (without the www) and enable the Static Website Hosting in its properties.

I prefer to use the jmesnil.net domain name to serve my content but I also want www.jmesnil.net to work and redirect to the naked domain name.

To achieve this, I need a second S3 bucket named www.jmesnil.net. However, instead of enabling website hosting, its Static Website Hosting property is set to Redirect all requests to another host name (using the value jmesnil.net).

This 2nd bucket will remain empty (nothing is deployed to it) but is required to redirect content from www.jmesnil.net.

Domain Names

Amazon Route 53 is a domain name service that I use to provide the domain names of my web site.

I created a hosted name for jmesnil.net with the following record sets:

  • jmesnil.net. is a A type record that is an ALIAS to the S3 bucket jmesnil.net (the dropdown list will propose all the S3 buckets you own)
  • www.jmesnil.net. is CNAME type record corresponding to the S3 bucket www.jmesnil.net public domain name (i.e. in my case it is www.jmesnil.net.s3-website-us-east-1.amazonaws.com).

Using Amazon S3 and Route 53, it is very simple and cost-effective to host a static web site1. Using Awestruct makes it simple and fun to write content for it :)

Amazon provides good documentation for its Web services including a full tutorial to set up a static website using a custom domain.

Content Delivery Service

For ech retina-ready responsive image I want to display, I need to export eight JPEG files from Lightroom.

My media assets (including these images) are deployed in a S3 bucket named media.jmesnil.net using s3cmd and I enabled the Static Website Hosting for it.

To use Amazon CloudFront as my content delivery service for the media assets, I created a Download distribution from the S3 bucket media.jmesnil.net.

Content delivered by CloudFront is served from a XXX.cloudfront.net domain name. Since I want to keep all my content under my own domain name, I use Route 53 again to serve the CloudFront content from media.jmesnil.net.

In Route 53's hosted zone for jmesnil.net, I added a new record set for media.jmesnil.net which is a CNAME type set to the CloudFront domain name (i.e. XXX.cloudfront.net). Then in Cloudfront distribution, I added media.jmesnil.net as an Alternate Domain Name.

To sum up:

  • http://jmesnil.net/XXX is served by the S3 bucket jmesnil.net
  • http://www.jmesnil.net/YYY is redirected to the naked URL http://jmesnil.net/YYY
  • http://media.jmesnil.net/ZZZ is using CloudFront to deliver the media assets and is backed by the S3 bucket media.jmesnil.net

All my content is served by URLs under my domain name jmesnil.net. With this configuration, I will not be depending on any third-party URLs for my own content If I decide one day to move to another hosted service or platform2.


  1. I leave as an exercise to the reader how to setup Awestruct, S3 and Route 53 to provide a staging web site at http://staging.jmesnil.net/ to check before going live on the "production" URL at http://jmesnil.net/ :) 
  2. And I certainly will: since I started my weblog in 2004, I moved from Movable Type to Blogger to Wordpress to Jekyll and finally to Awestruct for the software and from jroller to OVH to S3 for the hosting.