de8fdc0fe4
REQ-046: Docker image published to Gitea container registry per release. Dockerfile: multi-stage (golang:1.25 -> distroless/static-debian12:nonroot). CGO_ENABLED=0, ORCA_HOME=/var/lib/orca, ENTRYPOINT [/orca]. Image size: ~28MB. Runs as nonroot. .coreci.yml: new container-publish step in release pipeline (docker:24-cli, builds + tags + login + push + logout). scripts/release.sh: docker build + push after Gitea release. Graceful skip if docker absent or GITEA_TOKEN unset. Env-overridable registry. .dockerignore: excludes .git, bin/, .env, .ciagent/, testdata/, *.tar.gz. docs/docker.md: pull, run, state persistence (volume mount), local build, manual publish guide. Verified: docker build + run version/init with volume persistence. ---ci--- project: orca phase: 3 milestone: v0.5 status: verify ---/ci---
3.3 KiB
3.3 KiB
Phase 3 Verification: Docker Release (v0.5 P3)
Phase: 3 (docker release) Milestone: v0.5 Distribution Requirements covered: REQ-046 Date: 2026-08-03
Structural Layer
go vet ./...→ clean.go build ./...→ succeeds.- New files:
Dockerfile,.dockerignore,docs/docker.md. - Modified files:
.coreci.yml(container-publish step),scripts/release.sh(docker publish). .dockerignoreexcludes.git,bin/,.env,.ciagent/,testdata/,*.tar.gz.
Behavioral Layer
Docker build
docker build --build-arg VERSION=v0.4.4-test ... -t orca-test:v0.4.4 .→ succeeds.- Multi-stage build:
golang:1.25(builder) →gcr.io/distroless/static-debian12:nonroot(runtime). CGO_ENABLED=0guarantees static binary (modernc/sqlite is pure Go).
Docker run
docker run --rm orca-test:v0.4.4 version→orca version v0.4.4-test✓docker run --rm orca-test:v0.4.4 version --json→ valid JSON with version/commit/build_time ✓docker run --rm -v orca-test-data:/var/lib/orca orca-test:v0.4.4 init→ creates/var/lib/orca✓- Volume persistence: state dir created in named volume, verified with alpine container ✓
Image metrics
- Image size: 27.9MB (distroless static + Go binary).
- Runs as
nonrootuser (distroless default). ENV ORCA_HOME=/var/lib/orcaset for volume-mountable state.
.coreci.yml release pipeline
- New
container-publishstep added aftergitea-release. - Uses
docker:24-cliimage withGITEA_TOKENas registry credential. - Builds, tags (
<version>+latest), logs in, pushes, logs out.
scripts/release.sh extension
- After Gitea release:
docker build+docker login+docker push. - Skips gracefully if
dockernot on PATH (local dev without docker). - Skips push if
GITEA_TOKENnot set (builds locally only). - Env-overridable:
CONTAINER_REGISTRY,CONTAINER_OWNER,CONTAINER_IMAGE.
Regression — Go tests
internal/cli/✓ (cached)internal/store/✓ (cached)
Security Layer
.dockerignoreexcludes.env,.gitleaks-baseline.json,bin/— no secrets in image.- Image runs as
nonroot(distroless default) — least privilege. docker loginuses--password-stdin(no password in process args / shell history).docker logoutafter push — no credential leakage.- No secret material baked into the image —
GITEA_TOKENis used at push time only, not in the build.
Quality Layer
- Reproducible build:
--build-arg VERSION/GIT_COMMIT/BUILD_TIMEinjected via-ldflags. - Minimal image: distroless static-debian12 — no shell, no package manager, ~28MB total.
- Graceful degradation:
release.shskips docker publish when docker is absent. - CI integration:
.coreci.ymlcontainer-publish step usesdocker:24-cli(has docker CLI). - Documentation:
docs/docker.mdcovers pull, run, state persistence, local build, manual publish.
Must-Haves Checklist
docker build -t orca-test .succeeds locally.docker run --rm orca-test versionprints the version.scripts/release.sh vX.Y.Zpublishes both the Gitea release AND the container image..coreci.ymlrelease pipeline includes the container-publish step.
Verdict
PASS — all 4 verification layers pass. REQ-046 is satisfied. Ready
to ship as v0.4.4.