# Production checklist

> What to verify before pointing real traffic at a deployment.

URL: https://boelabs.com/en/docs/ai-gateway/production-checklist
Language: English

A condensed checklist. Each item links to the page with the full explanation.

## Secrets

- [ ] `MASTER_KEY` and every `ENCRYPTION_KEYRING` value are strong, unique per environment, and live in a
  secret manager — not in the image, not in git, not in the Compose file's defaults.
  `docker/compose.local.yaml`'s secrets are development-only; the production `docker/compose.yaml` base ships
  both empty and refuses to start until you set them. See [Security](https://boelabs.com/docs/ai-gateway/security).
- [ ] You have a rotation plan for both, and know the leaked-secret procedure —
  [Operations → Secrets](https://boelabs.com/docs/ai-gateway/operations#secrets).

## Network and TLS

- [ ] Postgres and Redis connections use a public-CA certificate, or a private network without TLS.
  **Bun's TLS implementation rejects self-signed certificates** — a raw Coolify/Dokploy-exposed port
  commonly hits this. See [Known errors](https://boelabs.com/docs/ai-gateway/troubleshooting#bun-may-fail-to-connect-to-postgresredis-over-self-signed-tls).
- [ ] Only the gateway (and optionally the dashboard) is exposed through your reverse proxy; Postgres
  and Redis stay on the internal network. See [Deployment](https://boelabs.com/docs/ai-gateway/deployment).

## Health and scaling

- [ ] Liveness probe → `GET /health/live` (no dependency checks — never point liveness at a
  dependency-aware endpoint, or a Postgres/Redis blip restarts every replica at once).
- [ ] Readiness probe → `GET /health/ready` (pulls an unhealthy instance from the load balancer without
  restarting it).
- [ ] Your orchestrator gives the container more than `DRAIN_DELAY_MS + SHUTDOWN_TIMEOUT_MS` before
  `SIGKILL` (`stop_grace_period` in Compose, **Stop Grace Period** in Coolify). Docker's default is
  10 seconds, which is shorter than the drain — the process is killed mid-sequence and every
  in-flight stream dies with it. See [Rollouts](https://boelabs.com/docs/ai-gateway/rollouts).
- [ ] The proxy in front of the gateway polls `/health/ready` and acts on it. Without that, the
  drain delay announces a departure nothing is listening for.
- [ ] Replicas are safe to scale horizontally; shared quotas/circuits are in Redis and maintenance work
  is idempotent or transactionally claimed. See [Operations](https://boelabs.com/docs/ai-gateway/operations).

## Data lifecycle

- [ ] Migrations are applied at boot (`MIGRATE_ON_BOOT`, the default), or you run them as your own
  step — and either way every migration works against the version it replaces, because a rollout has
  both live at once. See [Rollouts](https://boelabs.com/docs/ai-gateway/rollouts).
- [ ] `OBSERVABILITY_METADATA_RETENTION_DAYS`, `OBSERVABILITY_PAYLOAD_RETENTION_DAYS`, and
  `RESPONSES_STATE_RETENTION_DAYS` match your actual compliance/storage requirements. Every finished
  request keeps one encrypted payload sample, so the payload window is both the disk bill and the
  exposure window.
- [ ] `OBSERVABILITY_PAYLOAD_ACCESS` is a decision, not a default: `sealed` keeps capturing samples
  and lets nobody read them, which is what a deployment handling regulated content wants.
- [ ] You have a Postgres backup schedule. Redis needs none (fully rebuildable ephemeral state). See
  [Operations → Backups](https://boelabs.com/docs/ai-gateway/operations#backups).

## Observability

- [ ] `OTEL_ENABLED=true` with a real `OTEL_EXPORTER_OTLP_ENDPOINT` if you want traces/metrics —
  disabled by default.
- [ ] The encryption keyring is backed up and its rotation procedure is rehearsed; the gateway never
  emits payload bodies to OTel. See [Security](https://boelabs.com/docs/ai-gateway/security#observability-payloads).
- [ ] Logs (structured JSON on stdout) are shipped to a collector.

## Routing and resilience

- [ ] `PUT /admin/router-settings` reflects real choices, not silent defaults — especially
  `unsupportedParameterStrategy` (default `drop`, which silently strips parameters; `error` may be safer
  for a strict client). See [Routing](https://boelabs.com/docs/ai-gateway/routing) and [Parameter policy](https://boelabs.com/docs/ai-gateway/parameter-policy).
- [ ] Every Public Model you rely on has more than one deployment, or an explicit acceptance that it
  has none. See [Fallbacks](https://boelabs.com/docs/ai-gateway/fallbacks) for pool-exhaustion behavior.

## Dependencies

- [ ] `bun audit --production` is clean (CI enforces this at `--audit-level=high`, but re-check after
  adding any runtime extension dependency).

## Next steps

- [Upgrades](https://boelabs.com/docs/ai-gateway/upgrades) — what changes between releases and how to roll one out safely.
- [Operations](https://boelabs.com/docs/ai-gateway/operations) — the full runbook behind this checklist.

