Docker
topics is published as a single container image to the GitHub Container Registry at
ghcr.io/slopus/topics. The image is multi-arch (linux/amd64 and
linux/arm64), runs as a non-root user, and stores all durable state in a /data volume.
This page covers running it and how releases are cut.
Pull and run
The image binds 0.0.0.0:4000 inside the container. Because the server refuses to start
on a non-loopback bind with no API keys — it would be an open, unauthenticated event
store — you must pass either TOPICS_API_KEYS (any real deployment) or, for local/dev
only, TOPICS_ALLOW_INSECURE_NO_AUTH=1.
Production
# Production: bearer auth on. Clients send `Authorization: Bearer <key>`.
docker run --rm \
-p 4000:4000 \
-v topics-data:/data \
-e TOPICS_API_KEYS=replace-with-a-real-secret \
ghcr.io/slopus/topics:latest# → check it's up (health is always 200 once serving)
curl -fsS http://127.0.0.1:4000/v0/healthTOPICS_ALLOW_INSECURE_NO_AUTH=1 exists only so you can run the 0.0.0.0-binding image
locally without keys. On anything reachable from a network, set TOPICS_API_KEYS
instead. See Security.
What each flag does:
| Flag | Purpose |
|---|---|
-p 4000:4000 | Maps the container’s listen port (EXPOSE 4000) to the host. |
-v topics-data:/data | A named volume holding the WAL, segments, and snapshots. TOPICS_DATA_DIR defaults to /data in the image. |
-e TOPICS_API_KEYS=... | Comma-separated bearer keys (production). |
-e TOPICS_ALLOW_INSECURE_NO_AUTH=1 | Permits a keyless start on the 0.0.0.0 bind (local/dev only). |
The /data volume
The image sets TOPICS_DATA_DIR=/data and declares /data as a VOLUME. That directory
holds everything durable — the WAL, sealed segment files, and snapshots. Reuse the same
volume across restarts to preserve durable state; on the next start the server replays
the WAL from /data and recovers acknowledged writes. A fresh empty volume is a clean
first start.
# Inspect the durable state directory inside a running container.
docker exec -it <container> ls -la /dataFor the on-disk layout and optional hot→cold relocation (TOPICS_COLD_DIR), see
Storage & Tiering. For every tunable, see
Configuration.
Image internals
The image is built from a multi-stage Dockerfile and is deliberately minimal:
- Non-root. The server runs as a dedicated system user (
uid 10001) that owns/data. - Slim runtime. A
debian:bookworm-slimbase with onlyca-certificatesandcurl(the latter for the health check). Only thetopicsserver binary is shipped — thetopics-probetest/bench CLI is excluded to keep the image lean. - Defaults baked in.
TOPICS_HOST=0.0.0.0,TOPICS_PORT=4000,TOPICS_DATA_DIR=/data. EXPOSE 4000for the listen port.HEALTHCHECK. A built-in liveness probe runscurl -fsS http://127.0.0.1:$TOPICS_PORT/v0/healthevery 30s (5s timeout, 10s start period, 3 retries)./v0/healthis always 200 once the process is serving.
The container HEALTHCHECK hits /v0/health (liveness). For orchestrator readiness —
gating traffic until WAL replay completes — use /v0/ready, which returns 503 during
recovery and 200 once ready. See Running topics and
Observability.
Release flow
Releases are tag-driven, built by GitHub Actions, and published to GHCR.
-
Make sure
mainis green (CI runs build + test + clippy on every push and PR). -
Tag the commit with a
vX.Y.Zversion and push the tag:git tag v1.2.3 git push origin v1.2.3 -
The Publish container image workflow triggers on the
v*tag, builds the multi-arch image (linux/amd64+linux/arm64), attaches provenance and SBOM attestations, and pushes it to GHCR under three tags:Tag Example Meaning :X.Y.Zghcr.io/slopus/topics:1.2.3The exact version. :X.Yghcr.io/slopus/topics:1.2The latest patch of a minor line. :latestghcr.io/slopus/topics:latestThe newest tagged release.
You can also trigger the workflow manually from the Actions tab (workflow_dispatch); a
manual run is tagged with the short commit SHA instead of a version. The workflow uses the
built-in GITHUB_TOKEN with packages: write, so no extra secrets are required.
Pin a specific :X.Y.Z (or :X.Y) tag in production for reproducible deploys; reserve
:latest for evaluation.
See also
- Running topics — start, recovery, binding, and graceful shutdown.
- Configuration — every
TOPICS_*variable. - Security — keys, scopes, the prefix allowlist, and resource limits.
- Storage & Tiering — what lives under
/data.