Skip to content

Configuration

Every environment variable the system reads, where it comes from, and where the example files lie.

How configuration is loaded

Environment Source
Local backend/.env, frontend/.env, read by python-decouple and Vite
Staging Environment variables on the compose services
Production Docker Swarm secrets named TWTLNKPROD_*, exported by backend/entrypoint.sh:30-98 only when the variable is not already set

The TWTLNKPROD_* list in entrypoint.sh is the authoritative inventory of production keys. When you add a setting, add it there too or production will silently fall back to the config() default.

Backend

Django core

Variable Purpose
DEBUG Never true outside local development
SECRET_KEY Django signing key
TIME_ZONE Server timezone
ALLOWED_HOSTS Comma-separated hostnames
CSRF_TRUSTED_ORIGINS Origins allowed to post to the admin

Database

DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, DB_PORT.

Use 5433 locally to match backend/docker-compose-dev.yml.

Object storage (MinIO / S3)

S3_ENDPOINT, S3_ACCESS_KEY, S3_SECRET_KEY, S3_BUCKET, S3_USE_HTTPS.

Recordings, voice messages and uploads live here; the API serves them as presigned URLs.

Twilio

Variable Purpose
TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN Account credentials; the auth token also verifies webhook signatures
TWILIO_API_KEY, TWILIO_API_SECRET Used to mint Voice SDK access tokens
TWILIO_TWIML_APP_SID The TwiML application backing outbound client calls
TWILIO_CLIENT_TOKEN_TIME Access token lifetime
TWILIO_WEB_HOOK_DOMAIN Public domain Twilio calls back into. Changing it means re-running backend/tools/set_webhooks.py
TWILIO_FCM_TOKEN, TWILIO_APN_TOKEN Push credentials for Voice SDK notifications
TWILIO_CALL_QUEUE_NAME, TWILIO_CALL_QUEUE_SID The hold queue
TWILIO_CONF_WAIT_URL Hold music or message for conferences

Real-time (inert)

WEBSOCKET_DOMAIN, CHANNELS_BACKEND (redis or rabbit), CHANNELS_REDIS_HOST, CHANNELS_REDIS_PORT, CHANNELS_RABBIT, HEARTBEAT_TIMEOUT.

These configure Django Channels, which has no consumers registered. Only HEARTBEAT_TIMEOUT affects behaviour. See Known issues.

The three compose files disagree on the broker — production runs RabbitMQ, staging runs Redis, development runs RabbitMQ — and nothing depends on the answer today.

Stripe

STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, six PRODUCT_PRICE_ID_* entries and five STRIPE_EVENT_* entries.

Email

EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD, DEFAULT_FROM_EMAIL, USER_RESET_PASS_TOKEN_TIME.

Integrations and operations

Variable Purpose
PUSH_NOTIFICATIONS_CREDENTIAL Path to the Firebase service-account JSON (backend/settings/firebase/__init__.py:9)
AUDIO_TRANSCRIPTION_SERVICE Whisper endpoint used for CallTranscription
FRONTEND_LINK Base URL used in emails and redirects
GRAYLOG_ENDPOINT Log shipping target
LOG_LEVEL, LOG_LEVEL_DJANGO, LOG_OUT, LOG_OUT_CONSOLE_TYPE Logging configuration
CELERY_BROKER Loaded by entrypoint.sh:89 and read by nothing

backend/.env.example has drifted

It carries a stale STRIPE_KEY that nothing reads, and it is missing CELERY_BROKER, S3_USE_HTTPS, TWILIO_CONF_WAIT_URL, TWILIO_CALL_QUEUE_NAME, TWILIO_CALL_QUEUE_SID, CHANNELS_RABBIT and the four LOG_* variables. Copying it verbatim produces a backend that starts and then fails at runtime. Cross-check against backend/settings/settings.py and backend/entrypoint.sh.

Frontend

Only these are actually read by frontend/src/:

Variable Purpose
VITE_API_URL REST base URL, including /api/v1
PUBLIC_FIREBASE_API_KEY and the other PUBLIC_FIREBASE_* keys Firebase app configuration, read through $env/static/public (src/lib/actions/firebase/FirebaseApp.ts:9-27)
VITE_DEV Development-only behaviour
VITE_TWILIO_ERROR_RELOAD_DISABLED Stops the softphone from re-initialising five seconds after a device error (TwilioClientWeb.ts:105-113)

frontend/.env.example is wrong in two ways

  1. It names the Firebase keys VITE_FIREBASE_*; the code reads PUBLIC_FIREBASE_*. With the default SvelteKit prefix, the file as written does not work.
  2. It lists VITE_TWILIO_URL and VITE_WSAPI_URL, neither of which appears anywhere in src/.

Treat the working set above as the real contract until the example file is fixed.

In CI the console's environment used to be injected from the FRONTEND_ENV and STAGING_FRONTEND_ENV repository secrets. Those workflows were deleted, so the secrets are currently unused — see Deployment.

Repository root .env

Contains only MANAGE_PY_PATH, an absolute path to backend/manage.py on one developer's machine, used by the VS Code launch configuration. It is not application configuration, and the path it holds is valid on exactly one machine.