How I Built

TL/DR: I built the long way.

I needed a blog.

I didn’t spend too much time shopping before I settled with a self-hosted implementation of Jekyll. I’m a bit of a command line junkie. The draw of writing, formating and publishing each blogpost without having to touch a mouse was too enticing to pass.

The next step was to plan out a modular development structure for the website.

I decided to split the code into three repositories: blogposts, website and website theme. By isolating the blogposts, I could compensate my lack of a GUI by drafting posts from if I needed to. By seperating the theme from the main site, I could switch to a new theme without having to refactor the entire codebase and I could potentially use either repo for future websites. I chose Hyde by @mdo as a base theme. Forked it, updated it and called it Heidi.

Commiting to this model, the challenge now was to figure out exactly what each repo would look like, how to develop each side-by-side and how to bring them together as the finished site.

After a little research, I decided to turn the blogpost repo into a submodule of the main site repo. A simple git submodule update command would fetch the latest posts. However, the submodule approach proved too clumsy for the theme repo, so I decided instead to develop Heidi as a seperate ruby gem.

The Server

I had a number of requirements from my server:

  1. TLS encryption ( https:// instead of http:// )
  2. A staging domain to make sure the site works in a live environment
  3. A reverse-proxy to easy facilitate future capabilities
  4. A docker-centric workflow ( my latest infatuation )

I began developing the most excessive, scalable, docker server cluster I could imagine; With load balancing, continuous deployment, failover, all spread across as many virtual servers as I desired. By the time I was knee deep in iptables documentation, I realised I’d gone too far. Vowing to return one day to my mega cluster, I pushed on, building a simple NGiNX reverse-proxy server before finding a superb pre-built solution on GitHub.

The server now consists of five parts

The Development Environment

To build a seperate theme whilst building a website turned out to be my most disruptive decision. My most puzzling problem to solve.

To clarify:

My goal was to build a website, it was not to build a theme. The theme would be a by-product of the website. Ideally as I built the website, the theme would magically build itself behind the scenes, without me having to think about it. This meant that I would need to develop the website from both the theme repo and the website repo almost simultaneously.

There were no two ways about it. I needed a bash script.

The Build Script

The script is run from ( which can be aliased to whatever you like ).

It takes a number of options initialised by a simple case statement and two of those options also take a further option, again determined by a case statement.

Below is a description of what each option does and how it works.


Move posts, pages & config from site repo to theme repo for development.

Although the code I commit will be pushed to my theme repo rather than my site repo, by initially loading the files and configuration specific to my website, my theme server will appear as if i’m working on my website code directly.


Serve and watch theme or site or preview blogpost.

The serve option itself has four options

If I serve my theme, the script moves to the theme repo and runs bundle exec guard to serve a live-reloading website to localhost.

However, if I serve my site, the script

To preview blogposts I decided to re-appropriate gits functionality to the needs of the script.

The script

This process is resolved when a blogpost is posted to the website with the post option, detailed below.

The stop option simply stops and removes the containers that are serving the site locally.


Test theme gem by pushing, pulling and building from local gem server.

To avoid commiting broken code I have to be able to test my theme works when loaded as a gem.

The script


Update theme version number, commit changes and post gem to

When I know that the theme works as a gem and I’m happy with my changes, I bump, commit and publish.

The script


Deploy code to

The deploy option itself has three options

The deploy system relies mainly on docker tags to move and switch docker images.

The tags are:

While the above images live on docker hub and are pushed and pulled from my local machine to my server, the next two images only live on the server and determine what is viewable at and




deploy diagram


Post blogpost to website.

Resolving the git appropriation from serve post, the script pushes the completed post to master deletes the draft from drafts and then merges master into drafts to keep drafts housing drafts and all complete posts and master housing just the complete posts.

The script