ci-actions/docker-build-nix/README.md
Christopher Mühl b163ffa64b
feat: add docker-build-nix action for reproducible OCI images
Add reusable action for building Docker images with Nix flakes:
- Full reproducibility with Nix derivations
- Attic cache integration for build artifacts
- Optimized layering with dockerTools.buildLayeredImage
- Automatic Nix binary cache usage

Use this instead of docker-build when you want:
- Bit-for-bit identical builds
- Better caching via Attic/Nix
- Smaller, optimized images

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-04 12:11:29 +01:00

143 lines
4.2 KiB
Markdown

# 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
```yaml
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
```yaml
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:
```nix
{
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
- [docker-build](../docker-build/) - Traditional Docker builds with S3 cache
- [push-nix-cache](../push-nix-cache/) - Push arbitrary Nix paths to Attic