Docker Builds¶
Automated Docker image builds using GitHub Actions with multi-architecture support and GitHub Container Registry (GHCR).
Overview¶
Custom Docker images live in the docker/ directory at the repository root. Each subdirectory contains a Dockerfile and any supporting files for a single image.
docker/
├── app-one/
│ └── Dockerfile
├── app-two/
│ ├── Dockerfile
│ └── config.yaml
└── app-three/
└── Dockerfile
Auto-Discovery¶
The build workflow automatically discovers which images need to be built based on the trigger:
On Push to main¶
When files under docker/ are changed and pushed to main, the workflow uses tj-actions/changed-files to detect which subdirectories have been modified:
- id: changed
uses: tj-actions/changed-files@v47
with:
dir_names: "true"
dir_names_max_depth: "2"
files: docker/**
json: "true"
escape_json: "false"
Only the changed images are built, saving time and compute resources.
On Manual Dispatch¶
When manually triggered via workflow_dispatch, all images under docker/ are discovered and built:
Version Extraction¶
Image versions are automatically extracted from the Dockerfile's ARG directives:
The build step uses a regex to extract the version:
| Scenario | Tag |
|---|---|
ARG APP_VERSION=1.2.3 found | 1.2.3 |
No *_VERSION ARG found | Git commit SHA |
Version ARG Naming
Any ARG ending in _VERSION will be detected. Common patterns:
Multi-Platform Builds¶
All images are built for two architectures using Docker Buildx and QEMU emulation:
| Platform | Architecture | Use Case |
|---|---|---|
linux/amd64 | x86_64 | Intel/AMD worker nodes |
linux/arm64 | AArch64 | Raspberry Pi nodes |
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v6
with:
context: docker/${{ matrix.image }}
platforms: linux/amd64,linux/arm64
push: true
tags: |
ghcr.io/swibrow/${{ matrix.image }}:<version>
ghcr.io/swibrow/${{ matrix.image }}:latest
Build Times
ARM64 builds on AMD64 runners use QEMU emulation, which is slower than native builds. Expect ARM64 builds to take 2-5x longer than AMD64 builds.
Registry¶
All images are pushed to the GitHub Container Registry (GHCR):
Authentication¶
The workflow authenticates using the built-in GITHUB_TOKEN:
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
Permissions¶
The build job requires packages: write permission to push images:
Image Tags¶
Each successful build produces two tags:
| Tag | Purpose |
|---|---|
<version> | Immutable version tag extracted from Dockerfile |
latest | Rolling tag pointing to the most recent build |
Example for an image rrda with ARG RRDA_VERSION=2.1.0:
Adding a New Docker Image¶
-
Create a new directory under
docker/: -
Add a
Dockerfilewith a version ARG: -
Commit and push to
main: -
The build workflow will automatically detect the new directory and build the image.
-
The image will be available at:
Matrix Strategy¶
The build job uses a matrix strategy to build all discovered images in parallel:
This means if three images change in a single push, three build jobs run concurrently, each handling one image independently.