Files
orca/.ciagent/PHASE3_VERIFICATION.md
T
Jon Chery de8fdc0fe4 feat(P03): docker release — multi-stage Dockerfile + Gitea container registry publish
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---
2026-08-03 18:52:36 +00:00

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).
  • .dockerignore excludes .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=0 guarantees static binary (modernc/sqlite is pure Go).

Docker run

  • docker run --rm orca-test:v0.4.4 versionorca 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 nonroot user (distroless default).
  • ENV ORCA_HOME=/var/lib/orca set for volume-mountable state.

.coreci.yml release pipeline

  • New container-publish step added after gitea-release.
  • Uses docker:24-cli image with GITEA_TOKEN as 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 docker not on PATH (local dev without docker).
  • Skips push if GITEA_TOKEN not set (builds locally only).
  • Env-overridable: CONTAINER_REGISTRY, CONTAINER_OWNER, CONTAINER_IMAGE.

Regression — Go tests

  • internal/cli/ ✓ (cached)
  • internal/store/ ✓ (cached)

Security Layer

  • .dockerignore excludes .env, .gitleaks-baseline.json, bin/ — no secrets in image.
  • Image runs as nonroot (distroless default) — least privilege.
  • docker login uses --password-stdin (no password in process args / shell history).
  • docker logout after push — no credential leakage.
  • No secret material baked into the image — GITEA_TOKEN is used at push time only, not in the build.

Quality Layer

  • Reproducible build: --build-arg VERSION/GIT_COMMIT/BUILD_TIME injected via -ldflags.
  • Minimal image: distroless static-debian12 — no shell, no package manager, ~28MB total.
  • Graceful degradation: release.sh skips docker publish when docker is absent.
  • CI integration: .coreci.yml container-publish step uses docker:24-cli (has docker CLI).
  • Documentation: docs/docker.md covers pull, run, state persistence, local build, manual publish.

Must-Haves Checklist

  • docker build -t orca-test . succeeds locally.
  • docker run --rm orca-test version prints the version.
  • scripts/release.sh vX.Y.Z publishes both the Gitea release AND the container image.
  • .coreci.yml release pipeline includes the container-publish step.

Verdict

PASS — all 4 verification layers pass. REQ-046 is satisfied. Ready to ship as v0.4.4.