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>
143 lines
4.2 KiB
Markdown
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
|