Running the `cloacina-server` Docker image
The official cloacina-server image is published to the GitHub Container
Registry on every release tag and nightly on main. This page covers
pulling, configuring, and running it.
Pulling
Section titled “Pulling”# Latest stable releasedocker pull ghcr.io/colliery-io/cloacina-server:latest
# Pin to a specific versiondocker pull ghcr.io/colliery-io/cloacina-server:0.12.0
# Track main (rebuilt every night at 03:00 UTC)docker pull ghcr.io/colliery-io/cloacina-server:nightlyThe image is multi-arch (linux/amd64 + linux/arm64); Docker selects
the matching manifest automatically.
Tag scheme
Section titled “Tag scheme”| Tag | Updated | Notes |
|---|---|---|
latest |
every release | The most recent stable tag |
<X.Y.Z> |
one-shot | Immutable, pinned to that release |
<X.Y> |
every patch | Floats forward across patch releases |
nightly |
daily 03:00 UTC | Built from main |
Running
Section titled “Running”The server needs a Postgres database — DATABASE_URL is the only
required env var.
docker run --rm \ -e DATABASE_URL=postgres://cloacina:cloacina@host.docker.internal:5432/cloacina \ -p 8080:8080 \ ghcr.io/colliery-io/cloacina-server:latestOn startup it auto-runs migrations and (on first boot) generates a
bootstrap API key. Watch the logs for the key, or pin one with
-e CLOACINA_BOOTSTRAP_KEY=....
Common configuration
Section titled “Common configuration”All flags double as env vars:
| Flag | Env | Purpose |
|---|---|---|
--bind |
— | Bind address (default 127.0.0.1:8080; usually 0.0.0.0:8080 in containers) |
--database-url |
DATABASE_URL |
Postgres connection string |
--bootstrap-key |
CLOACINA_BOOTSTRAP_KEY |
Pin the initial admin API key |
--require-signatures |
CLOACINA_REQUIRE_SIGNATURES |
Reject unsigned packages |
--verification-org-id |
CLOACINA_VERIFICATION_ORG_ID |
Org UUID for signature verification |
--tenant-runner-cache-size |
CLOACINA_TENANT_RUNNER_CACHE_SIZE |
LRU cap on per-tenant runners (default 256) |
The image’s home directory is /home/cloacina/.cloacina
(CLOACINA_HOME is set so any tooling that reads it resolves correctly).
Compose example
Section titled “Compose example”services: postgres: image: postgres:16 environment: POSTGRES_USER: cloacina POSTGRES_PASSWORD: cloacina POSTGRES_DB: cloacina volumes: - cloacina-pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U cloacina"] interval: 5s retries: 12
cloacina-server: image: ghcr.io/colliery-io/cloacina-server:latest depends_on: postgres: condition: service_healthy environment: DATABASE_URL: postgres://cloacina:cloacina@postgres:5432/cloacina command: ["--bind", "0.0.0.0:8080"] ports: - "8080:8080" healthcheck: test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:8080/health || exit 1"] interval: 10s retries: 6
volumes: cloacina-pgdata:The image itself does not declare a HEALTHCHECK — orchestrators each
have their own probe story (compose example above; Kubernetes via the
Helm chart in CLOACI-T-0605).
Image properties
Section titled “Image properties”- Base:
debian:bookworm-slim+libpq5+ca-certificates - Compressed size: ~150 MB
- Runs as non-root (uid
10001, gid10001) - Exposes port
8080 - Source labelled via
org.opencontainers.image.sourceso ghcr links the image back to the repo
Building locally
Section titled “Building locally”docker build -t cloacina-server:dev .docker run --rm cloacina-server:dev --versionThe Dockerfile lives at the repo root; .dockerignore keeps build
artifacts and dev metadata out of the build context.
See also
Section titled “See also”- Deploying the API Server — full configuration reference (auth, signatures, multi-tenancy)
- Production Deployment — scaling and operational hardening