ci-actions/docker-build-nix
Christopher Mühl 3ff832a982
fix: use /tmp for TMPDIR instead of PWD/tmp
/tmp should always be writable in containers, whereas PWD/tmp
might not be accessible from nested containers.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-04 17:19:27 +01:00
..
action.yaml fix: use /tmp for TMPDIR instead of PWD/tmp 2026-03-04 17:19:27 +01:00
README.md feat: add docker-build-nix action for reproducible OCI images 2026-03-04 12:11:29 +01:00

docker-build-nix

Build and push Docker/OCI images generated by Nix flakes, with Attic cache integration.

Features

  • Reproducible builds: Uses Nix flakes for bit-for-bit identical images
  • Attic caching: Pushes build artifacts to your Attic cache for faster subsequent builds
  • Nix store optimization: Leverages Nix's existing binary caches (nixos.org + your Attic)
  • Smaller images: Nix dockerTools.buildLayeredImage creates optimized layers

Usage

Basic example

name: Build Docker Image
on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: nix  # Requires runner with Nix
    steps:
      - uses: actions/checkout@v4

      - uses: https://git.toph.so/toph/ci-actions/docker-build-nix@main
        with:
          flake-output: .#dojo-image
          image-name: toph/dojo
          registry-password: ${{ secrets.GITEA_TOKEN }}
        env:
          ATTIC_TOKEN: ${{ secrets.ATTIC_TOKEN }}

Multiple images

jobs:
  build-web:
    runs-on: nix
    steps:
      - uses: actions/checkout@v4
      - uses: https://git.toph.so/toph/ci-actions/docker-build-nix@main
        with:
          flake-output: .#dojo-image
          image-name: toph/dojo
          image-tag: main
          registry-password: ${{ secrets.GITEA_TOKEN }}
        env:
          ATTIC_TOKEN: ${{ secrets.ATTIC_TOKEN }}

  build-agent:
    runs-on: nix
    steps:
      - uses: actions/checkout@v4
      - uses: https://git.toph.so/toph/ci-actions/docker-build-nix@main
        with:
          flake-output: .#agent-image
          image-name: toph/dojo/agent
          image-tag: main
          registry-password: ${{ secrets.GITEA_TOKEN }}
        env:
          ATTIC_TOKEN: ${{ secrets.ATTIC_TOKEN }}

Inputs

Input Required Default Description
flake-output - Nix flake output (e.g., .#dojo-image)
image-name - Target image name (e.g., user/repo)
registry-password - Registry password/token
image-tag main Image tag
registry git.toph.so Docker registry
registry-username ${{ gitea.actor }} Registry username
cache-name ci Attic cache name
attic-endpoint https://cache.toph.so Attic endpoint

Environment Variables

Variable Required Description
ATTIC_TOKEN Optional Attic token for pushing to cache. If not set, skips cache push.

How It Works

  1. Build with Nix: Runs nix build <flake-output> which uses Nix caching
  2. Push to Attic: Uploads the entire build closure to your Attic cache
  3. Load to Docker: Loads the OCI tarball into local Docker daemon
  4. Tag & Push: Tags and pushes to your Docker registry

Example Flake

Your flake.nix should export image outputs:

{
  outputs = { self, nixpkgs }:
    let
      pkgs = import nixpkgs { system = "x86_64-linux"; };
    in
    {
      packages.x86_64-linux = {
        # Your app
        default = pkgs.callPackage ./package.nix { };

        # OCI image
        dojo-image = pkgs.dockerTools.buildLayeredImage {
          name = "dojo";
          tag = "latest";
          contents = [ self.packages.x86_64-linux.default ];
          config = {
            Cmd = [ "${self.packages.x86_64-linux.default}/bin/dojo" ];
          };
        };
      };
    };
}

Prerequisites

  • Nix runner: Runner with nix label using docker://registry.toph.so/nix-runner:latest
  • Attic cache: Optional but recommended for caching (cache.toph.so)
  • ATTIC_TOKEN: Set in Forgejo secrets if you want cache push
  • GITEA_TOKEN: Auto-available in Forgejo Actions

Comparison with docker-build

Feature docker-build docker-build-nix
Build method Docker Nix
Reproducibility Layer-dependent Byte-for-byte
Caching S3 layers Attic derivations
Image size Larger Optimized
Runner Any Requires Nix

See Also