Setup
Configure the gateway: requirements, environment, secrets, and choosing a database and Redis.
Everything the gateway needs before you deploy. To just see it running, the Quickstart is faster; come here to configure a real environment, then pick a target under Deployment.
Requirements
- Bun 1.3+ — the gateway runtime (runs TypeScript directly; no build step) and the package manager / task runner.
- Postgres 18+
- Redis 8+
Unified Gateway runs on Bun, not Node. If you plan to reach a database or Redis over TLS with a self-signed certificate, read Known errors first — Bun's TLS may not accept those, and the fix is a configuration choice you make here.
Environment
Create apps/gateway/.env (copy apps/gateway/.env.example). The minimum:
PORT=4000
NODE_ENV=production
MASTER_KEY=replace-with-a-long-secret
CREDENTIALS_ENCRYPTION_KEY=64_hex_chars_32_bytes
DATABASE_URL=postgres://user:pass@host:5432/unifiedgateway
REDIS_URL=redis://host:6379Everything else ships with production-ready defaults — override only what you need. The most common:
| Variable | Default | Purpose |
|---|---|---|
MAX_STRING_LENGTH_PROMPT_IN_DB | 8000 | Prompt/response truncation in request_logs. |
SHUTDOWN_TIMEOUT_MS | 10000 | Drain budget on SIGTERM/SIGINT. |
REQUEST_LOG_PARTITION_CREATE_DAYS | 7 | Future daily request_logs partitions kept ahead. |
REQUEST_LOG_PARTITION_RETENTION_DAYS | 30 | Daily partitions retained before being dropped. |
OTEL_ENABLED | false | Set with OTEL_EXPORTER_OTLP_ENDPOINT to export traces/metrics. |
UNIFIED_GATEWAY_EXTENSIONS_MANIFEST | — | Path to a mounted extensions manifest. |
Secrets
Two secrets are critical. Store them in your secret manager — never in git or the image:
| Secret | Purpose | Format |
|---|---|---|
MASTER_KEY | Operator credential; full access to /admin/*. | Strong random string (≥ 8 chars; longer is better). |
CREDENTIALS_ENCRYPTION_KEY | Encrypts provider credentials at rest (AES-256-GCM). | 32 bytes in hex (64 chars). |
openssl rand -base64 48 # MASTER_KEY
openssl rand -hex 32 # CREDENTIALS_ENCRYPTION_KEYRotation procedures live in Operations → Secrets.
Database and Redis
The gateway needs a Postgres 18+ database and a Redis 8+ instance. How you connect matters because of the Bun TLS constraint:
- Self-hosted on the same private network (Compose / Coolify / Portainer / Dokploy): connect over
plaintext —
postgres://…andredis://…. Safe by network isolation, and it sidesteps the self-signed TLS issue. This is the default in every Deployment recipe. - Managed provider (recommended for development, or when the database lives off-network): pick one that presents a public-CA certificate, which Bun connects to cleanly.
Managed database and Redis
Good free-tier options that work with Bun's TLS out of the box:
| Service | Type | Notes |
|---|---|---|
| Neon | Postgres | Serverless, generous free tier, public-CA TLS, connect by hostname. |
| Supabase | Postgres | Free tier; use the connection string or the pooler. |
| Aiven | Postgres / Redis | Free tier; public-CA TLS. |
| Upstash | Redis | Free tier; rediss:// over public-CA TLS. |
Avoid pointing the gateway at a self-signed database over a public port (the default for a raw Coolify/Dokploy database exposed publicly) — see Known errors.