Docker image lifecycle and GHCR publishing
Generated page
Model gemma-mtp, commit f508a4b65b3f, 2026-08-15, sources: 6. Edit the code or the hand-written documentation instead.
Diagram
The release workflow and tag-based publishing
The publishing process is triggered by git tags matching the v* pattern or via manual dispatch release.yml:12. The workflow performs a critical transformation of the repository name into a lowercase registry path to comply with container registry requirements release.yml:54. The version is derived by stripping the leading 'v' from the git tag, ensuring that a tag like v0.1.0 results in an image tagged :0.1.0 release.yml:50.
The check gate and distribution integrity
To prevent the "shipping of unchecked code," the release workflow enforces a strict order of operations. It first runs ./gradlew check as a gate release.yml:62. The ci/docker-build.sh script is designed to respect this by explicitly running the gate before performing the :booblik-app:installDist task docker-build.sh:21-27. This ensures the image is built from a distribution that has already passed all tests, rather than building from a potentially broken local workspace docker-build.sh:5-7.
The docker-smoke conformance kit
The ci/docker-smoke.sh script performs deep inspection of the running container to ensure the runtime environment matches the measured profile. It validates that the process runs as the booblik user rather than root docker-smoke.sh:95. Crucially, it parses the jvm: line in the logs to verify that six specific flags—including -Xmx64M and -XX:MaxDirectMemorySize=32M—are present docker-smoke.sh:76-83. It also verifies that the broker's health check responds to METADATA requests docker-smoke.sh:87.
The sparse segment and volume persistence
A specific edge case is tested to ensure that the storage engine's performance characteristics are preserved in the image. The smoke test checks that when a segment is created, it remains "sparse" on the filesystem docker-smoke.sh:104. It does this by inspecting the stat output of the segment file to ensure the allocated blocks are significantly lower than the apparent file size docker-smoke.sh:102-104.
The latest tag and registry synchronization
Once the image is verified, the workflow performs a dual-push to GHCR. It tags the specific versioned image (e.g., :0.1.0) and the :latest pointer release.yml:87-89. This ensures that users can always pull the most recent stable version via the :latest tag while maintaining a permanent record of specific releases release.yml:88.
Key files
| File | Lines | What is there |
|---|---|---|
…/workflows/release.yml | 10-23 | Workflow trigger conditions and manual input definitions |
…/workflows/release.yml | 39-58 | Version extraction logic and registry path formatting |
ci/docker-smoke.sh | 76-83 | JVM runtime profile flag verification |
ci/docker-build.sh | 21-26 | Gate execution logic |
README.md | 69-72 | The specific JVM profile required for measurement |
Behaviour that surprises
- The
pipefailtrap: Indocker-smoke.sh:39, usinggrepin a pipeline withset -o pipefailcan cause a successful match to return a failure code (141) becausegrepexits early and sends aSIGPIPEtodocker logs. - The
installDistdependency: Theci/docker-build.shscript does not use a multi-stage Dockerfile; instead, it relies on the host to run:booblik-app:installDistfirst to ensure the image contains the exact distribution that passed the gatedocker-build.sh:27-32.