"Using Guix Docker Images for Gitlab CI/CD"

January 16, 2026
Tags:

Over the years I've made several changes to how this website is hosted and deployed. In its original incarnation, it was a Jekyll site hosted with GitHub Pages. Eventually I felt the need to move the repository and its deployment to GitLab for one or more reasons. GitLab offers a Jekyll project for getting started with GitLab Pages. I ended up forking the Build Jekyll with Bundler repo as a starting point, migrating my styling and markdown posts afterwards.

As many others have, I felt the need to fiddle around with the choice of framework for my blog and learned about Haunt, a static site generator written in Guile, one of the GNU Scheme implementations. Haunt doesn't require markdown files as a source, offering several types of readers and allowing customization. By making a few small tweaks to my posts, mostly around my use of inline HTML which one of Haunt's dependencies didn't seem to like, I was able to migrate my blog to Haunt without too much fuss. I previously implemented a tags system in Jekyll to allow generating dedicated tag pages on build in addition to the aggregate tags page, but I found the approach cumbersome. Creating this functionality for my blog in Guile on the other hand was straighforward and cleaner.

Generating your site is done with

haunt build

transforming your underlying files into a static site with styling. The Haunt website offers two pathways to get the package. Either build from source, or do

guix install haunt

Guix (pronounced like geeks) bills itself as "a package manager for GNU/Linux systems".. "designed to give users more control over their general-purpose and specialized computing environments, and make these easier to reproduce over time and deploy to one or many devices." That package manager shares a lineage with Nix, and like Nix, there is also a proper distro centered on Guix as a package manager are core OS utility. Guix is also notable for using the GNU Shepherd as its init system and service manager. Guix and Shepherd are both written in Guile, with the Guix System using Guile for total configuration of the OS.

I thought it'd be interesting to make use of Guix to build my site directly on my CI/CD pipeline. After some searching, I came across a Docker image for using Guix in CI/CD. I have some initial challenges getting the build to work related to locale settings on the image, but landed on the gitlab-ci.yml file shown below that identifies needed dependencies from my project manifest file. With that in place, it runs haunt build, moves the generated site to the expected path, and GitLab Pages takes care of the rest.

# requiring the environment of GNU Guix for Haunt
image: metacall/guix


# the 'pages' job will deploy and build your site to the 'public' path
pages:
  stage: deploy
  script:
    - guix package -m manifest.scm
    - export GUIX_PROFILE="/root/.guix-profile"
    - source "$GUIX_PROFILE/etc/profile"
    - export GUIX_LOCPATH="$GUIX_PROFILE/lib/locale"
    - export LANG="en_US.UTF-8"
    - export LC_ALL="en_US.UTF-8"
    - haunt build
    - mv site public
  artifacts:
    paths:
      - public
  only:
    - master # this job will affect only the 'master' branch

Without a little further digging, I'm not fully sure what could be attributed to user error vs opportunities to customize the base Docker image, but I think it's an interesting way to customize and deploy my website.