My personal blog deployment

Thomas Dickson

8 minute read



There are a lot of solutions out there for deploying blogs, from Vercel to Netlify to GitHub pages. Why would someone bother going through the effort of learning Terraform, Ansible and the basics of server administration to deploy a simple Jekyll blog with low quality content?

Because I am an engineer and I must understand how these things work.

I wanted to follow two key principles when evolving my approach to deploying this blog. These were:

  1. Everything was as simple as possible (confident that this was a famous quote at some point)
  2. To minimise dependencies on external services as much as possible

Making things simple involves using reliable, mature technology that has been used for (at least) several years and is likely not to be depreciated for a good while longer. Both in academia and in industry I’ve used tools that were “bleeding edge” and had fancy new functionality which made solving specific problems easy. However, these tools suffered from lack of support or functionality outside of a tight domain. Furthermore, the amount of time I spend working through dependency issues and undocumented bugs with my current role strongly pushes me towards working with simple tools that I can understand build myself.

Minimising dependencies on external services has a clear goal: I don’t want to build on quicksand. There is a tradeoff between using a service to reducing the time to production and the cost involved in building a bespoke solution. When it comes to supporting something I hope to have a long time in production, such as my personal blog, I want to maximise the amount of control I have over the deployment process and infrastructure. This approach also helps guarantee how much services will cost to support. I’m either paying for something that’s simple to support or use or I’ve written the automation that will solve the problem that a managed service solves for me.

First things first

How much does this all cost?

Total: about £70 a year.

I think I spent about 20 hours in total developing learning about Terraform, Ansible and nginx to be able to develop some simple scripts for deploying this blog and webapps on various subdomains. Whether that’s really a cost or an investment in learning about these technologies remains to be seen.

Could this have been done cheaper? Almost certainly yes, but would it be mine?

The blog itself

So this is a typical Jekyll blog. Jekyll is a static site generator, written in Ruby, that turns markdown text into html. As you can see in the diagram below, it allows you to stitch together html snippets, styling and additional javascript libraries in order to generate a static site. It’s popular, simple to use and cheap to maintain (although I dislike the word “maintain” in the software context - it’s really just about continued development against new situations).

graph LR A(Content in markdown) --> B(Jekyll build) --> C(Nginx) --> D(Domain) E(Gems) --> B F(JS Libraries) --> G(HTML Snippets) --> B H(Styling in SASS/CSS) --> B

The additional gems I use are:

I pull in a few javascript libaries to give a bit of extra functionality:

I then use Nginx, Lets Encrypt and a domain name purchased from Ionos and registered with Digital Ocean to serve the static content generated by Jekyll. Nginx acts as the server/reverse proxy to serve the blog at my domain and apply the right certificates that were created using Lets Encrypt, an excellent service. I used IONOS at a previous company and together with Digital Ocean provides a reliable service for making the blog widely accessible.

Getting it in the cloud

Part of my strategy (as well as to understand everything) is to reduce the number of dependencies I have on managed services. Managed services often have hidden costs/risks or functionality that could catch me out in the long run. I can avoid these by taking on the cost of implementing my own solution up-front.

I decided to choose using a Digital Ocean droplet rather than buy a domain and then use a service like GitHub pages or Netlify to handle the deployment and support. I found the Digital Ocean UI simple to use, their costs are straightforwards and there are lots of helpful tutorials to perform various tasks. I’ve professional experience with Azure, AWS and GCP now, but Digital Ocean still remains the simplest and cheapest option for me to use.

Using a service would have saved a lot of time initially but now that I’ve got the code for deploying my own website it’s not a problem I’ll have to solve again and I totally own all parts of this solution. Digital ocean goes down? Fine, just let me replace the Terraform code towards AWS/Azure/GCP etc. The redundancy I now have feels more valuable than getting something more ephemeral in the cloud even if that could have gotten me closer to my various side project goals by 20 hours.

Automating the deployment

The process for automating the deployment involved two key stages:

graph LR A(Create server) --> D(Configure server) --> E(Point domain at server IP)

Terraform was the tool I used to write the process to instantiate the VPS (or Droplet) used to host my blog. I then used Ansible for automating the configuration of the server itself for building and deploying my blog.

Why bother using two different automation tools that nominally do the same thing? I was able to learn that whilst they do do the same thing they do it in different ways. As I unashamedly paraphrase from this article, it’s turns out that:

Rightly or wrongly I found the ability to use Terraform to determine the infrastructure I needed to be quite easy to use. I toyed with the idea of running an Ansible playbook on server creation, but I ended up finding the seperation of server creation and configuration into two different processes easier to handle.

I use pass for storing the secrets I use locally for deploying and updating the blog. It’s an excellent tool and I doubt I’ll ever use a managed service for hosting my personal secrets. I could well lose my laptop, but it’s also likely that one of the many online services I might use may be hacked and we’re all back to square 1 again.

Next steps

In this blog post I’ve detailed the design decisions and higher level implementation details of how I’ve created my own process for updating my personal blog. I learnt a lot about Infrastructure as Code, server configuration and the basics of static site generation. Hopefully you might have been able to get some ideas of how you might be able to solve similar problems, and if you have any questions please reach out to me.

I’ve got a few ideas for where to take this next: