Blog Rewrite (V2)

Three years after my last rewrite of this blog, and having run my WordPress-based food site for two years, it was once again time to tackle my personal blog. The ease at which I could update my recipes and the power WordPress gave, combined with the basically-zero running costs of its serverless & static nature persuaded me I needed to do the same with my main blog.

I have never been good at front-end design, nor the modern technologies associated with it (React etc). Whilst I can get by, I don’t particularly find joy in spending hours tweaking components or CSS to get things just right. Add to that the very manual nature of updating my blog via markdown, and the apparently endless security alerts I was getting on all the various libraries I was dependent on, I wasn’t really updating it very often.

By comparison, I’ve been easily and happily adding recipes to my food blog that entire time. My mind was made up – I would use the same WordPress-based approach for this blog.

With the advent of Full Site Editing and the Twenty Twenty-Four theme in WordPress, I could now very quickly and easily knock together a site design I feel much happier with. Whilst it does not seem to be quite as performant as GeneratePress, the benefits were well worth the trade-off in my judgement. I’ll probably keep playing with the look-and-feel quite a bit, but for so little effort I’m pretty happy with where it has got to.

Rebuilding the “serverless” tech

A few years have passed since I last assessed the tech behind my food site, and so I wanted to reassess whether it was still the best approach. A few things are obvious, simple things like upgrading to the latest version of Terraform and the AWS provider. I reworked it from the ground-up. However, I had also received this email from AWS:

We are reaching out to let you know that as of December 31, 2024, Amazon Aurora will no longer support Serverless version 1 (v1). As per the Aurora Version Policy [1], we are providing 12 months notice to give you time to upgrade your database cluster(s). Aurora supports two versions of Serverless. We are only announcing the end of support for Serverless v1. Aurora Serverless v2 continues to be supported. We recommend that you proactively upgrade your databases running Amazon Aurora Serverless v1 to Amazon Aurora Serverless v2 at your convenience before December 31, 2024.

Amazon Web Services

No big deal, v2 must be better, so I might as well set about using that. Well I was wrong – the huge selling point of Aurora Serverless for me was the auto-pausing (i.e. scaling to zero when not in use). Sure, it took about 30 seconds to cold-start, but that was tolerable when the upside was not paying for it when not in use. Aurora Serverless v2 does not have that feature, and requires you to run with 0.5 ACU all the time. For me, that isn’t serverless at all – that is a server with built-in autoscaling.

Assessing the options

Given I had no choice, I decided to assess what I could do instead of Aurora Serverless v1. At the moment, my whole food blog setup costs around $0.01/month most of the time, with occasional small increases when I spin it up to update it. So I was looking for something approaching that.

Aurora Serverless V2

Running this at 0.5 ACU all the time was a non-starter, as that would cost around $52/month. At the time of writing, 1 ACU costs $0.14/hour. I considered simply stopping the database and only starting it when needed, but RDS will automatically restart your database after 7 days and leave it running.

I got to thinking I could use Step Functions to detect when it was automatically restarted and then shut it down again. I would have to pay for the time it takes to start up and shut down, but if I could keep that to around 10 minutes each time, then that would be approximately $0.05/month.

After doing some testing, I found it took around 15 minutes to restart and 10 minutes to shutdown. At 25 minutes each time (and likely much more when I factor in automatic maintenance patches being applied) it would cost maybe $0.15-$0.50/month. That is considerably more than I was looking for, but tolerable.

The main problem was at 15 minutes to start up, that is very frustrating to have to wait for when you want to just do a quick blog update. Not only that, but I have introduced another thing that could go wrong – Step Functions. So what if we just snapshot and delete the DB and then restore each time? Well, it turns out it takes roughly the same amount of time – so at least now it would cost less, but the start up time was still a big problem.

Aurora On-Demand

Given Aurora Serverless V2 isn’t really serverless anymore, I took a look at standard on-demand Aurora. A db.t3.small appears to be equivalent to 0.5 ACU but costs significantly less – around $32/month. For applications with the need for a low-power always-on RDBMS this looks far preferable over Aurora Serverless V2, which just looks like a bit of a rip-off at this point.

This doesn’t solve our start-up/shut-down problems though, I got very similar timings in my testing.

RDS On-Demand

Back to our old-school RDS, we can run for around $15/month on the smallest instance type (a db.t4g.micro). Granted, this has less power than the Aurora options, although it would be more than enough for my purposes. Using RDS does mean you potentially miss out on some of the Aurora nice-to-have features too, like not having to worry about running out of storage.

Again, though, the start-up and shut-down times are way too long. It looked like all my managed database options were out.

ECS Containers

For local development, I run a MySQL container as part of a docker-compose configuration with WordPress. Whilst normally I wouldn’t advocate at all for non-managed databases like this, for this use-case I didn’t feel I had much of a choice. By putting the MySQL container within the same ECS Task as the WordPress container (all running on Fargate Spot), I can have the database startup and shutdown on the same cycle as WordPress. It also spins up within a matter of seconds.

Assuming 1 vCPU with 2GB memory assigned, this approach would cost around $11/month if running all the time – which obviously I won’t be doing. I think RDS/Aurora would still be the preferred choice for an always-on application, even though it costs slightly more.

New Architecture

Many of the concepts remain the same. WordPress runs in a container on ECS Fargate Spot only when I want to update the site, and is shutdown otherwise. MySQL now joins it within the same ECS Task. I publish the content to S3 via WP2Static to generate a static version of the website to be served to the public.

I substituted out AWS CodeBuild for GitHub Actions to building the custom WordPress image. I found Actions a lot easier to work with and it also allowed me to have a web-interface for spinning up / down the WordPress container without needing the project checked out locally.

I also rebuilt the container in a cleaner way, allowing it to run nicely locally as well as on ECS. It now also automatically configures all the basics of the site which I require, rather than needing to do it by hand. Options such as language, timezone, date formats etc are all built-in. It also installs, activates and configures all the plugins I require. I also additionally added a WebP image optimiser plugin this time to help with performance.

# Install Syntax Highlighting Code Block
if ! sudo -E -u www-data wp plugin is-installed syntax-highlighting-code-block; then
  echo "Syntax Highlighting Code Block not installed: installing Syntax Highlighting Code Block"
  sudo -E -u www-data wp plugin install --activate syntax-highlighting-code-block
  sudo -E -u www-data wp option update syntax_highlighting --format=json \
    '{"theme_name":"a11y-dark","highlighted_line_background_color":"#4a4a4a"}'
fiCode language: PHP (php)

Performance & Conclusion

So how does it perform? Wonderfully! Static serverless WordPress really can tick all the boxes for small blog websites.

It does seem a real shame that AWS have taken the decision to sunset Aurora Serverless V1, and V2 really does not live up to the name in my opinion. There also seems to be nothing to suggest they will be bringing auto-pause to V2 any time soon. If they do, I’ll happily move my workload back.

I plan to update my food blog as well to use this new set up, or perhaps I’ll look in to WordPress Multisite or similar to make maintenance a little easier. Overall I’m very pleased with how this turned out, despite the challenges. I’m hoping this means I’ll be much more tempted to update my blog a little more often, now that it is so much easier!