Static Website Deployments on AWS Made Easy
Last month at Planes, we had a project that was prime for static hosting: a very small piece of UI that would be used globally and need to scale to 100,000 concurrent users. I began browsing hosting options and narrowed it down to the following:
Surge.sh — easy deployment, files served over a CDN, and seemed like I’d only need the free tier for this project.
GitHub Pages — super fast and very easy to deploy but lacked some functionality I’d needed for other projects, such as the ability to add client-side routing, which wouldn’t be a blocker on this occasion.
Some sort of AWS setup — I had no idea what this would look like at this point but knew that it would be the ‘legit’ option.
Deploying to AWS S3 and CloudFront isn’t easy, or at least a faff! You’ll find yourself dipping in and out of the AWS dashboard hourly, and, if you are like me, not enjoying it. Deploying involves tying in a number of different services that all seem daunting and over-cumbersome in the age of development we are in. I’m a sucker for things being automated or beautiful, and the AWS console ticks neither box for me. 😬
Surge supports deployment to a CDN in seconds and prides itself on allowing developers to ‘not leave the command line’. Ka-ching! I’d already loved using Surge.sh on another project so jumped straight to it. $ surge ./build my-domain.com is all you need to deploy. I had some overriding albeit unfounded concerns, including that Surge wouldn’t be able to handle the project’s requirements of up to 100,000 concurrent users because, well, it seemed too good to be true. I took this worry to Surge’s Slack channel but was quickly defused by the creator, who responded with, “Just let us know when you are going live, shouldn’t be a problem.” 😍 And although I was now feeling more or less confident, it didn’t seem right to risk the project and add workload to Surge when I’m not even a paid plan customer! This led me to compare against GitHub Pages…
Publishing to GitHub Pages is as easy as creating a branch with your built site and pushing to it or with the gh-pages cli with command gh-pages -d ./build. Simple!
Following some basic performance load time testing to compare with Surge, the results were pretty conclusive; Surge.sh was loading in about 300–500ms, whereas GitHub was under 100ms. But despite its lightning-fast page load times and easy deployment, GitHub Pages does have limits on bandwidth. With this in mind, the ‘legit’ AWS setup seemed the only option.
AWS S3 and CloudFront
AWS’ S3 provides a way of hosting static assets most frequently used to serve images on the web. As with most services on AWS, it can be configured to fit almost any use case.
I began searching the plentiful articles on the topic of deploying static sites, which all pretty much boiled down to the following:
Create a new S3 bucket called whatever your domain is (if you are using a custom domain)
Upload your site’s files to the bucket
Enable ‘Static Website Hosting’ for the bucket
Create a new CloudFront Distribution
Fill out the distribution config to point to the S3 bucket
After re-releasing, you’ll need to create a new ‘Invalidation’ for your CloudFront distribution to update the cache in your CDN. This process is the cost of using incredibly powerful tools. Cumbersome setup process aside, AWS was the perfect fit for my project. It gave me the performance and scalability as well as the control if things blew up. But I missed Surge… 😩
So, I decided to build Static, a single command to deliver the joy of Surge’s simplicity with the power of AWS. Here are a few things that Static provides:
Deployed to S3: Deploys your directory to an S3 bucket
Custom domains: Prefixed with your domain name (or a random string if none is provided)
Automatic Static Hosting: Enables Static Hosting for your bucket
CDN’d via CloudFront: Creates a CloudFront distribution so that your site is served over a CDN, making it speedy wherever you are in the world
Invalidates cache on each deployment: It will update the cache of your CloudFront distribution if one exists
Client-side Routing: It’ll handle both Standard Static Routing or Client-side Routing.
Custom error pages: If you aren’t using Client-side Routing, you can add your own 404 page by adding a 404.html document to the route of your directory
Clean URLs: All URLs will be ‘cleaned’, i.e. your-domain.com/hello.html is reached via your-domain.com/hello
So we’ve got almost exactly the same functionality as Surge in a single command (static ./ domain.com) with all of the benefits of using AWS. 🎉 To install: npm i -g sttc. Enjoy!