Production checklist
What to set and verify before a gateway takes real traffic.
4 min readUpdated for v2.4.0Edit on GitHub
Applies toHelm installs; Compose notes where they differ
Start from
examples/values-production.yaml in the chartThenRun
obench score against stagingWork through each list in order. Every item links to the page that explains it.
Secrets
- Point the chart at pre-created Secrets with
obleth.existingSecretandcontrolPlane.existingSecret, so credentials never enter a values file or your shell history. With either set, the chart renders no Secret of its own, so yours must carry every key in the tables below. - Generate
OBLETH_ADMIN_TOKENwithopenssl rand -hex 32. There is no default; the gateway will not start without it. - Set
OBLETH_ENCRYPTION_KEY(openssl rand -base64 32). Without it, upstream API keys, MCP auth headers and upstream header values are stored in plaintext. Keep a copy: restoring a backup needs the same key. - Set
OBLETH_API_KEY_PEPPER(openssl rand -hex 32) and never change it. Changing it invalidates every issued key. - Keep the real
.envout of version control (Compose).
The gateway Secret (obleth.existingSecret):
| Key | When |
|---|---|
OBLETH_ADMIN_TOKEN | Always |
OBLETH_DATABASE_URL | Always |
OBLETH_REDIS_URL | Always. It carries the Redis password: redis://:<password>@<host>:6379 |
OBLETH_CLICKHOUSE_PASSWORD | clickhouse.enabled: true (its container reads it), or an external ClickHouse with a password |
OBLETH_ENCRYPTION_KEY, OBLETH_API_KEY_PEPPER | Recommended |
OBLETH_SLACK_WEBHOOK_URL, OBLETH_JWT_ISSUERS | Optional |
REDIS_PASSWORD | redis.enabled: true. The same password as in OBLETH_REDIS_URL |
POSTGRES_PASSWORD | postgres.enabled: true |
The dashboard Secret (controlPlane.existingSecret):
| Key | Notes |
|---|---|
DASHBOARD_ADMIN_EMAIL, DASHBOARD_PASSWORD | The break-glass admin; the password needs at least 8 characters |
DASHBOARD_SESSION_SECRET | At least 32 characters; the dashboard refuses to start otherwise |
DATABASE_URL | The same Postgres database the gateway uses |
BETTER_AUTH_URL | The dashboard's external URL |
TRUSTED_ORIGINS, OIDC_PROVIDERS | Optional: extra login origins, and SSO providers |
The keys are also listed in Helm values. Upgrading an existing existingSecret install to v2.0.0 has its own steps: see Upgrading from v1.x.
Datastores
- Redis has a password:
redis.passwordin Helm,REDIS_PASSWORDin Compose. Use URL-safe characters; a hex value is simplest. - For high availability, run Postgres and ClickHouse outside the chart (for example CloudNativePG and a replicated or managed ClickHouse), and a Redis that presents one primary at a stable address. Redis Cluster is not supported.
- Bundled datastores keep
persistence.enabled: true. With it off, data lives in anemptyDirand is lost when the pod restarts. - If you enforce term budgets, keep Redis persistence (AOF) on so a restart does not reset them.
- Give the telemetry spill file a writable path with room for a ClickHouse outage. The chart mounts one at
/var/lib/obleth; see Reliability.
Replicas and fairshare
- Run more than one gateway replica for redundancy (
values-production.yamlruns three), spread across nodes withaffinity.antiAffinity. The PodDisruptionBudget renders only when more than one replica is guaranteed. - Leave
OBLETH_FAIRSHARE_SHARED_SLOTSandOBLETH_FAIRSHARE_REPLICA_AWAREon (the defaults), so pool sizes and tenant and key caps hold across the replicas as shared slots in Redis. Size them as fleet-wide numbers, not per replica. See Scaling. - Set
max_in_flighton every model to what its backend can serve at once, or use thediscoveredcapacity mode. A model without one getsOBLETH_DEFAULT_MODEL_MAX_IN_FLIGHT(32). - Keep
OBLETH_GLOBAL_MAX_IN_FLIGHT(default 4096) above the sum of the pool sizes. The gateway logs a warning at start-up when it is lower. - Clients retry on
503withRetry-After, which a request gets after waitingOBLETH_ADMISSION_TIMEOUT_SECS(60) in the queue.
Network
- Terminate TLS at your ingress or HAProxy. The gateway serves plain HTTP.
- Expose only the data plane (
8080) and the dashboard. Keep the Management API (9180) and metrics (9091) on the internal network. - Turn on
networkPolicy.enabledif your CNI enforces NetworkPolicy. It limits the bundled datastores to the pods that use them and the Management API port to the dashboard and provisioner. - In Compose, the data plane (
8088), dashboard (3002) and edge proxy (80) listen on all interfaces; put a firewall or TLS proxy in front. ChangeHAPROXY_STATS_USERandHAPROXY_STATS_PASSWORDfromadminif you run theedgeprofile.
More in Security.
Backups
- Back up Postgres with point-in-time recovery; it holds every setting, key and tenant.
- Back up ClickHouse if you need usage history.
- Download a config backup from Settings › Data and backups and store it like a credential.
- Test a restore on a staging install. See Backup and restore.
Alerts and metrics
- Add a Slack webhook or an email server in Settings › Alerts, and send a test alert. See Alerting.
- Scrape
:9091/metrics(serviceMonitor.enabled: truewith the Prometheus Operator). - Alert on any increase of
obleth_telemetry_dropped, onobleth_fairshare_shared_slots_mode{mode="fallback"} == 1, and on a rise inobleth_requests_total{status="5xx"}. See Observability.
Upgrades and shutdown
- Upgrade with
--reset-then-reuse-valuesso your overrides carry forward. See Upgrades. - If you raise
OBLETH_SHUTDOWN_GRACE_SECS, raise the pod'sterminationGracePeriodSeconds(345) or Compose'sstop_grace_periodby the same amount. See Shutdown and timeouts.
Before go-live
- Create fairshare groups and tenants, register models, and mint one key per client. A fresh install has no models.
- If Claude Code or Anthropic SDKs will connect, set Default model for Anthropic clients in Settings › Routing.
- Run
obench scoreagainst staging and keep the scorecard as a baseline. See Benchmarks and chaos testing. - Send a few requests and confirm they appear in Request logs.
