Docker Jekyll and Mr Hyde

Once you get it set up, Jekyll is a great tool for building a personal website. There are dozens of free templates that look nice right out of the box. It’s also easy to get your hands dirty with HTML, CSS, and/or Javascript, if you’re into that. Posts are written in Markdown, which is a nice balance of convenience and capability1. I use Jekyll to host this very site via GitHub Pages!

Unfortunately, the setup for Jekyll is a pain in the ass. I recently fresh-installed my laptop and the process looked something like this:

  • Install jekyll via package manager.
  • Jekyll uses Liquid, which uses Ruby, so install ruby and ruby-dev too.
  • Ruby plugins are called gems. Install the jekyll gem.
  • Uh oh.
  • Uninstall both Jekylls.
  • Install the bundler gem, then do bundle install to install all the dependencies listed in the repo’s Gemfile.
  • Also do bundle update to get rid of weird versioning errors.
  • From now on, prefix all commands with bundle exec in case gems conflict with one another.

It works, but it’s not pretty. To avoid going through this again, I wrapped it all up in Docker. Dependencies are installed (in the right order) in the Dockerfile, and orchestration is written up in the Makefile. With just Docker and a command line, I can now build the container, fire up my site within that container, and serve it locally just by running:


Then I can point a browser to localhost:4000 and see my site, just like I would if running directly on my machine. And since I’m mounting the repo into the container (rather than making a copy) it even re-builds automatically as I make changes.


The only snag I hit was port forwarding. On Linux, a service running on port 4000 within the container can be forwarded to the host machine using the flag -p 4000:4000. But my new machine is a Macbook, which means Docker is run in a VM under the hood. So -p forwards the container port to the VM port, not the host port. It took a minute to figure out what was going on, but luckily the workaround was quick: instead of serving to (localhost), tell Jekyll to serve on (a wildcard local address).

You can take this all for a spin yourself! To use my template for your content, swap out my _posts and assets for your own. If you’re already running Jekyll and just want to try out the Docker stuff, copy over my Makefile and Dockerfile (plus host: in _config.yml).

This is just a little project, but getting Docker into our workflow is a big deal. Now I can pull down this repo and it’ll just work, regardless of what else is (or isn’t) installed. No need to manually keep track of requirements2. No need to put a bug fix on hold to install them. No need to worry about projects stepping on each others’ toes. Docker lets the machine keep track of tedious and error-prone tasks, so we can spend more time doing what we love: reading StackOverflow to figure out why our code is broken!

  1. Markdown is a way to write rich text documents using a plain text editor – basically like the BBCode web forums used ten years ago, but nice. It lets you include italics, links, footnotes, etc in a document without clicking through menus or getting bitten by invisible formatting

  2. One of these days, I’ll learn Ansible. Until then, I have an email thread with myself titled “FRESH INSTALL STEPS.” 

© Charles Fyfe 2020 under CC-BY