Skip to content

Environment Variables

All backend configuration that must be known before Django starts (database, Redis, secrets, storage) is provided through environment variables. Everything else — site name, reminders, visibility rules, recording toggle, SSO — is configured at runtime from the admin interface, see Advanced Options.

Where to Set Them

Deployment Location
Debian packages /etc/hcw/backend.conf, loaded by systemd (EnvironmentFile=) for the hcw, hcw-celery and hcw-scheduler services
Docker Compose The environment: block of each service in docker-compose.yml
Development backend/.env, loaded automatically at startup. Copy backend/.env-dist to get started

The backend loads backend/.env if it exists, then falls back to the process environment. Variables set in the real environment always work, even without a .env file.

Restart required

Environment variables are read once at process startup. After any change, restart the API, the Celery worker and the scheduler — they each run in their own process and must share the same configuration.

Django Core

Variable Default Description
DJANGOSECRET_KEY (none) Required. Secret key used to sign sessions, tokens and password reset links. Generate one with echo -n "your secret phrase" \| sha256sum. Changing it invalidates all active sessions.
DEBUG False Set to the exact string True to enable debug mode. It also switches the cache from Redis to local memory and accepts every CORS origin. Never enable in production.
ALLOWED_HOST (none) Main hostname the backend is allowed to answer for.
ALLOWED_HOSTS (empty) Comma-separated list of additional hostnames, appended to ALLOWED_HOST. Use * to accept everything (development only).
CSRF_TRUSTED_ORIGINS (empty) Comma-separated list of origins including the scheme (e.g. https://admin.example.com). Required for the Django admin behind HTTPS.
CORS_ALLOWED_ORIGINS (empty) Comma-separated list of extra browser origins allowed to call the API. The Capacitor origins used by the mobile apps are always allowed.
DEFAULT_TIME_ZONE UTC Default timezone applied to new users, e.g. Europe/Zurich.
STATIC_ROOT statics Directory where collectstatic writes static files. The Debian package uses /usr/share/hcw/backend/statics/.
MEDIA_ROOT upload Directory where uploads are stored when S3 is not configured. Always use an absolute path: the API and the Celery worker are not started from the same working directory.

Maintenance Mode

Maintenance mode makes every HTTP request return a 503 without touching the database or Redis, which makes it usable even while the database is down.

Variable Default Description
MAINTENANCE False Set to True to enable maintenance mode.
MAINTENANCE_MESSAGE The service is temporarily unavailable for maintenance. Please try again later. Message returned to clients.
MAINTENANCE_RETRY_AFTER 300 Value of the Retry-After header, in seconds.

Database

PostgreSQL is mandatory: multi-tenancy relies on PostgreSQL schemas.

Variable Default Description
DATABASE_NAME (none) Database name.
DATABASE_USER (none) Database user. It must own the database to be able to create tenant schemas.
DATABASE_PASSWORD (none) User password.
DATABASE_HOST (none) Server hostname or IP address.
DATABASE_PORT (none) Server port, usually 5432.

Redis

Redis is used as the Celery broker, as the cache, and as the WebSocket channel layer.

Variable Default Description
REDIS_HOST 127.0.0.1 Redis hostname.
REDIS_PORT 6379 Redis port.

Email

Variable Default Description
EMAIL_HOST (none) SMTP server hostname.
EMAIL_PORT 25 SMTP port.
EMAIL_HOST_USER (none) SMTP username, if authentication is required.
EMAIL_HOST_PASSWORD (none) SMTP password.
EMAIL_USE_TLS (disabled) Enables STARTTLS, typically on port 587.
EMAIL_USE_SSL (disabled) Enables implicit TLS, typically on port 465. Mutually exclusive with EMAIL_USE_TLS.
DEFAULT_FROM_EMAIL (none) Sender address used for all outgoing emails.

TLS/SSL flags

EMAIL_USE_TLS and EMAIL_USE_SSL are enabled by any non-empty value, including False or 0. To disable them, leave the variable out of the configuration entirely.

Authentication

Variable Default Description
ACCESS_TOKEN_LIFETIME 3600 JWT access token lifetime in minutes (the default is therefore 60 hours). Lower it to 60 for a one-hour lifetime.
REFRESH_TOKEN_LIFETIME_DAYS 1 Refresh token lifetime in days. Refresh tokens are rotated on every use.

SSO and password login

OpenID Connect providers and the "SSO only" toggle are no longer configured through the environment. Set them from the admin interface, see Single Sign-On and Advanced Options.

File Storage (S3)

When S3 is configured, uploads (attachments, logos, recordings) are stored on an S3-compatible service instead of the local filesystem.

Variable Default Description
S3_BUCKET_NAME (none) Bucket name.
S3_ENDPOINT_URL (none) Service endpoint, e.g. https://s3.example.com for MinIO or Ceph.
S3_ACCESS_KEY (none) Access key.
S3_SECRET_KEY (none) Secret key.
S3_REGION us-east-1 Region.
S3_VERIFY (enabled) Set to the exact string false to skip TLS certificate verification (self-signed certificates).
S3_ADDRESSING_STYLE auto Addressing style: auto, path or virtual. MinIO and Ceph deployments whose bucket is not a DNS subdomain need path.

All or nothing

S3_BUCKET_NAME, S3_ENDPOINT_URL, S3_ACCESS_KEY and S3_SECRET_KEY must be set together. A partial configuration aborts startup with an ImproperlyConfigured error rather than silently falling back to local storage, which would make files written by one process unreadable by another.

Call Recording

Recordings are pushed to S3 by the media server. By default they reuse the S3_* settings above; set the LIVEKIT_S3_* variables only to store them on a different bucket or server.

Variable Default Description
LIVEKIT_S3_BUCKET_NAME value of S3_BUCKET_NAME Bucket dedicated to recordings.
LIVEKIT_S3_ENDPOINT_URL value of S3_ENDPOINT_URL Endpoint dedicated to recordings.
LIVEKIT_S3_ACCESS_KEY value of S3_ACCESS_KEY Access key.
LIVEKIT_S3_SECRET_KEY value of S3_SECRET_KEY Secret key.
LIVEKIT_S3_REGION value of S3_REGION Region.
RECORDING_CHECK_INITIAL_DELAY 120 Seconds to wait after the call ends before looking for the file on S3.
RECORDING_CHECK_MAX_RETRIES 4 Number of retries after the first check.
RECORDING_CHECK_RETRY_DELAY 30 Seconds between two retries.

Recording itself is enabled per tenant from the admin interface (ENABLE_VIDEO_RECORDING).

Media Servers

Variable Default Description
ROOM_SERVER_PIN_TTL 86400 How long, in seconds, the room-to-media-server mapping is kept in cache. Must outlast the longest possible call, including recording.

Media servers themselves are declared from the admin interface, see Media Servers.

Live Transcription

Variable Default Description
WHISPER_LIVE_URL ws://127.0.0.1:9090 WebSocket URL of the whisper-live server.
WHISPER_LIVE_API_KEY (empty) Must match the --api_key passed to the whisper-live server. Leave empty to disable authentication.

Transcription is enabled per tenant from the admin interface (ENABLE_LIVE_TRANSCRIPTION).

Push Notifications

Variable Default Description
WEBPUSH_VAPID_PUBLIC_KEY (none) VAPID public key for browser web push.
WEBPUSH_VAPID_PRIVATE_KEY (none) Matching VAPID private key.
WEBPUSH_VAPID_CLAIMS_EMAIL mailto:admin@hcw-at-home.com Contact address sent to the push service, in mailto: form.
GOOGLE_APPLICATION_CREDENTIALS (none) Path to the Firebase service account JSON file, read by the Firebase SDK. Required for native mobile app notifications (FCM).

Antivirus (ClamAV)

Uploads are scanned only when one of these variables is set. CLAMD_SOCKET takes precedence over the TCP variables.

Variable Default Description
CLAMD_SOCKET (none) Path to the clamd Unix socket, e.g. /var/run/clamav/clamd.ctl.
CLAMD_TCP_ADDR 127.0.0.1 clamd hostname, when connecting over TCP.
CLAMD_TCP_SOCKET 3310 clamd TCP port.

FHIR Server

Variable Default Description
FHIR_SYSTEM_SCHEME https Scheme used in derived Identifier.system URLs.
FHIR_SYSTEM_PATH (empty) Optional path appended after the tenant domain, e.g. /fhir. Must start with /.
FHIR_SYSTEM_BASE_URL (none) Forces a single canonical base URL for every tenant, bypassing per-tenant derivation.
FHIR_DEFAULT_COUNT 20 Default number of resources per Bundle page.
FHIR_MAX_COUNT 100 Upper bound for the _count search parameter.
FHIR_STRICT_SEARCH False Set to True to reject unknown search parameters instead of ignoring them.
FHIR_INCLUDE_NARRATIVE True Include the human-readable text narrative in returned resources.
FHIR_BUNDLE_TOTAL_MODE accurate accurate returns the exact total in Bundles, none omits it (cheaper on large datasets).

See FHIR R4 Integration for the full details of URL derivation.

Mobile Applications

Variable Default Description
MOBILE_ANDROID_PACKAGE com.healthcare.patient Android package name used to deep-link into the native app.
MOBILE_ANDROID_STORE_URL Google Play URL of the default package Store link offered when the app is not installed.
MOBILE_IOS_STORE_URL (empty) App Store link. Leave empty to hide the iOS banner.
IABSIS_PUBLIC_KEY_B64 (Iabsis key) Base64 Ed25519 public key used to verify the instance signature. Only change it if you sign your instances with your own key and ship a matching native app.

Each tenant can override the MOBILE_* values from the admin interface.

Frontend Containers

The patient, practitioner and admin images are Nginx containers that proxy /api and /ws to the backend.

Variable Applies to Description
BACKEND_URL patient, practitioner, admin Internal URL of the API, e.g. http://api:8000. Substituted into the Nginx configuration at container startup.
TAG docker compose Image tag to pull, e.g. TAG=0.10.0 docker compose pull. Defaults to latest.

Deprecated Variables

backend/.env-dist still lists a few variables that are no longer read by the code. They are kept only for backward compatibility with older configuration files and can be removed.

Variable Replacement
USERS_VISIBILITY USERS_VISIBILITY option in Advanced Options
OPENID_NAME, OPENID_CLIENT_ID, OPENID_SECRET, OPENID_CONFIGURATION_URL Single Sign-On configuration in the admin interface
DISABLE_PASSWORD_LOGIN DISABLE_PASSWORD_LOGIN option in Advanced Options
ENABLE_REGISTRATION ENABLE_REGISTRATION option in Advanced Options
ENCRYPTION_KEY No longer used. End-to-end encryption keys are managed per user, see End-to-End Encryption

Minimal Example

# Django
DJANGOSECRET_KEY=change-me
DEBUG=False
ALLOWED_HOST=hcw.example.com
ALLOWED_HOSTS=patient.example.com,admin.example.com
CSRF_TRUSTED_ORIGINS=https://admin.example.com
STATIC_ROOT=/usr/share/hcw/backend/statics/
MEDIA_ROOT=/var/lib/hcw/uploads
DEFAULT_TIME_ZONE=Europe/Zurich

# Database
DATABASE_NAME=hcw
DATABASE_USER=hcw
DATABASE_PASSWORD=change-me
DATABASE_HOST=127.0.0.1
DATABASE_PORT=5432

# Redis
REDIS_HOST=127.0.0.1
REDIS_PORT=6379

# Email
EMAIL_HOST=smtp.example.com
EMAIL_PORT=587
EMAIL_USE_TLS=1
EMAIL_HOST_USER=hcw@example.com
EMAIL_HOST_PASSWORD=change-me
DEFAULT_FROM_EMAIL=no-reply@example.com