Tom's Blog

Nix for Zola

Table of contents

Repo-local Nix flake

As an experiment, I wanted to install the Zola CLI with a repo-local Nix Flake. In other words, I checked in a flake.nix (and flake.lock) file into the repo hosting my blog content. The idea here is that this config is portable to any machine with Nix installed, as basically an analog to a .tool-versions for Mise or asdf.

The flake.nix:

outputs =
  { nixpkgs, flake-utils }:
  flake-utils.lib.eachDefaultSystem (
    system:
    let
      pkgs = nixpkgs.legacyPackages.${system};
    in
    {
      devShells.default = pkgs.mkShell {
        packages = with pkgs; [
          zola
        ];
      };
    }
  );

Analysis

This configures the installation Zola CLI from NixPkgs Unstable when you run nix develop, giving you access to zola in the develop sub-shell. This simple case is extremely trivial but lays the groundwork for me to use this pattern in the future with more complex repository toolsets.

But this seems like a lot of code to install a single package?

Sure, but what's the best way to learn how to use something other than the simplest possible case?

The Cool Part

Once you have your entire repository's worth of build-time tooling set up with a Nix Flake, you can just rely on Nix in CI! Here's the relevant sections of the Forgejo CI yaml for the blog repo:


jobs:
  build-and-deploy:
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          # Bear blog checks out as a submodule
          submodules: true

      - name: Install Nix
        uses: https://github.com/cachix/install-nix-action@v31
        with:
          nix_path: nixpkgs=channel:nixpkgs-unstable
          extra_nix_config: |
            experimental-features = nix-command flakes

      - name: Check Zola version
        run: nix develop --command zola --version

      - name: Build
        run: nix develop --command zola build --base-url https://toms-blog.pages.dev/

In the long term I think I'm going to bake a custom runner image that already has Nix installed to make this CI take even less time :D