OBLETHdocs

Docker Compose

Services, profiles, required variables, volumes and overrides of the obleth Docker Compose stack in deploy/docker/.

5 min readUpdated for v2.4.0Edit on GitHub

The stack runs obleth on one host for development, evaluation or staging. Run every command from deploy/docker/ so Compose loads deploy/docker/.env. What each variable does, and how Compose sets it, is in Environment variables.

Start the stack

cd obleth-gateway/deploy/docker
cp .env.example .env          # then change every password and secret
docker compose up -d --build

docker compose pull && docker compose up -d runs the published images from ghcr.io/thediymaker/obleth-gateway/ instead of building. Pin a release in .env:

OBLETH_VERSION=v2.4.0
OBLETH_COMPRESSOR_VERSION=v2.4.0   # only with the compressor profile

OBLETH_VERSION defaults to latest; dev tracks edge builds. The compression sidecar has its own tag because edge builds skip it.

Profiles

Core services always start. .env.example sets COMPOSE_PROFILES=benchmark,edge,observability; leave it empty for the core services only, or add one for a single command with docker compose --profile slurm up -d.

ProfileAdds
none (core)postgres, redis, clickhouse, obleth, control-plane
benchmarkbenchmark-backend, a model-free test upstream
mockSame as benchmark
edgehaproxy on port 80
observabilityprometheus, grafana, jaeger, postgres-exporter, redis-exporter
slurmobleth-provisioner
compressorcompressor, the prose-compression sidecar (about 600 MB model)
sso-devdex, a local OIDC provider for testing dashboard SSO

Services

ServiceImageProfileRoleWaits for
postgrespostgres:16coreConfiguration and dashboard sign-in tables
redisredis:7coreHot cache and budgets; AOF on, password required
clickhouseclickhouse/clickhouse-server:24.8coreUsage ledger and spans
oblethobleth:${OBLETH_VERSION:-latest}coreData plane, Management API, metricspostgres, redis, clickhouse healthy
control-planecontrol-plane:${OBLETH_VERSION:-latest}coreDashboardobleth started, postgres healthy
benchmark-backendbenchmark-backend:${OBLETH_VERSION:-latest}benchmark, mockTest upstream; network alias mock-backend
compressorobleth-compressor:${OBLETH_COMPRESSOR_VERSION:-latest}compressorProse-compression scorer
obleth-provisionerobleth-provisioner:${OBLETH_VERSION:-latest}slurmSlurm replica reconcilerobleth started
dexdexidp/dex:v2.41.1sso-devOIDC provider; network alias host.docker.internal
haproxyhaproxy:3.2edgeFront door, see HAProxyobleth started
prometheusprom/prometheus:latestobservabilityScrapes obleth, ClickHouse, HAProxy and the exporters
grafanagrafana/grafana:latestobservabilityBundled dashboards; anonymous access offprometheus started
postgres-exporterquay.io/prometheuscommunity/postgres-exporter:latestobservabilityPostgres metricspostgres healthy
redis-exporteroliver006/redis_exporter:latestobservabilityRedis metricsredis healthy
jaegerjaegertracing/all-in-one:1.60observabilityOTLP trace collector and UI

First-party images are under ghcr.io/thediymaker/obleth-gateway/. The benchmark backend runs with a 20 ms time to first token, 3 ms per token and 256 concurrent requests. postgres, redis and clickhouse have healthchecks every 3 s; obleth, control-plane and compressor use the healthcheck built into their image (/health, /login and /health). Ports are listed in Endpoints and ports.

Required variables

Compose stops with an error when any of these is unset or empty. .env.example has development values for all of them; replace each before a shared deployment.

VariableUsed by
POSTGRES_PASSWORDpostgres, postgres-exporter, and both database URLs
REDIS_PASSWORDredis, redis-exporter, and OBLETH_REDIS_URL
CLICKHOUSE_PASSWORDclickhouse and the gateway
OBLETH_ADMIN_TOKENobleth, control-plane, obleth-provisioner
DASHBOARD_PASSWORDcontrol-plane break-glass admin, at least 8 characters
DASHBOARD_SESSION_SECRETcontrol-plane, also as BETTER_AUTH_SECRET; at least 32 characters
GRAFANA_ADMIN_PASSWORDgrafana (observability profile)
openssl rand -hex 16       # POSTGRES_PASSWORD, REDIS_PASSWORD, CLICKHOUSE_PASSWORD
openssl rand -hex 32       # OBLETH_ADMIN_TOKEN, DASHBOARD_SESSION_SECRET
openssl rand -base64 32    # OBLETH_ENCRYPTION_KEY (optional, recommended)

Paste the values into .env; Compose does not run commands there. Keep REDIS_PASSWORD URL-safe, since it is placed in redis://:PASSWORD@redis:6379. After changing .env, recreate the service, for example docker compose up -d obleth.

Variables Compose does not forward

The obleth service hardcodes these, so a value in .env has no effect:

VariableFixed value
OBLETH_GLOBAL_MAX_IN_FLIGHT4096
OBLETH_DEFAULT_MODEL_MAX_IN_FLIGHT32
OBLETH_FAIRSHARE_HISTORY_SECS3600
OBLETH_FAIRSHARE_ALGORITHMhierarchical
OBLETH_CAPACITY_DISCOVERY_NAMESPACES, OBLETH_CAPACITY_DEFAULT_SERVICEempty (the kubernetes source needs a pod)
OBLETH_PROXY_LISTEN, OBLETH_ADMIN_LISTEN, OBLETH_METRICS_LISTEN0.0.0.0:8080, 0.0.0.0:9180, 0.0.0.0:9091
OBLETH_CLICKHOUSE_URLhttp://clickhouse:8123
RUST_LOGinfo,obleth=debug

OBLETH_UPSTREAM_POOL_IDLE_SECS, OBLETH_UPSTREAM_TCP_KEEPALIVE_SECS, OBLETH_PORT_SPAN and the provisioner's OBLETH_PROVISIONER_* variables other than RESTART_AFTER_FAILURES are not passed, so their defaults apply.

To change any of them, override the service's environment: in a second file:

# deploy/docker/compose.tuning.yml
services:
  obleth:
    environment:
      OBLETH_DEFAULT_MODEL_MAX_IN_FLIGHT: "64"
      OBLETH_FAIRSHARE_HISTORY_SECS: "7200"
docker compose -f docker-compose.yml -f compose.tuning.yml up -d obleth

Or set COMPOSE_FILE=docker-compose.yml:compose.tuning.yml in .env (; on Windows) so every command includes it.

The obleth service has stop_grace_period: 345s: the 300 s OBLETH_SHUTDOWN_GRACE_SECS drain, 20 s for the telemetry flush, 10 s for the trace exporter, and a margin. If you raise the grace period, raise stop_grace_period by the same amount in the override file. See shutdown and timeouts.

Volumes

VolumeServiceMounted atHolds
pgdatapostgres/var/lib/postgresql/dataConfiguration and sign-in tables
redisdataredis/dataAOF; rebuilt from Postgres if lost
chdataclickhouse/var/lib/clickhouseUsage ledger and spans

Read-only bind mounts supply clickhouse/prometheus.xml and clickhouse/system-logs.xml (ClickHouse's own logs at information level, with a week of its system log tables kept), haproxy.cfg, dex/config.docker.yaml, prometheus.yml and the Grafana provisioning and dashboards directories.

Standalone datastores

datastores.compose.yml runs Postgres, Redis and ClickHouse on their own, as a durable tier for a gateway that runs elsewhere (a Helm install with the bundled datastores off, or a binary):

cd deploy/docker
cp datastores.env.example datastores.env   # change every password
docker compose --env-file datastores.env -f datastores.compose.yml up -d

The project is named obleth-datastores and uses the same images and volume names. Ports publish on BIND_ADDR (default 127.0.0.1): 5432, 6379, 8123 and 9000. Set it to a private interface address to reach them from another host, behind a firewall. Redis runs with --appendfsync everysec and a password. Point the gateway at it:

OBLETH_DATABASE_URL=postgres://obleth:POSTGRES_PASSWORD@DB_HOST:5432/obleth
OBLETH_REDIS_URL=redis://:REDIS_PASSWORD@DB_HOST:6379
OBLETH_CLICKHOUSE_URL=http://DB_HOST:8123
OBLETH_CLICKHOUSE_USER=obleth
OBLETH_CLICKHOUSE_PASSWORD=CLICKHOUSE_PASSWORD
OBLETH_CLICKHOUSE_DB=obleth

Stop the stack

docker compose down
Compression sidecar build options

COMPRESSOR_CPUS (default 4) sets the container CPU quota and the onnxruntime thread count. The scoring model is chosen when the image is built: COMPRESSOR_SOURCE (onnx), COMPRESSOR_MODEL_ID (chopratejas/kompress-v2-base) and COMPRESSOR_ONNX_FILE (onnx/kompress-fp32.onnx). The gateway calls the sidecar only when OBLETH_COMPRESSOR_URL=http://compressor:8080 is set, and skips it when it does not answer.