feat: add docker-build reusable action
Add reusable action for building and pushing Docker images with: - S3 build cache support (SeaweedFS) - Optional Nix/Attic cache configuration - Auto-tagging based on branches, PRs, and semver tags - Multi-registry support Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
19468d38d8
commit
ac56aac0a7
2 changed files with 281 additions and 0 deletions
143
docker-build/README.md
Normal file
143
docker-build/README.md
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
# docker-build
|
||||
|
||||
Build and push Docker images with S3 caching and optional Nix cache support.
|
||||
|
||||
## Features
|
||||
|
||||
- **S3 build cache**: Uses your self-hosted S3 (SeaweedFS) for fast layer caching
|
||||
- **Nix cache integration**: Automatically configures Attic cache for Dockerfiles using Nix
|
||||
- **Auto-tagging**: Smart tagging based on branches, PRs, and semver tags
|
||||
- **Multi-registry support**: Works with Forgejo Docker registry or any other
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic example
|
||||
|
||||
```yaml
|
||||
name: Build Docker Image
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: https://git.toph.so/toph/ci-actions/docker-build@main
|
||||
with:
|
||||
dockerfile: ./Dockerfile
|
||||
image-name: git.toph.so/${{ gitea.repository }}
|
||||
registry-password: ${{ secrets.GITEA_TOKEN }}
|
||||
```
|
||||
|
||||
### With Nix cache support
|
||||
|
||||
For Dockerfiles that use Nix/Lix (e.g., `FROM ghcr.io/lix-project/lix`):
|
||||
|
||||
```yaml
|
||||
- uses: https://git.toph.so/toph/ci-actions/docker-build@main
|
||||
with:
|
||||
dockerfile: ./Dockerfile.nix
|
||||
image-name: git.toph.so/${{ gitea.repository }}/nix
|
||||
registry-password: ${{ secrets.GITEA_TOKEN }}
|
||||
enable-nix-cache: 'true'
|
||||
```
|
||||
|
||||
### Multiple images from one repo
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
build-web:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: https://git.toph.so/toph/ci-actions/docker-build@main
|
||||
with:
|
||||
dockerfile: ./deploy/Dockerfile
|
||||
image-name: git.toph.so/${{ gitea.repository }}
|
||||
registry-password: ${{ secrets.GITEA_TOKEN }}
|
||||
|
||||
build-worker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: https://git.toph.so/toph/ci-actions/docker-build@main
|
||||
with:
|
||||
dockerfile: ./deploy/Dockerfile.worker
|
||||
image-name: git.toph.so/${{ gitea.repository }}/worker
|
||||
registry-password: ${{ secrets.GITEA_TOKEN }}
|
||||
```
|
||||
|
||||
### Custom tags
|
||||
|
||||
```yaml
|
||||
- uses: https://git.toph.so/toph/ci-actions/docker-build@main
|
||||
with:
|
||||
dockerfile: ./Dockerfile
|
||||
image-name: git.toph.so/myorg/myapp
|
||||
registry-password: ${{ secrets.GITEA_TOKEN }}
|
||||
tags: |
|
||||
git.toph.so/myorg/myapp:latest
|
||||
git.toph.so/myorg/myapp:v1.0.0
|
||||
git.toph.so/myorg/myapp:stable
|
||||
```
|
||||
|
||||
## Inputs
|
||||
|
||||
| Input | Required | Default | Description |
|
||||
|-------|----------|---------|-------------|
|
||||
| `dockerfile` | ✅ | - | Path to Dockerfile |
|
||||
| `image-name` | ✅ | - | Full image name (e.g., `git.toph.so/user/repo`) |
|
||||
| `registry-password` | ✅ | - | Registry password/token |
|
||||
| `context` | ❌ | `.` | Build context path |
|
||||
| `registry` | ❌ | `git.toph.so` | Docker registry |
|
||||
| `registry-username` | ❌ | `${{ gitea.actor }}` | Registry username |
|
||||
| `push` | ❌ | `true` | Push image to registry |
|
||||
| `tags` | ❌ | auto-generated | Custom tags (newline-separated) |
|
||||
| `s3-cache-bucket` | ❌ | `docker-cache` | S3 bucket for build cache |
|
||||
| `s3-endpoint` | ❌ | `https://s3.toph.so` | S3 endpoint URL |
|
||||
| `enable-nix-cache` | ❌ | `false` | Configure Nix binary cache |
|
||||
| `attic-endpoint` | ❌ | `https://cache.toph.so` | Attic/Nix cache endpoint |
|
||||
|
||||
## Auto-generated tags
|
||||
|
||||
When `tags` input is not provided, tags are auto-generated based on the event:
|
||||
|
||||
| Event | Generated tags |
|
||||
|-------|----------------|
|
||||
| Push to `main` | `main`, `<short-sha>` |
|
||||
| Push tag `v1.2.3` | `1.2.3`, `1.2`, `1`, `latest`, `<short-sha>` |
|
||||
| Pull request #42 | `pr-42`, `<short-sha>` |
|
||||
|
||||
## S3 Cache
|
||||
|
||||
The action uses your self-hosted S3 (SeaweedFS) for Docker build cache layers, which:
|
||||
- Speeds up builds by reusing unchanged layers
|
||||
- Works across different runners and workflow runs
|
||||
- Automatically managed by Docker Buildx
|
||||
|
||||
**No additional setup required** — the cache is automatically used if S3 is accessible.
|
||||
|
||||
## Nix Cache Integration
|
||||
|
||||
When `enable-nix-cache: 'true'`, the action configures:
|
||||
- `cache.nixos.org` (official Nix cache)
|
||||
- `cache.toph.so/ci` (your CI cache, 90d retention)
|
||||
- `cache.toph.so/toph` (your trusted cache, 180d retention)
|
||||
|
||||
This allows Dockerfiles using Nix to fetch pre-built derivations instead of rebuilding from source.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
**For all builds:**
|
||||
- S3 service running at `s3.toph.so` (SeaweedFS)
|
||||
- `GITEA_TOKEN` secret configured (auto-available in Forgejo Actions)
|
||||
|
||||
**For Nix-enabled builds:**
|
||||
- Attic cache service running at `cache.toph.so`
|
||||
|
||||
## Examples
|
||||
|
||||
See the main [ci-actions README](../README.md) for infrastructure setup details.
|
||||
138
docker-build/action.yaml
Normal file
138
docker-build/action.yaml
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
name: Build and Push Docker Image
|
||||
description: Build and push a Docker image with S3 caching and Nix cache support
|
||||
|
||||
inputs:
|
||||
context:
|
||||
description: 'Build context path'
|
||||
required: false
|
||||
default: '.'
|
||||
|
||||
dockerfile:
|
||||
description: 'Path to Dockerfile'
|
||||
required: true
|
||||
|
||||
image-name:
|
||||
description: 'Full image name (e.g., git.toph.so/user/repo or git.toph.so/user/repo/image)'
|
||||
required: true
|
||||
|
||||
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
|
||||
|
||||
push:
|
||||
description: 'Push image to registry'
|
||||
required: false
|
||||
default: 'true'
|
||||
|
||||
tags:
|
||||
description: 'Custom tags (newline-separated), overrides auto-tagging'
|
||||
required: false
|
||||
|
||||
s3-cache-bucket:
|
||||
description: 'S3 bucket for Docker build cache'
|
||||
required: false
|
||||
default: 'docker-cache'
|
||||
|
||||
s3-endpoint:
|
||||
description: 'S3 endpoint URL'
|
||||
required: false
|
||||
default: 'https://s3.toph.so'
|
||||
|
||||
enable-nix-cache:
|
||||
description: 'Configure Nix binary cache for builds using Nix'
|
||||
required: false
|
||||
default: 'false'
|
||||
|
||||
attic-endpoint:
|
||||
description: 'Attic/Nix cache endpoint'
|
||||
required: false
|
||||
default: 'https://cache.toph.so'
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Configure Nix cache
|
||||
if: inputs.enable-nix-cache == 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p ~/.config/nix
|
||||
cat > ~/.config/nix/nix.conf <<EOF
|
||||
extra-substituters = https://cache.nixos.org/ ${{ inputs.attic-endpoint }}/ci ${{ inputs.attic-endpoint }}/toph
|
||||
extra-trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= ci:db8ZBxd5cjqoGzOYThRQcxj4XnaqHJZBZw1phCQOiz8= toph:E/oP7KyljH/yprI5LArxNPpSlQCdo29sMOkh3jm53Yg=
|
||||
experimental-features = nix-command flakes
|
||||
EOF
|
||||
|
||||
- name: Log in to registry
|
||||
if: inputs.push == 'true'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ inputs.registry }}
|
||||
username: ${{ inputs.registry-username }}
|
||||
password: ${{ inputs.registry-password }}
|
||||
|
||||
- name: Generate tags
|
||||
id: tags
|
||||
shell: bash
|
||||
run: |
|
||||
if [ -n "${{ inputs.tags }}" ]; then
|
||||
# Use custom tags if provided
|
||||
echo "tags=${{ inputs.tags }}" >> $GITHUB_OUTPUT
|
||||
else
|
||||
# Auto-generate tags based on event type
|
||||
TAGS=""
|
||||
IMAGE_BASE="${{ inputs.image-name }}"
|
||||
|
||||
# Branch name tag
|
||||
if [ "${{ github.event_name }}" = "push" ]; then
|
||||
BRANCH_NAME="${GITHUB_REF#refs/heads/}"
|
||||
TAGS="${TAGS}${IMAGE_BASE}:${BRANCH_NAME}\n"
|
||||
fi
|
||||
|
||||
# PR tag
|
||||
if [ "${{ github.event_name }}" = "pull_request" ]; then
|
||||
TAGS="${TAGS}${IMAGE_BASE}:pr-${{ github.event.pull_request.number }}\n"
|
||||
fi
|
||||
|
||||
# Tag-based versioning
|
||||
if [[ "${{ github.ref }}" == refs/tags/v* ]]; then
|
||||
VERSION="${GITHUB_REF#refs/tags/v}"
|
||||
TAGS="${TAGS}${IMAGE_BASE}:${VERSION}\n"
|
||||
MAJOR="${VERSION%%.*}"
|
||||
MINOR="${VERSION#*.}"
|
||||
MINOR="${MINOR%%.*}"
|
||||
TAGS="${TAGS}${IMAGE_BASE}:${MAJOR}.${MINOR}\n"
|
||||
TAGS="${TAGS}${IMAGE_BASE}:${MAJOR}\n"
|
||||
TAGS="${TAGS}${IMAGE_BASE}:latest\n"
|
||||
fi
|
||||
|
||||
# SHA tag
|
||||
SHORT_SHA="${GITHUB_SHA:0:7}"
|
||||
TAGS="${TAGS}${IMAGE_BASE}:${SHORT_SHA}"
|
||||
|
||||
echo -e "tags<<EOF" >> $GITHUB_OUTPUT
|
||||
echo -e "$TAGS" >> $GITHUB_OUTPUT
|
||||
echo "EOF" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: ${{ inputs.context }}
|
||||
file: ${{ inputs.dockerfile }}
|
||||
push: ${{ inputs.push }}
|
||||
tags: ${{ steps.tags.outputs.tags }}
|
||||
cache-from: type=s3,region=auto,bucket=${{ inputs.s3-cache-bucket }},endpoint_url=${{ inputs.s3-endpoint }}
|
||||
cache-to: type=s3,region=auto,bucket=${{ inputs.s3-cache-bucket }},endpoint_url=${{ inputs.s3-endpoint }},mode=max
|
||||
Loading…
Add table
Reference in a new issue