Since I don’t want to install and manage a compatible version of Ruby for my Jekyll version and all dependencies of my website I decided to use Jekylls’ Docker image to develop this page. For my build pipeline in Gitlab CI I wanted to make use of these already existing definitions.

I created a simple docker-compose.yml file that loads my source files as a volume, like explained in the documentation of Jekyll’s Docker Image:

version: '3.7'

services:
  blog:
    image: jekyll/jekyll:3.8.5
    command: jekyll serve --watch --force_polling --verbose
    ports:
      - 4000:4000
    volumes:
      - ./blog:/srv/jekyll

For simple usage in development I defined jekyll serve as my default command so that I can use docker-compose up to be ready for development.

In Gitlab CI you can use the docker-engine directly which would allow to directly load the jekyll image but unfortunately you can’t define a volume yet. So their needed to be another solution.

I came up with a Docker-in-Docker setup. The idea is to start Docker within the Container that gets started by Gitlab CI and define the volume in it. Even better, we can make use of our already existing docker-compose file that already defines the Jekyll version and the path to our page.

So I came up with the following pipeline:

image: tmaier/docker-compose:18.09

services:
  - docker:dind

build-blog:
  script:
    - docker-compose -f docker-compose.yml run -e JEKYLL_ENV=production blog jekyll build

The image I’m using is well maintained and provides docker-compose. The docker:dind service starts the docker daemon as its entrypoint.

With that up and running we can simply use our docker-compose.yml file and run it with the jekyll build command. The -e JEKYLL_ENV=production sets the JEKYLL_ENV environment that is used by many plugins to do optimizations.

Now we can proceed with the resulting artifact and do whatever we need to do. In my case I have another stage that deploys the page on my webserver.

Update

Check out the source code in the repository of this page.