Nix
Cache Nix store paths with Shipfox's colocated binary cache, reducing derivation build times across CI runs
Nix is a purely functional package manager and build system. Its binary cache stores built derivations (store paths) so that any machine with access to the cache can download pre-built outputs instead of rebuilding them from source.
Shipfox provides a built-in Nix binary cache on every runner at $SHIPFOX_NIX_URL. Store paths are uploaded and fetched over the local network, making cache operations much faster than reaching a public cache server.
How it works
When a Nix derivation is built, its output is stored in the Nix store under a content-addressed path. Shipfox's cache server implements the Nix binary cache protocol, which means any nix-build, nix build, or store realisation can pull pre-built paths from it and upload new ones after building.
In automatic mode, Shipfox configures the cache as an extra substituter and installs a post-build hook that uploads newly built store paths. This works whether Nix is pre-installed on the runner image or installed during the job.
Automatic setup
Automatic Nix cache setup depends on whether Nix is already installed on the runner when the job starts:
When Nix is installed during the job (e.g. via DeterminateSystems/nix-installer-action or nixbuild/nix-quick-install-action), Shipfox pre-sets the NIX_CONFIG environment variable. Nix installers read this variable and apply the settings automatically:
extra-substituters = <shipfox-cache-url>
extra-trusted-substituters = <shipfox-cache-url>
require-sigs = false
post-build-hook = /tmp/shipfox-nix-upload.shWhen Nix is already installed on the runner image, Shipfox appends the same settings to /etc/nix/nix.conf and installs the upload hook at /etc/nix/upload-to-shipfox-cache.sh.
In both cases, no workflow changes are required:
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@v21
- name: Build
run: nix build .#my-package
- name: Run tests
run: nix develop --command make testAutomatic caching is enabled by default. You can disable it per tool from your Organization Settings in the Shipfox dashboard if you prefer to manage the configuration yourself.
Manual setup
If you want full control over the Nix cache configuration, use the $SHIPFOX_NIX_URL environment variable exposed on every runner.
Fetch from cache: set the substituter so Nix downloads pre-built paths before building:
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@v21
with:
extra-conf: |
extra-substituters = ${{ env.SHIPFOX_NIX_URL }}
extra-trusted-substituters = ${{ env.SHIPFOX_NIX_URL }}
require-sigs = false
- name: Build
run: nix build .#my-packagePush to cache: upload a store path after building:
- name: Build
run: |
STORE_PATH=$(nix build .#my-package --no-link --print-out-paths)
nix copy --to "$SHIPFOX_NIX_URL" "$STORE_PATH"Full round-trip example: build, push, then verify by fetching from cache:
- name: Build and cache
run: |
STORE_PATH=$(nix-build --no-out-link default.nix)
nix copy --to "$SHIPFOX_NIX_URL" "$STORE_PATH"
echo "STORE_PATH=$STORE_PATH" >> "$GITHUB_ENV"
- name: Fetch from cache
run: nix copy --from "$SHIPFOX_NIX_URL" --no-check-sigs "$STORE_PATH"require-sigs = false is required because Shipfox's cache does not sign store paths. If you manage your own signing keys, you can omit this and configure signing separately.