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---
2.9 KiB
Docker Guide
Orca is available as a container image on the Gitea container registry. The image is a minimal distroless static build (~2MB runtime layer) that runs the orca binary directly.
Image
git.cloudinit.dev/coreci/orca:<version>
git.cloudinit.dev/coreci/orca:latest
The image is built from the Dockerfile in the repo root:
- Build stage:
golang:1.25— compiles a static binary withCGO_ENABLED=0(modernc/sqlite is pure Go, no CGO). - Runtime stage:
gcr.io/distroless/static-debian12:nonroot— ~2MB, no shell, runs asnonrootuser.
Pull
docker pull git.cloudinit.dev/coreci/orca:latest
# or pin a version
docker pull git.cloudinit.dev/coreci/orca:v0.4.4
The repo is public (REQ-045), so anonymous pull works without login.
Run
# Print version
docker run --rm git.cloudinit.dev/coreci/orca:v0.4.4 version
# Initialize state (creates /var/lib/orca/ inside the container)
docker run --rm -v orca-data:/var/lib/orca git.cloudinit.dev/coreci/orca:v0.4.4 init
# Run the daemon (persist state via volume)
docker run -d --name orca \
-p 8080:8080 \
-v orca-data:/var/lib/orca \
git.cloudinit.dev/coreci/orca:v0.4.4 daemon --addr=:8080
State Persistence
The image sets ENV ORCA_HOME=/var/lib/orca. All orca state (SQLite
database, CA certs, server certs) is written under this path. To
persist state across container restarts, mount a volume:
docker volume create orca-data
docker run --rm -v orca-data:/var/lib/orca git.cloudinit.dev/coreci/orca:v0.4.4 init
docker run -d --name orca -p 8080:8080 -v orca-data:/var/lib/orca git.cloudinit.dev/coreci/orca:v0.4.4 daemon
Without a volume, state is lost when the container exits.
System-Level Namespace Inside Containers
The --system flag is not needed inside containers — the image already
sets ORCA_HOME=/var/lib/orca. Use --system only if you want a
different namespace root (e.g., /root/.orca), which requires running
as root (the distroless image runs as nonroot by default).
Build Locally
docker build --build-arg VERSION=v0.4.4 -t orca-local:v0.4.4 .
docker run --rm orca-local:v0.4.4 version
Build args:
VERSION— semver tag (injected via-ldflags)GIT_COMMIT— short commit hashBUILD_TIME— ISO 8601 build timestamp
Publish (for maintainers)
The .coreci.yml release pipeline includes a container-publish step
that builds and pushes the image on every tag release. To publish
manually:
export GITEA_TOKEN=<token>
docker build --build-arg VERSION=v0.4.4 -t git.cloudinit.dev/coreci/orca:v0.4.4 -t git.cloudinit.dev/coreci/orca:latest .
echo "$GITEA_TOKEN" | docker login git.cloudinit.dev -u cloudinit-bot --password-stdin
docker push git.cloudinit.dev/coreci/orca:v0.4.4
docker push git.cloudinit.dev/coreci/orca:latest
See Also
- Install Guide — binary install (alternative to Docker).
- Namespace and Paths —
ORCA_HOMEand--systemflag.