Custom Docker Image and CI Config File for Hugo and Madoko on GitLab

More detail about the custom Docker image and the GitLab CI config file I use.

Bryan Klein

3 minute read

I posted last year about using Hugo and Madoko in a Custom Docker Image for GitLab CI/CD. I received an email asking for more information about the image and my CI file setup. This post goes into a bit more detail about the GitLab CI configuration file that I used and what the various parts of it do in the build process.

The format and parameters of the yml file are specified in the GitLab CI documentation. I will explain my specific implementation details for my CI configuration file below.

image: registry.gitlab.com/zivbk1/bryanklein.com:latest

I created my own docker image that contained the version of Hugo, Madoko and LaTeX that I wanted to use. The image line tells the GitLab CI system to use my own image when running the rest of the build scripts that follow. See the docker config file that was used to build the image.

before_script:
  - chmod +x ./bin/hugo
  - bin/hugo version

The ‘before_script’ section is where you execute any commands, or set up environmental variables that might be necessary before the build scripts run. These commands are run within the system that is run from the image specified earlier.

In this case, I first make sure that the Hugo binary that I keep in my repository is executable in that system. I then run Hugo to test that it’s working by having it report the version that is being used. Instead of setting a version parameter like I would do in Netlify, I keep the version of Hugo that I want to use under version control, in the bin folder of my repo, and I make that file executable when I run my build scripts within the image. This way, I don’t have to worry about Netlify or anyone else supporting the version of Hugo that I want to use.

pages:
  script:
  - for filename in docs/*.mdk; do madoko -v --odir=static/html_docs $filename; done
  - bin/hugo

The pages section is the build target for all website pages. Within that target, I have a script section that runs a couple of commands. The first command runs Madoko over every file in the docs directory, in my repo, that ends with the ‘mdk’ extension. It sets the html output of Madoko to the ‘html_docs’ directory in the ‘static’ output folder. This is showing that I can use a different documentation system (Madoko) to build content that will be included in the final output of Hugo. As Hugo will pass through anything in the ‘static’ folder without processing it, to the final website output.

You can see an example html output page from Madoko in the html_docs directory of my website. This is the source file for that page in my repo.

  artifacts:
    paths:
    - public
  only:
  - master

The final part of the yml file tells the CI system where to get the files that should be used for the website content. Hugo by default builds its output to a folder named ‘public’ and the ‘only’ filter tells the build system to only build this ‘pages’ target when there is a commit to the ‘master branch of my repository. This way I could commit files in development to another branch in my repository and not trigger a build/update of my website.

As a final note, I have built other sites that do not use the same setup as I have on my personal site. Here is another repo for a PTA website that is also based on Hugo, but uses GitHub, Netfliy and Forestry.io instead of GitLab, GitLab CI, Cloudflare and Forestry.io.

I should probably write up some documents for that site too, it had some challenges along the way to get it all working as intended too. :)