Configuration
Environment variables and service configuration
All configuration lives in a single .env file next to the
docker-compose.yml. Copy the example and fill the fields that matter for
your deployment:
cp .env.example .envThe reference .env.example is published in the public quickstart repository
alongside the compose file.
Sections
The file is grouped by service. Each service reads only its own prefix — e.g.
everything the asp-net backend needs is BACKEND_*, everything the python
worker needs is WORKER_*, etc. Shared values (Postgres host, Kafka brokers,
Redis password) are defined once in the base sections at the top of the
file and referenced via ${VAR} interpolation from the service sections
below.
| Section | Prefix | What it controls |
|---|---|---|
| Host ports | *_EXTERNAL_PORT | Which host ports docker exposes the services on. Change if they clash locally. |
| Service URLs | *_INTERNAL_URL, *_PUBLIC_URL | Internal DNS names (used between containers) vs browser-facing URLs. |
| Postgres | POSTGRES_* | Database credentials. One Postgres instance hosts multiple DBs. |
| Redis | REDIS_* | Shared password. Services use different logical DB numbers. |
| Kafka | KAFKA_* | SASL creds + bootstrap servers. |
| MinIO | MINIO_* | S3-compatible object storage for recordings and invoices. |
| Keycloak | KEYCLOAK_* | Admin user, SMTP, OAuth, email verification. |
| LiveKit | LIVEKIT_* | API keys, SIP trunk, WebRTC NAT config. |
| Backend | BACKEND_* | .NET API settings, LLM keys, Stripe plan codes. |
| Worker | WORKER_* | Python voice agent — LLM/STT/TTS provider keys. |
| Frontend | FRONTEND_CLIENT_*, FRONTEND_WIDGET_* | Runtime config injected into the Angular bundles. |
| Lago | GETLAGO_* | Billing engine: DB, Redis, Stripe, webhook URL. |
| Webhooks | WEBHOOKS_* | Inbound webhook receiver (Lago, LiveKit callbacks). |
| Logging (opt-in) | LOGGING_* | Fluent Bit / Benthos / Elasticsearch credentials. |
Critical settings
A handful of values must be set before first boot — defaults won't work:
| Variable | Why |
|---|---|
| API keys for the LLM / STT / TTS providers you enable | Model access for agents (vendor-specific var names — see .env.example) |
GETLAGO_MIGRATE_STRIPE_SECRET_KEY | Billing (only if Stripe enabled) |
KEYCLOAK_SMTP_* | Email delivery for signup / password reset |
LIVEKIT_API_KEY / LIVEKIT_API_SECRET | WebRTC signing — generate random 32-char secrets |
GETLAGO_RSA_PRIVATE_KEY | Base64-encoded RSA key for Lago webhook signatures |
Encryption keys (*_ENCRYPTION_*, SECRET_KEY_BASE) | Rotate from defaults to random strings in prod |
The .env.example ships with working placeholders for local dev, but every
secret must be replaced for a production deployment.
Profiles
Some services are opt-in and don't start unless you enable a profile:
# Logging stack (Elasticsearch + Kibana + Fluent Bit + Benthos)
docker compose --profile logging up -d
# Analytics (ClickHouse)
docker compose --profile analytics up -dScaling individual services
To run more than one instance of a session-bound service (worker, livekit, bridge), either use Docker Swarm replicas or replace the Compose stack with a real orchestrator (Kubernetes, Nomad, ECS). All services are stateless except the backbone (Postgres, Redis, Kafka, MinIO, Keycloak).
See Requirements for how to size each service against your expected concurrent session load.