After a few years of running this site on Wordpress (on a Gentoo Linux IaaS instance hosted at Linode), I decided to get with the times and switch over to using a static site generator, storing the site content as code.

Over time I had become increasingly aware of the effort required to keep a Wordpress site secure, to the extent that I worried it would only be a matter of time before I’d take too long to patch the latest zero-day in a Wordpress plugin or similar, and the site would end up getting hacked. Static site generators provide an elegant solution that massively reduces the attack surface, largely eliminating the security concerns typically associated with running a dynamic content management system. And they align perfectly with a modern “infrastructure-as-code” approach. So I decided the time had come to make this my next mini-project. And I am very happy with the results (I should really have done this sooner).

After a few days of researching the available options, I settled on:

  • Hugo as the static site generator - primarily due to its popularity, especially for minimalist tech blogs
  • An Azure Static Web App as the hosting platform - because it’s free for a site of this size, and I’m familar with Azure already
  • Hello-friend-ng as the theme - it matched my design preferences pretty well, and looked simple enough for me to tweak if necessary
  • Statique for comments - this is not one of the well-known commenting solutions, but I really like the concept. The Azure blob storage used to host the comments is the only part of this site that costs me money (ignoring domain registrar fees, which are not purely for this site), but it is literally only pennies per month
  • GoatCounter for analytics, replacing my prior use of Google Analytics - providing simple and useful analytics, in a privacy-aware manner

I was pleasantly surprised by how easy it was to get the hang of using Hugo, and how refreshing it is to use markdown versus other formats (or editors). It was also easy to export content from Wordpress in a format suitable for Hugo. Having said that, most of my time in performing this migration went on fixing up a few aspects of the automatic HTML to markdown conversion that hadn’t worked out quite right.

So far the only things I had implemented for the Wordpress instance of this site that I have not managed to transfer to Hugo and Azure Static Web Apps are all limitations of the latter:

  • The site is not available over IPv6
  • I can’t customize the list of supported TLS ciphers (for example, permitting only AEAD ciphers)
  • No TLS session resumption mechanism is supported (impacting performance)
  • The TLS cert used by the site uses RSA rather than EC cryptography
  • OCSP Must-Staple is not supported
  • TLS_FALLBACK_SCSV is not supported

Most / all of the above could probably be addressed by adding something like Azure Front Door or Cloudflare in front of the Azure Static Web App. But doing so would not be free (CloudFlare has a free tier, but that doesn’t encompass custom TLS certificates and ciphers). The site currently gets an A rating on Qualys’ SSL Labs test suite (it was previously A+), and I think it might be just the lack of TLS_FALLBACK_SCSV that is holding it back (which I’m not sure I understand, as I thought that wasn’t necessary for a site that only supports TLS 1.2 and 1.3… ie 1.3 has its own downgrade prevention mechanism, and if versions older than 1.2 are not supported, there is nothing to downgrade to from 1.2).

Beyond simply switching to a static site generator, the entire process has served as a nice refresher course for me on web development, and I understand far more than I did beforehand. And having now spent a few weeks on further tweaks I much prefer the overall look and feel of the site. So all-in-all a very worthwhile project.