67 docs indexed
All services, compose profiles, volumes, and networking in the obleth Docker Compose stack.
The Docker Compose stack lives in deploy/docker/. It is the recommended way to run obleth locally or in a staging environment.
cd obleth-gateway/deploy/docker
cp .env.example .env
# Core services only (postgres, redis, clickhouse, obleth, control-plane)
docker compose up -d
# Ad-hoc extras
docker compose --profile benchmark up -d
docker compose --profile benchmark --profile edge up -d
docker compose --profile benchmark --profile observability up -d
docker compose --profile slurm up -d
Run the commands from deploy/docker/ so Compose picks up .env from that
directory. Rather than passing --profile on every command, list the profiles
you want in COMPOSE_PROFILES in .env — .env.example ships with
COMPOSE_PROFILES=benchmark,edge,observability, so a single docker compose up -d --build brings up the whole dev stack.
| Profile | What it adds |
|---|---|
| (none) | obleth, postgres, redis, clickhouse, control-plane |
benchmark | benchmark-backend benchmark fixture service |
mock | Legacy alias for the benchmark fixture profile |
edge | HAProxy on port 80 |
observability | Prometheus, Grafana, Jaeger, plus the Postgres and Redis exporters |
slurm | obleth-provisioner Slurm plugin (keeps managed models alive on a Slurm cluster) |
compressor | Neural prose compression sidecar (the image bakes a ~600 MB ONNX model) |
sso-dev | Local Dex OIDC provider for dashboard SSO development |
The first-party services (obleth, control-plane, benchmark-backend, obleth-provisioner) declare both an image: tag (published to GHCR by the release workflow) and a build: context (local source). docker compose pull && docker compose up -d runs the published images; docker compose up --build builds from the working tree. Pin a specific release with OBLETH_VERSION=v0.9.6 in your .env. The published image paths are under ghcr.io/thediymaker/obleth-gateway/.
| Service | Source | Purpose |
|---|---|---|
obleth | built from ../.. | Main gateway |
postgres | postgres:16 | Config database |
redis | redis:7 | Hot cache + token budgets |
clickhouse | clickhouse/clickhouse-server:24.8 | Usage ledger |
control-plane | built from ../../control-plane | Dashboard |
benchmark-backend | built from ../../benchmark-backend | OpenAI-compatible benchmark fixture backend (benchmark profile) |
haproxy | haproxy:3.2 | Edge proxy (edge profile) |
prometheus | prom/prometheus:latest | Metrics collection (observability profile) |
grafana | grafana/grafana:latest | Dashboards (observability profile) |
jaeger | jaegertracing/all-in-one:1.60 | Distributed tracing (observability profile) |
postgres-exporter | quay.io/prometheuscommunity/postgres-exporter:latest | Postgres metrics on :9187 (observability profile) |
redis-exporter | oliver006/redis_exporter:latest | Redis metrics on :9121 (observability profile) |
obleth-provisioner | ghcr.io/thediymaker/obleth-gateway/obleth-provisioner | Slurm provisioner plugin (slurm profile) — see Slurm Provisioning |
compressor | ghcr.io/thediymaker/obleth-gateway/obleth-compressor | Neural prose compression sidecar (compressor profile) — see Model Boons |
dex | dexidp/dex:v2.41.1 | Local OIDC provider (sso-dev profile) — see Dashboard SSO |
| Service | Container port | Host port |
|---|---|---|
obleth data plane | 8080 | 8088 |
obleth admin | 9180 | 127.0.0.1:9180 |
obleth metrics | 9091 | 127.0.0.1:9091 |
postgres | 5432 | 127.0.0.1:5432 |
redis | 6379 | 127.0.0.1:6379 |
clickhouse HTTP | 8123 | 127.0.0.1:8123 |
clickhouse native | 9000 | 127.0.0.1:9000 |
benchmark-backend | 8081 | 8081 |
control-plane | 3000 | 3002 |
haproxy | 80 | 80 |
prometheus | 9090 | 127.0.0.1:9090 |
grafana | 3000 | 3001 |
jaeger UI | 16686 | 127.0.0.1:16686 |
jaeger OTLP | 4317, 4318 | 127.0.0.1:4317, 127.0.0.1:4318 |
dex | 5556 | 5556 |
HAProxy's 8404 (metrics + /stats), the compression sidecar's 8080, the
ClickHouse exporter's 9363, and the Postgres/Redis exporters (9187, 9121)
are exposed to the Compose network only and have no host binding.
| Volume | Mounted at | Contents |
|---|---|---|
pgdata | /var/lib/postgresql/data | Postgres data |
redisdata | /data | Redis AOF/RDB |
chdata | /var/lib/clickhouse | ClickHouse tables |
Copy the example file and edit it before starting the stack:
cp deploy/docker/.env.example deploy/docker/.env
Compose loads deploy/docker/.env automatically. The real .env is gitignored;
only the documented .env.example (with labeled dev examples) is committed.
Secrets are required — Compose uses ${VAR:?error} syntax and refuses to start
if they are unset:
# Required (no default — compose errors out if missing)
POSTGRES_PASSWORD=...
CLICKHOUSE_PASSWORD=...
OBLETH_ADMIN_TOKEN=... # openssl rand -hex 32
DASHBOARD_ADMIN_EMAIL=... # break-glass admin email (sign-in is email-based)
DASHBOARD_PASSWORD=... # >= 8 chars
DASHBOARD_SESSION_SECRET=... # >= 32 chars; openssl rand -hex 32
# Datastore identity (non-secret defaults; centralized here and composed into
# OBLETH_DATABASE_URL / ClickHouse URL)
POSTGRES_USER=obleth
POSTGRES_DB=obleth
CLICKHOUSE_USER=obleth
CLICKHOUSE_DB=obleth
# Recommended security hardening
OBLETH_ENCRYPTION_KEY=... # openssl rand -base64 32 (AES-256-GCM at rest)
OBLETH_API_KEY_PEPPER=... # openssl rand -hex 32
OBLETH_BLOCK_PRIVATE_NETWORKS= # set 1 for strict SSRF mode (private targets blocked by default-off)
OBLETH_ALLOWED_PRIVATE_CIDRS= # under strict mode, allow e.g. 10.0.0.0/8 for internal upstreams
# Common tuning
OBLETH_GLOBAL_MAX_IN_FLIGHT=64
OBLETH_FAIRSHARE_ALGORITHM=hierarchical
OBLETH_UPSTREAM_BASE_URL=http://benchmark-backend:8081
# Dashboard reachable by LAN IP or an alternate hostname (comma-separated).
# Without this, better-auth rejects logins whose Origin does not match
# BETTER_AUTH_URL.
TRUSTED_ORIGINS=http://192.168.1.50:3002
# Compressor profile (the sidecar is off until the URL is set)
OBLETH_COMPRESSOR_URL=http://compressor:8080
OBLETH_COMPRESSOR_TIMEOUT_MS=800
# Observability profile (required when running --profile observability)
GRAFANA_ADMIN_USER=admin # Grafana admin login
GRAFANA_ADMIN_PASSWORD=... # required — compose errors out if unset
# (anonymous access is disabled)
# Edge profile (HAProxy stats page auth)
HAPROXY_STATS_USER=admin
HAPROXY_STATS_PASSWORD=... # protects the :8404/stats page
The images run as a non-root user. The datastore ports, the Management API
(9180), the metrics endpoint (9091), Prometheus (9090), and Jaeger
(16686, 4317, 4318) are bound to 127.0.0.1, so they are reachable only
from the host — not the network. The data plane (8088), dashboard (3002),
and HAProxy (80) bind all interfaces.
cd deploy/docker
docker compose down
# Remove volumes (deletes ALL data: config, keys, and usage history)
docker compose down -v