Dockerizing a Jekyll blog

Jekyll blogs are the last thing you may think of Dockerizing. They are small they are easy to setup and equally easy to run. But when you have multiple Rubies on your local system and you don’t want to keep installing maintaining multiple versions of rubies and corresponding gems, you might want to start thinking of Docker. Once way to do this would of course be Vagrant. But Vagrant might seem a bit of an overkill when all you want to run is static site generator.

I started using Docker full time about two months ago. I work on multiple projects all Rails/Ruby based and all of them requiring different versions and combinations of Rails/Ruby. While I used to use Vagrant for some of these projects, switching between them started to be annoying, given the time it takes for one to stop and the other to start. The other issue for me was the setup time it took in some cases. Provisioning scripts, frequent crashes, slow response times - I decided to let go of Vagrant and move on to Docker.

If you have worked on a Ruby based app you will be familiar with the whole gem installation process. I didn’t want to go through the whole the gem installation process every time I had to switch the machine I work on which by the way is prone to frequent change. So I decided it was time it was all bundled in to a tidy container that could simply be downloaded and run as and when I wanted.

The first step in Dockerizing any app is creating an image. In this case it was quite simple.

FROM ruby:latest

RUN apt-get update -qq && \
  apt-get install -y -qq nodejs procps && \
  rm -rf /var/lib/apt/lists/*

RUN mkdir /app

ADD Gemfile /app/Gemfile
RUN bundle install

ADD . /app

This is a pretty standard Dockerfile for a Ruby application. It uses a Ruby image to create a container. It also creates an app folder in the container that serves as the working directory and contains the application. It also adds the Gemfile installs all the necessary gems. The image can be then built with

$ docker build .

To create an image and push it to a Docker’s container registry, you need to tag the image first. This can be done with the tag command

$ docker tag image_id your-docker-hub-name/docker-repo-name

You can get the image id with docker images. Now we can push the docker image with

$ docker push your-docker-hub-name/docker-repo-name

Now you have a containerized blog that can be downloaded and run anywhere. Now you can run the blog with something like

$ docker run -v /local-path/to/blog:/app --rm -p 4000:4000 your-docker-hub-name/docker-repo-name jekyll serve --host

I am not delving into the options used here. You can easily find them in the docker run reference

If you want to run it as close to your production setup, you can use dnsmasq to redirect .dev queries to localhost and map the container’s port 80 to the host’s port 80.