Configuration
Runtime configuration for the gateway, UI, cache invalidation, plugins, and observability.
Configuration
Configuration is split between odock-server, odock-ui, Docker Compose, and the observability profile.
Gateway Configuration
odock-server loads .env best-effort and then reads environment variables. POSTGRES_DSN is required.
HTTP
| Variable | Default | Description |
|---|---|---|
HTTP_HOST | 0.0.0.0 | Bind host |
HTTP_PORT | 8080 | Bind port |
HTTP_READ_TIMEOUT | 15s | Request read timeout |
HTTP_WRITE_TIMEOUT | 60s | Response write timeout |
HTTP_IDLE_TIMEOUT | 60s | Keep-alive timeout |
HTTP_MAX_HEADER_BYTES | 1048576 | Maximum header size |
HTTP_ENABLE_TLS | false | Enable direct TLS |
HTTP_TLS_CERT_FILE | empty | Required when TLS is enabled |
HTTP_TLS_KEY_FILE | empty | Required when TLS is enabled |
HTTP_TRUST_PROXY_HEADERS | false | Respect forwarded client IP headers |
HTTP_TRUSTED_PROXY_CIDRS | empty | Trusted proxy CIDR or IP list |
HTTP_MAX_CONCURRENT_REQUESTS | 0 | Global in-process request cap; 0 disables |
Storage
| Variable | Default | Description |
|---|---|---|
POSTGRES_DSN | required | Postgres DSN used by the gateway |
POSTGRES_MAX_OPEN | 25 | Max open DB connections |
POSTGRES_MAX_IDLE | 5 | Max idle DB connections |
POSTGRES_MAX_LIFETIME | 30m | Connection lifetime |
POSTGRES_LOG_QUERIES | false | Query logging flag |
REDIS_ADDR | localhost:6379 | Redis address |
REDIS_USERNAME | empty | Redis username |
REDIS_PASSWORD | empty | Redis password |
REDIS_DB | 0 | Redis DB |
REDIS_POOL_SIZE | 20 | Redis pool size |
REDIS_DIAL_TIMEOUT | 5s | Redis dial timeout |
Provider Defaults
Provider defaults are used when a request does not receive provider settings from the model database row.
| Provider | Base URL variable | API key variable | Timeout variable |
|---|---|---|---|
| OpenAI | PROVIDER_OPENAI_BASE_URL | PROVIDER_OPENAI_API_KEY or OPENAI_API_KEY | PROVIDER_OPENAI_TIMEOUT |
| Anthropic | PROVIDER_ANTHROPIC_BASE_URL | PROVIDER_ANTHROPIC_API_KEY or ANTHROPIC_API_KEY | PROVIDER_ANTHROPIC_TIMEOUT |
| Gemini | PROVIDER_GEMINI_BASE_URL | PROVIDER_GEMINI_API_KEY or GEMINI_API_KEY | PROVIDER_GEMINI_TIMEOUT |
| vLLM | PROVIDER_VLLM_BASE_URL | PROVIDER_VLLM_API_KEY | PROVIDER_VLLM_TIMEOUT |
In normal UI-managed operation, provider base URLs and encrypted provider keys come from the configured Provider, ProviderApiKey, and Model rows.
Observability
| Variable | Default | Description |
|---|---|---|
OBSERVABILITY_PROMETHEUS_ENABLED | true | Expose /metrics |
OBSERVABILITY_OTEL_EXPORTER | otlphttp | Shared exporter fallback |
OBSERVABILITY_OTEL_TRACES_EXPORTER | fallback | Trace exporter |
OBSERVABILITY_OTEL_METRICS_EXPORTER | fallback | Metric exporter |
OBSERVABILITY_OTEL_ENDPOINT | http://localhost:4318 | Shared OTLP endpoint |
OBSERVABILITY_OTEL_TRACES_ENDPOINT | empty | Trace endpoint override |
OBSERVABILITY_OTEL_METRICS_ENDPOINT | empty | Metric endpoint override |
OBSERVABILITY_SERVICE_NAME | gateway-service | Service name |
OBSERVABILITY_SERVICE_NAMESPACE | odock | Service namespace |
OBSERVABILITY_SERVICE_VERSION | dev | Service version |
OBSERVABILITY_DEPLOYMENT_ENVIRONMENT | development | Environment |
OBSERVABILITY_SAMPLE_RATE | 0.1 | Trace sampling rate, between 0 and 1 |
Governance Runtime
| Variable | Default | Description |
|---|---|---|
AUTH_CACHE_TTL | 5m | Positive API key cache TTL |
AUTH_NEGATIVE_CACHE_TTL | 30s | Negative auth cache TTL |
RATELIMIT_GLOBAL_POLICY | empty | JSON policy applied globally |
RATELIMIT_POLICY_CACHE_TTL | 5m | Policy cache TTL |
MODEL_CACHE_TTL | 5m | Model metadata and access cache TTL |
MCP_CACHE_TTL | 5m | MCP server cache TTL |
SMART_ROUTING_POLICY_CACHE_TTL | 5m | Smart routing policy cache TTL |
SAFETY_ENGINE_MODE | noop | Use security to enable SafetySec |
SAFETY_SESSION_TTL | 24h | SafetySec Redis session TTL |
SAFETY_BLOCK_THRESHOLD | 0.85 | Accumulated safety score block threshold |
Provider Key Decryption
| Variable | Description |
|---|---|
PROVIDER_KEY_ENCRYPTION_KEY_ID | Expected key ID for encrypted provider-key envelopes |
PROVIDER_KEY_ENCRYPTION_PRIVATE_KEY | RSA private key PEM, often with literal \n escapes |
PROVIDER_KEY_DECRYPT_CACHE_TTL | In-process plaintext decrypt cache TTL |
PROVIDER_KEY_ENCRYPTION_KEY_ID and PROVIDER_KEY_ENCRYPTION_PRIVATE_KEY must be configured together.
Cache Invalidation
| Variable | Default | Description |
|---|---|---|
CACHE_INVALIDATION_SECRET | empty | Enables /v1/internal/cache/invalidate when set |
CACHE_INVALIDATION_CHANNEL | odock:cache-invalidation | Redis pub/sub channel |
When the UI mutates API keys, model access, models, providers, organisations, teams, or MCP servers, it sends invalidation commands to the gateway if both ODOCK_SERVER_INTERNAL_URL and CACHE_INVALIDATION_SECRET are configured in odock-ui.
UI Configuration
The UI is a Next.js application using Better Auth and Prisma.
Important variables:
| Variable | Description |
|---|---|
DATABASE_URL | Postgres DSN for Prisma |
BETTER_AUTH_SECRET | Better Auth secret |
BETTER_AUTH_URL or NEXT_PUBLIC_APP_URL | Public auth base URL |
GITHUB_CLIENT_ID | GitHub OAuth client ID |
GITHUB_CLIENT_SECRET | GitHub OAuth client secret |
NEXT_PUBLIC_APP_URL | Public UI URL |
NEXT_PUBLIC_PROVIDER_KEY_ENCRYPTION_KEY_ID | Browser-side key ID |
NEXT_PUBLIC_PROVIDER_KEY_ENCRYPTION_PUBLIC_KEY | RSA public key used by browser encryption |
ODOCK_SERVER_INTERNAL_URL | Internal URL for gateway cache invalidation |
CACHE_INVALIDATION_SECRET | Must match the gateway secret |
RBAC_AUDIT_LOG | Enables RBAC audit logging when set by implementation |
RESEND_API_KEY | Invitation email provider key when email sending is enabled |
INVITATION_EMAIL_FROM | Invitation email sender |
Provider-key encryption values prefixed with NEXT_PUBLIC_ are compiled into the browser bundle. Provide them at build time.
Plugin Configuration
The gateway loads plugin configuration from PLUGINS_CONFIG_PATH, defaulting to ./configs/plugins.json.
Runtime tuning:
| Variable | Default | Description |
|---|---|---|
PLUGINS_CONFIG_PATH | ./configs/plugins.json | Config JSON path |
PLUGINS_MAX_PARALLEL | 4 | Max parallel plugin workers per phase |
PLUGINS_ASYNC_POST_RESPONSE | false | Enable async post-response plugins |
PLUGINS_ASYNC_QUEUE_SIZE | 128 | Async plugin queue size |
PLUGINS_ASYNC_WORKERS | 2 | Async plugin workers |
PLUGINS_ENV_* | empty | Extra env values available to plugin factories |
Config shape:
{
"plugins": [
{
"name": "audit_log",
"enabled": true,
"storage_access": ["usage", "api_keys"],
"config": { "level": "info" }
}
],
"phases": {
"pre_route": { "sequential": [], "parallel": ["audit_log"] },
"pre_upstream": { "sequential": [], "parallel": [] },
"post_upstream": { "sequential": [], "parallel": [] },
"post_response": { "sequential": ["audit_log"], "parallel": [], "async": true }
}
}Policy JSON Shape
Policy JSON stored on organisations, teams, API keys, models, and MCP servers uses this envelope:
{
"policies": {
"ip": {
"allowlist": ["10.0.0.0/8"],
"blocklist": []
},
"ratelimit": {
"requests": {
"per_second": 20,
"per_minute": 1200,
"burst": 50
},
"tokens": {
"per_minute": 120000
},
"concurrency": {
"max": 40,
"lease_ttl_seconds": 30
},
"payload": {
"max_request_bytes": 2097152,
"max_tokens": 8192
}
}
}
}The implementation currently validates non-negative values. lease_ttl_seconds is accepted in schema/config shape, but the active Redis leaser uses the gateway's stage defaults.