Skip to main content

Docker

Chronos ships with a production-ready Dockerfile for containerized deployment.

Building the Image​

docker build -f deploy/docker/Dockerfile -t chronos .

Or use the Makefile:

make docker-build

This builds a multi-stage image (deploy/docker/Dockerfile):

  1. Build stage (golang:1.25-alpine) -- compiles the CLI binary with CGO_ENABLED=0 (the SQLite adapter uses the pure-Go modernc.org/sqlite driver, so no C toolchain is needed)
  2. Runtime stage (alpine:3.24) -- minimal image with only the binary, CA certs/timezone data, and a non-root chronos user

Running​

docker run -p 8420:8420 chronos serve :8420

With Environment Variables​

docker run -p 8420:8420 \
-e OPENAI_API_KEY=sk-... \
-e CHRONOS_DB_PATH=chronos.db \
chronos serve :8420

With Persistent Storage​

Mount a volume for the SQLite database:

docker run -p 8420:8420 \
-v chronos-data:/data \
-e CHRONOS_DB_PATH=/data/chronos.db \
chronos serve :8420

With PostgreSQL​

For production, use PostgreSQL instead of SQLite:

docker run -p 8420:8420 \
-e CHRONOS_STORAGE_BACKEND=postgres \
-e CHRONOS_STORAGE_DSN="postgres://user:pass@db-host:5432/chronos?sslmode=require" \
chronos serve :8420

See Configuration for the full list of CHRONOS_* environment variables (storage backend selection, auth, rate limiting, etc.).

Docker Compose​

Example docker-compose.yml for a full stack:

version: "3.8"

services:
chronos:
build:
context: .
dockerfile: deploy/docker/Dockerfile
ports:
- "8420:8420"
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY}
- CHRONOS_STORAGE_BACKEND=postgres
- CHRONOS_STORAGE_DSN=postgres://chronos:chronos@postgres:5432/chronos?sslmode=disable
depends_on:
- postgres
restart: unless-stopped

postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: chronos
POSTGRES_PASSWORD: chronos
POSTGRES_DB: chronos
volumes:
- pgdata:/var/lib/postgresql/data
ports:
- "5432:5432"

qdrant:
image: qdrant/qdrant:latest
ports:
- "6333:6333"
volumes:
- qdrant-data:/qdrant/storage

volumes:
pgdata:
qdrant-data:

Local Development Stack​

deploy/local/ ships a one-command Postgres-backed local mirror of the production platform — the real server (unlocking the store-backed cross-replica scheduler and shared SQL rate limiter) plus Prometheus and Grafana for observability:

cd deploy/local
cp .env.example .env
docker compose up -d --build
# …or, from the repo root:
make dev-up
ServiceURLNotes
Chronos APIhttp://localhost:8420REST + SSE control plane
Health (ready)http://localhost:8420/health/readyreadiness probe
Metricshttp://localhost:8420/metricsPrometheus text format
Swagger UIhttp://localhost:8420/swagger/on by default in .env.example
Prometheushttp://localhost:9090scrapes chronos:8420/metrics
Grafanahttp://localhost:3000login admin / admin — dev only

Grafana ships a provisioned dashboard ("Chronos — Local (Golden Signals)") covering request rate, error rate, latency percentiles, scheduler backlog, and Go runtime stats. See deploy/local/README.md for details.

Cross-Platform Builds​

Build for multiple architectures:

make build-cross

This produces binaries for:

  • linux/amd64
  • linux/arm64
  • darwin/amd64
  • darwin/arm64

Makefile Targets​

TargetDescription
make docker-buildBuild the Docker image
make docker-pushPush to container registry
make docker-runBuild and run locally
make build-crossCross-compile for all platforms
make dev-upBuild + start the local dev stack (chronos + postgres + prometheus + grafana)