Self-Hosting
Environment Variables
Every variable referenced by docker-compose.traefik.yml, documented.
This page is the authoritative reference for every variable consumed by docker-compose.traefik.yml. Copy .env.example to .env.production and fill in the required rows.
| Variable | Required | Example | Used by |
|---|
DOMAIN_API | Yes | api-id.your-company.com | gateway, Oathkeeper, Hydra |
DOMAIN_WEB | Yes | id.your-company.com | web dashboard, Universal Login |
DOMAIN_DOCS | Yes | docs-id.your-company.com | merged docs app (public + /internal) |
DOMAIN_POLIS | Yes | sso-id.your-company.com | Polis SCIM service |
DOMAIN_SAML | Yes | saml-id.your-company.com | SAML IdP endpoints |
DOMAIN_GRAFANA | Yes | grafana-id.your-company.com | Observability dashboards |
DOMAIN_MINIO | Yes | minio-id.your-company.com | S3-compatible object storage console |
DOMAIN_DOCS_INTERNAL | No | docs-internal-id.your-company.com | Legacy host -- Traefik 302s to $DOMAIN_DOCS/internal |
All five are required. Rotate with make db-rotate-passwords (zero-downtime, writes new secret then re-configures pgbouncer).
| Variable | Consumed by |
|---|
POSTGRES_PASSWORD | Postgres superuser |
POSTGRES_KRATOS_PASSWORD | Kratos DB user |
POSTGRES_HYDRA_PASSWORD | Hydra DB user |
POSTGRES_KETO_PASSWORD | Keto DB user |
POSTGRES_POLIS_PASSWORD | Polis DB user |
64-character random hex strings. Generate with openssl rand -hex 32.
| Variable | Consumed by | Rotation procedure |
|---|
HYDRA_SYSTEM_SECRET | Hydra (session + cookie encryption) | Upgrade guide |
KRATOS_COOKIE_SECRET | Kratos session cookie | Rotate yearly; supports two-value blue/green |
KRATOS_CIPHER_SECRET | Kratos field-level encryption | Rotate only during a maintenance window |
| Variable | Required | Notes |
|---|
POLIS_API_KEY | Yes | Admin API key the gateway uses to call Polis |
POLIS_NEXTAUTH_SECRET | Yes | NextAuth session encryption |
POLIS_WEBHOOK_SECRET | Yes | HMAC secret for Polis -> gateway webhooks |
POLIS_SCIM_WEBHOOK_SECRET | Yes | HMAC secret for SCIM provisioning events |
POLIS_CLIENT_SECRET_VERIFIER | Yes | Shared with Hydra for verifier flow |
POLIS_OPENID_CLIENT_SECRET | Yes | Hydra client secret for Polis' own OIDC integration |
POLIS_OPENID_RSA_PRIVATE_KEY | Yes | PEM-encoded RSA key (2048 bit min) for signing |
POLIS_CLIENT_ID | Yes | Hydra client ID for Polis |
POLIS_CLIENT_SECRET | Yes | Matching Hydra client secret |
| Variable | Required | Default |
|---|
VALKEY_PASSWORD | Yes | -- |
MINIO_ROOT_USER | Yes | -- |
MINIO_ROOT_PASSWORD | Yes | 12+ chars |
GRAFANA_ADMIN_PASSWORD | Yes | -- |
Configure exactly one provider. Omit all to disable SMS flows.
| Variable | Provider |
|---|
TWILIO_ACCOUNT_SID + TWILIO_AUTH_TOKEN + TWILIO_FROM_NUMBER | Twilio |
VONAGE_API_KEY + VONAGE_API_SECRET + VONAGE_FROM_NUMBER | Vonage |
MESSAGEBIRD_ACCESS_KEY + MESSAGEBIRD_ORIGINATOR | MessageBird |
AWS_SNS_ACCESS_KEY_ID + AWS_SNS_SECRET_ACCESS_KEY + AWS_SNS_REGION | AWS SNS |
Each provider is opt-in. Create OAuth apps with the provider, then set:
| Provider | Variables |
|---|
| Google | GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET |
| GitHub | GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET |
| Microsoft | MICROSOFT_CLIENT_ID, MICROSOFT_CLIENT_SECRET |
| Facebook | FACEBOOK_CLIENT_ID, FACEBOOK_CLIENT_SECRET |
| Variable | Provider |
|---|
HCAPTCHA_SITE_KEY + HCAPTCHA_SECRET_KEY | hCaptcha |
TURNSTILE_SITE_KEY + TURNSTILE_SECRET_KEY | Cloudflare Turnstile |
CAPTCHA_ENABLED_ROUTES | Comma-separated route prefixes to guard |
| Variable | Default | Purpose |
|---|
OTEL_EXPORTER_OTLP_ENDPOINT | -- | OTLP collector URL (traces + metrics) |
OTEL_SERVICE_NAMESPACE | avnology | Service namespace label |
LOG_LEVEL | info | debug / info / warn / error |