Jekyll in Docker with Docker Compose

Jekyll in Docker with Docker Compose Featured Image

Containerised local development is often the way forward for small software development teams. It allows everyone to replicate the same working environment without spending ages configuring their individual systems.

This goes especially for the nowadays more uncommon languages such as Ruby - and if you’re not ready to make the leap to Hugo - running the ruby based Jekyll in Docker is a great solution for local Jekyll web-development.

Setup Jekyll in Docker and Docker Compose

First, make sure you have docker running in the background, whether via the docker engine or Docker Desktop etc.

Then, create a docker-compose.yml file in the root of your Jekyll project with the below YAML content.

Run this docker compose file to launch a container with the official Jekyll docker image, and your Jekyll sites files.

Once the container has fully loaded, you can access it via http://0.0.0.0:4000 and since we’re only running this locally the lack of SSL/HTTPS should be fine in most cases.

services:
  jekyll:
    image: jekyll/jekyll
    volumes:
      - .:/srv/jekyll
      - ./vendor/bundle/:/usr/local/bundle
    ports:
      - "4000:4000"
    command: jekyll serve --force_polling --drafts

Tip: If you’re using Visual Studio Code (aka VS Code, the most popular IDE at the time of writing), you can install the official Docker extension and run “Docker Compose: Up” from the “Ctrl+Shift+P” command menu. This docker extension also makes it easy to access the containers logs etc too.

Tip 2: You may also want to add the following exclude command to your Jekyll _config.yml file, it’ll prevent the new docker-compose file from being deployed into your static site.

exclude:
  - docker-compose.yml

Jekyll Docker Compose Explained

Here we’ll walk through the docker-compose.yml config file to explain what’s going on.

image: jekyll/jekyll

This asks Docker to pull down and run the official Jekyll docker container image. You can be reasonably sure this official docker image is safe when compared to a customised docker image made by someone else.

volumes:
  - .:/srv/jekyll
  - ./vendor/bundle/:/usr/local/bundle

Here we’re asking Docker to create a live mapping from our current working directory a.k.a . to /srv/jekyll which is the serving location inside of the docker container. This means that any time we update a file locally in our IDE, the changes are applied live inside the docker container also. The vendor part simply speeds up the docker setup by caching some files locally.

ports:
  - "4000:4000"

This one is pretty self explanatory, it asks Docker to map the container’s port 4000 to our local port 4000, allowing us to access the site in our browser on 0.0.0.0:4000.

command: jekyll serve --force_polling --drafts

This is the serve jekyll command that you may be used to when working with jekyll. It builds the site and serves it live via a mini built-in web-server. It’ll also watch for changes in your files and rebuild the site live after each change (excluding the _config.yml file). After changing a file, all you need to do is reload the browser page.

The --force_polling simply forces jekyll to watch for file changes that would not usually be passed through docker in the same way they would be locally. This is a small quirk of running jekyll serve in a container like this.

The --drafts flag asked Jekyll to include any posts under _drafts in the development site as if they were real posts, handy for previewing drafts locally before committing.

Comments & Questions

Reply by email to send in your thoughts.

Comments may be featured here unless you say otherwise. You can encrypt emails with PGP too, learn more about my email replies here.

PGP: 9ba2c5570aec2933970053e7967775cb1020ef23