Migrated to Jekyll and AWS
I’ve just switch my blog from self-hosted WordPress to Jekyll hosted on Amazon AWS. I’ve been less than excited about my experience with WordPress and I wanted a simple, responsive, and performant site for my blog. All the features I need can be achieved with a static site. Jekyll seems to be the leader in this area, perhaps due to its use as the engine powering GitHub Pages.
Why Migrate?
There were a few reasons, some tangible and others not so much. I wanted to refresh my blog. I haven’t written in a while and before I started again, I wanted it to have a fresh, modern feel. WordPress, even with all the nice new themes available, just didn’t feel right. So, I investigated Jekyll and the themes available and gave it a shot.
My WordPress site was slow and complicated
I didn’t perform an objective comparison of the performance between between WordPress and Jekyll/AWS. However, just running a few manual tests using both desktop and mobile browsers I was able to quickly see that Jekyll/AWS is must peppier than my WordPress site.
Could I have taken the time to optimize WordPress? Sure. Could I have hosted it somewhere else to make sure it had exclusive access to compute and storage resources? Yup. Did I do these things? Nope - I didn’t want to take the time, especially since it would have meant getting into the nitty-gritty of WordPress optimization, which I just didn’t want to do.
Mobile Friendly
Most folks live off their phones, obviously. If your site isn’t mobile friendly, it leaves a bad impression. Two main aspects to a mobile-friendly site are speed and simplicity. Speed in delivering the content and navigating around, and simplicity in the look-and-feel and how easy it is to find your way without being distracted.
The new Jekyll-based site is simple and responsive. Not only does this feel good when viewing on a phone, it should help with Google search scores.
WordPress security isn’t great
WordPress sites have been hacked many times due to many different vulnerabilities. I was always checking to see if I had the latest WordPress patches because I didn’t want to get hacked. While this kind of assurance work is a must for a business-critical web site, I didn’t want to budget my time this way anymore.
The most secure site I can think of is a completely static site. You don’t have to worry about issuing patches to plugins, or have to worry that you’ve got a vulnerability in some custom code you’ve put together. All the site is is a web server serving static files. Feels like 1994 all over again, but in a good way.
Cost
The plan I signed up for on BlueHost costs me about $200 per year (which includes more than just my blog, so it’s not apples-to-apples). There are cheaper self-hosted blogging solutions out there, for sure. However, I wanted to see how cheaply I could self-host a static site using infrastructure that had no reasonable limitations. Amazon AWS fit the bill.
Getting my hands dirty
Even though I spend most of my time these days advising customers on technology and leadership strategy, I still like to get my hands dirty with technical details from time to time. This looked like a good way to do that and produce something useful at the same time within a limited time budget. I had fun setting it up.
Why self-host?
I’ve always liked the idea of self-hosting blogs. It’s a control thing. It’s nice to have authoritative control over your content such that you’re reliant on other services (and censors) as little as possible. If you want to get more exposure for your posts, on LinkedIn or Medium for example, you can always post on those sites with a link back to your own “authoritative” content.
Migrating Content from WordPress to Jekyll
The process was fairly straightforward, made simpler because I don’t have many posts. There are many good Jekyll importers, including one for WordPress. I used this one to import my blog content into a Jekyll site. This process was fast and easy.
Hosting on AWS
Hosting a static web site on AWS is simple, but there are a few moving parts one has to deal with related to DNS records, aliasing, SSL certificates, etc. For this reason, this hosting method is NOT recommended for non-technical folks. The solution I ended up with was a combination of the following:
- S3: One bucket to hold all my content, served over the web
- CloudFront: a “distribution” to cache the content from S3 and serve it from end points that are geo-local to the browser
- Route 53: Amazon’s DNS service
- Certificate Manager: Amazon’s certificate authority (CA)
AWS S3 is built to store and serve content quickly, and it’s cheap. You can configure an S3 bucket to serve its content over the web. Using CloudFront you can automatically compress and edge-replicate your content, accelerating access to users anywhere in the world.
As far as I could figure out, you have to use Route 53 if you want to cleanly setup a site with a custom domain served through CloudFront. It’s easy to point your domain registrar over to Route 53 - it may just take some time for the changes to take effect. It took about 8 hours in my case, so be patient.
Getting a certificate from AWS Certificate manager is easy also, and free. The key is to make sure that you use an SNI certificate. SNI is “Server Name Indication” and allows multiple certificates to be served from the same IP address. All modern browsers/versions support the SNI protocol, while some legacy browsers don’t. This was fine for my purposes.
The Result
Speed
Using Google PageSpeed Insights, my new site does pretty well: 88/100 mobile, 89/100 desktop. My WordPress site was at 58/100.
Responsiveness
The “sidebar” will collapse automatically when the viewport gets narrow, either on desktop or mobile browsers (go ahead, give it a try). Right out of the box, the site looks good on my iPhone, which is one of my most needed features.
I chose to use the Jekyll theme HydeJack version 6.6.1. There are lots of themes available for Jekyll, with different visuals and supported features. This one seemed good for my purposes.
New Publishing Process
I have more control over the publishing process now. However, it does require a bit more technical know how (including comfort with Git and Markdown).
My workflow for adding a new post is as follows:
- Make sure I have the latest version of the blog’s content locally (git pull).
- Create a new file under the “_posts” folder with a name like “2017-10-01-nice-post.md”.
- Edit the markdown.
- From a command line, run “jekyll serve” (Jekyll will run a local web server on port 4000).
- Using a browser, go to http://localhost:4000.
- When I’m happy with the post, commit the change (git add / git commit).
- Push the change to my cloud repo for safe keeping (git push).
- Build the blog for production (command line: “JEKYLL_ENV=production bundle exec jekyll build”).
- Put the contents of the _site folder onto S3.
I use a script that leverages Amazon’s S3 client library to sync my local site content to the S3 bucket all in one shot:
aws s3 sync _site s3://
The max-age attribute is served by S3 to CloudFront so that CloudFront will load new content from S3 every day. This way I don’t have to remember to invalidate the CloudFront cache when I make changes (since it’s not critical for me to have my posts show up immediately). You could, of course, add a CloudFront invalidation via script, but I chose not to do this.
The Cost
The total cost for hosting my blog on AWS is under $3 US per month. The single largest cost is from Route 53 (3 domains x $0.50 per domain). Based on the AWS pricing schedule, I’d have to have tens of thousands of hits per month before the cost became more than a few lattes. I’m happy with this.
I hope this was helpful to you. If you have any quesitons or suggestions, feel free to reach out to me.