ci-actions/docker-build-nix/action.yaml
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

88 lines
2.4 KiB
YAML

name: Build and Push Docker Image from Nix
description: Build OCI image with Nix flake, push to registry with Attic caching
inputs:
flake-output:
description: 'Nix flake output for the OCI image (e.g., .#dojo-image)'
required: true
image-name:
description: 'Target image name in registry (e.g., git.toph.so/user/repo)'
required: true
image-tag:
description: 'Image tag'
required: false
default: 'main'
registry:
description: 'Docker registry'
required: false
default: 'git.toph.so'
registry-username:
description: 'Registry username'
required: false
default: ${{ gitea.actor }}
registry-password:
description: 'Registry password/token'
required: true
cache-name:
description: 'Attic cache name to push build artifacts'
required: false
default: 'ci'
attic-endpoint:
description: 'Attic cache endpoint'
required: false
default: 'https://cache.toph.so'
runs:
using: composite
steps:
- name: Build OCI image with Nix
shell: bash
run: |
echo "Building ${{ inputs.flake-output }}..."
nix build "${{ inputs.flake-output }}" --print-build-logs
- name: Push build artifacts to Attic cache
shell: bash
if: env.ATTIC_TOKEN != ''
env:
ATTIC_TOKEN: ${{ env.ATTIC_TOKEN }}
run: |
# Configure attic client
mkdir -p ~/.config/attic
cat > ~/.config/attic/config.toml <<EOF
[servers.cache]
endpoint = "${{ inputs.attic-endpoint }}"
token = "${ATTIC_TOKEN}"
EOF
# Push entire closure to cache
attic push "${{ inputs.cache-name }}" ./result
- name: Load image into Docker
shell: bash
run: |
echo "Loading OCI image into Docker..."
docker load < ./result
- name: Tag and push to registry
shell: bash
run: |
# Extract image name from the loaded output
IMAGE_ID=$(docker images --format "{{.Repository}}:{{.Tag}}" | head -n1)
echo "Loaded image: $IMAGE_ID"
# Tag with target name
TARGET_IMAGE="${{ inputs.registry }}/${{ inputs.image-name }}:${{ inputs.image-tag }}"
echo "Tagging as: $TARGET_IMAGE"
docker tag "$IMAGE_ID" "$TARGET_IMAGE"
# Login and push
echo "${{ inputs.registry-password }}" | docker login ${{ inputs.registry }} -u ${{ inputs.registry-username }} --password-stdin
docker push "$TARGET_IMAGE"