Hosting a static site using Hakyll and AWS

January 21, 2019

After getting fed-up with WordPress, I wanted to migrate onto some sort of static site generation. And since you’re reading these words right now, it looks like that migration succeeded!

I ended up choosing Hakyll and Amazon S3 as my build and hosting solutions of choice, and I’m pretty happy with both. (Although some of the other elements of the AWS ecosystem, not so much. More on that later.) This post is more as a reference for myself, in case I need to tear things down or things go haywire.

Why Hakyll?

Honestly, because I felt like it. It’s Haskell, it seems interesting, so why not. Yeah, yeah, I know it’s not really a great reason.

The biggest advantage is that it comes with Pandoc support right out of the box, which lets me be very flexible in how I write my posts/content. In particular, being able to compile Literate Haskell files without needing to jump through any hoops is massive.

Hakyll is also very much “configuration over convention,” and the entire site specification is just a normal Haskell program. While the amount of flexibility and customization is a little overkill for what I have right now, it’s comforting to know that I’ll never have to twist the site out of shape to get it to do something unusual.

Cool, so how is this site working at all?

The 10,000-meter view of this blog is:

  1. I write blog posts in $EDITOR and keep track of them with Git
  2. New posts get pushed up to AWS CodeCommit (aka. AWS’ heavily gimped version of GitHub)
  3. I trigger a build of the site using AWS CodeBuild, using a custom-built Docker image with Hakyll installed
  4. Once finished, CodeBuild uploads the site assets to S3
  5. AWS CloudFront and Route 53 handle the arcane magic of connecting the URL in your browser to S3

Most of this should be pretty easy to set up, although there are a few subtleties:

So yeah, there you have it. A (kind of) working build and deployment system for a Hakyll-based site! Seriously, just go use GitLab or GitHub Pages.

Before you close that tab...