- Dockerfile: deterministic build from pinned CONTAINER_APP_VERSION + FEATURES - Merges named feature branches at specific SHAs for reproducibility - Switch CronJob to custom image with --clone-url-base and --all-organizations - Add kingfisher to service-versions.yaml (version tracks upstream main SHA) - Document spork container builds in new how-to card - Document spork workflow in CLAUDE.md - Update kingfisher service docs for custom image Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2.8 KiB
| title | modified | last-reviewed | tags | |||
|---|---|---|---|---|---|---|
| Build a Spork Container | 2026-03-29 | 2026-03-29 |
|
Build a Spork Container
How to build a container image from a spork-strategy project with fully-pinned, reproducible inputs.
Why not use the deploy branch directly?
The deploy branch is force-pushed on every mirror-sync. Building from deploy is not reproducible — the same Dockerfile run a week later gives different code. Instead, spork containers build their own merge tree from explicit inputs:
CONTAINER_APP_VERSION— the commit onmainto base on (the upstream version)FEATURES— space-separatedbranch=shapairs to merge on top
This makes builds reproducible regardless of when they run.
Prerequisites
- Sporked project set up (see create-a-spork)
- Container build tooling (
mise run container-build-and-release)
Get the SHAs
cd ~/code/3rd/kingfisher
git fetch origin
# Upstream SHA (what main is based on)
git rev-parse --short origin/main
# e.g., 1d37d29
# Feature branch SHAs
git rev-parse --short origin/feature/upstream/clone-url-base
# e.g., 677c7a5
Build the container
# The version in service-versions.yaml is the upstream SHA
mise run container-build-and-release kingfisher 1d37d29 \
--build-arg CONTAINER_APP_VERSION=1d37d29 \
--build-arg FEATURES="feature/upstream/clone-url-base=677c7a5"
The container tag will be 1d37d29-<blumeops-commit>.
Update the deployment
- Update
argocd/manifests/kingfisher/kustomization.yamlwith the new tag - Update
service-versions.yamlif the upstream SHA changed - Sync the ArgoCD app
How the Dockerfile works
The build stage:
- Clones the sporked repo from forge
- Checks out
mainatCONTAINER_APP_VERSION - For each entry in
FEATURES, fetches the branch and merges at the pinned SHA - Builds from source with
cargo build --release
If any merge conflicts, the build fails loudly.
The runtime stage is minimal: debian-slim + git + the binary.
Note on CONTAINER_APP_VERSION
For most blumeops containers, CONTAINER_APP_VERSION is an upstream release version like 5.22.0 or v2.19.2. For sporked containers it's a git SHA — the upstream commit the build is based on. This is a deliberate abuse of the naming convention to satisfy the container-version-check hook. Don't confuse it with an upstream release number.
Reproducibility guarantee
Given the same CONTAINER_APP_VERSION and FEATURES, the build produces identical source code regardless of what deploy, blumeops, or main currently look like on forge. The only external dependency is the Rust/Boost toolchain version in the FROM line.
See also
- create-a-spork — initial spork setup
- manage-spork-branches — feature branch workflow
- kingfisher — first sporked project