Docker-Jekyll

20 February 2020

Back to Tips and Tricks Table of Contents.

A Docker tutorial.

Roadmap

Backstory

This page will cover the (1) use and (2) creation of a Docker image for generating websites with Jekyll. Why would I do such a thing?

Well, the story is as follows. I maintain two websites, this one, and another one, that are generated with Jekyll. Every time I tried to update the other one (not amytabb.com), things were broken, I would have to fight with Ruby – something I know very little about – and a planned 5-minute update ended up consuming an inordinate amount of time. Since I update from more than one machine, my thinking was that I could freeze the Ruby version once and for all, and just run Jekyll from a container.

Getting a Docker image set up for amytabb.com was easy. Getting a Docker image set up for the other website never worked – and finally, I realized I would need to start with a template with fewer dependencies. Since I have very little on that other website (I am purposefully not linking to it …), this is not a big deal and will save me time and angst in the long run.

In the meantime, I had gotten a container working, so why not write a blog post? If you’ve been having a hard time getting Jekyll working, or there are incompatibilities with versions, this method should work no matter what OS you have. Technically, since Jekyll will be running from the container, even though I use an Ubuntu image, it should run.

Here goes!

Install Docker

If you don’t have Docker already, you’ll need to install it. Here’s the link to install for Linux, and I also endorse uninstalling old versions if you have them floating around.

Build image or pull from Docker hub

The image is currently at Docker hub, amytabb/jekyll-basic. To pull to your local disk,

docker pull amytabb/jekyll-basic

Alternatively, you can build the Docker image on your local disk yourself. The Dockerfile is in a Github repository, amy-tabb/docker-jekyll-basic

git clone https://github.com/amy-tabb/docker-jekyll-basic.git

cd into the directory, and then build:

sudo docker build -t jekyll-image .

Run Jekyll from container

Now it is time to run Jekyll from the container. We need a lot of stuff here. Assuming that jekyll-image is the image name (it would be amytabb/jekyll-basic:latest if you pulled it from Docker hub),

sudo docker run  --network host -v /home/atabb/git/amy-tabb.github.io:/write_directory -it jekyll-image jekyll serve

is one concrete example. Substituting in the generics:

sudo docker run --network host -v /full/file/path/of/web/site:/write_directory -it jekyll-image jekyll-commands

Let’s start at the back – the jekyll commands.

For some websites, the commands are bundle exec jekyll serve. The template I am using is generated with jekyll serve, so I used that.

jekyll-image is the name of the docker image, again, you would use whatever name you selected when you built the image locally, or amytabb/jekyll-basic:latest if you pulled it from Docker hub.

-v /full/file/path/of/web/site:/write_directory means to bind the first path on the host machine, to the second path in the image (separated by a :). I set up the Dockerfile such that the working directory is /write_directory, so that will not change. -v indicates a bind mount (a type of mount in Docker).

--network host means to allow the container to access the host’s network. From the docs, this is only available in the Linux Docker version. But I really don’t know what the status is for other OS’s. I have complained about Docker’s docs before.

run: we’re running the image to get a container.

Details of the Dockerfile, extensions

FROM ubuntu:18.04

RUN apt-get update

RUN apt-get -y upgrade

RUN apt-get -y install ruby-full build-essential zlib1g-dev

RUN apt-get -y install ruby-bundler

RUN useradd jekylluser 

RUN mkdir /home/jekylluser

RUN mkdir /write_directory

RUN chown jekylluser /home/jekylluser

USER jekylluser

WORKDIR /home/jekylluser/

ENV HOME "/home/jekylluser"
ENV GEM_HOME "$HOME/gems"
ENV PATH "$HOME/gems/bin:$PATH"

RUN gem install github-pages

RUN gem install bundler

WORKDIR /write_directory/

I’ll explain each part. For more in-depth details about using Docker for research purposes, I have a tutorial that concerns using Docker to package code for those not on your OS – which in my case, is C++ with Linux.

Final note: beware of relative and full paths in Docker. There are many ways to get things wrong. Docker: What’s the deal with WORKDIR? has a full explanation of these phenomenon, and to eliminate problems, I use full paths (starting with /). In short, if there’s a way to get it wrong, I’ve probably done it!

Extensions

Hopefully, you can see there’s plenty of ways you can alter this basic Dockerfile for custom cases, to install more gems or to extend functionality.

© Amy Tabb 2020. All rights reserved. The contents of this site reflect my personal perspectives and not those of any other entity.