Environment Variables
This page centralizes the environment variables used by Docker Compose, the Django backend, Celery, the face-service, and Docker image builds.
The project-root .env file has two roles:
- Docker Compose uses it to expand
${...}indocker-compose.ymlanddocker-compose.prod.yml. - Backend, Celery, and the development frontend containers read runtime variables through
env_file: .env.
WARNING
Do not commit a real .env file. Use strong random values for production passwords, keys, object-storage credentials, WeChat secrets, and SM2 private keys. Prefer a secrets manager where available.
Minimum Configuration
Development needs at least:
POSTGRES_PASSWORD=password
DJANGO_DEBUG=true
SM2_PUBLIC_KEY=your_sm2_public_key
SM2_PRIVATE_KEY=your_sm2_private_keyProduction needs at least:
POSTGRES_DB=myucspace
POSTGRES_USER=postgres
POSTGRES_PASSWORD=change_me_to_a_strong_password
POSTGRES_HOST=db
POSTGRES_PORT=5432
DJANGO_DEBUG=false
DJANGO_SECRET_KEY=change_me_to_a_long_random_secret
DJANGO_ALLOWED_HOSTS=example.com,localhost,127.0.0.1
CSRF_DOMAINS=https://example.com
CORS_ALLOWED_ORIGINS=https://example.com
SM2_PUBLIC_KEY=your_sm2_public_key
SM2_PRIVATE_KEY=your_sm2_private_key
REDIS_URL=redis://redis:6379/2
CELERY_BROKER_URL=redis://redis:6379/0
CELERY_RESULT_BACKEND=redis://redis:6379/1TIP
The current project uses PostgreSQL. Legacy MYSQL_* variables do not apply to the current Compose and Django configuration.
Build-Time Variables
These variables affect Docker image builds and are wired through Compose build.args. Defaults use official upstream sources; servers in mainland China can override them in .env.
| Variable | Default | Description |
|---|---|---|
DEBIAN_MIRROR_HOST | empty | Optional apt mirror host. Empty means the base image's default Debian sources are used; for example mirrors.tuna.tsinghua.edu.cn. |
PYTHON_PACKAGE_INDEX_URL | https://pypi.org/simple | Python package index used by pip to install uv and by uv pip install to resolve dependencies. |
PYTHON_PACKAGE_TRUSTED_HOST | empty | Optional trusted/insecure host. It is mapped to pip's PIP_TRUSTED_HOST and uv's UV_INSECURE_HOST. |
China build example:
DEBIAN_MIRROR_HOST=mirrors.tuna.tsinghua.edu.cn
PYTHON_PACKAGE_INDEX_URL=https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
PYTHON_PACKAGE_TRUSTED_HOST=mirrors.tuna.tsinghua.edu.cnINFO
Dockerfiles map PYTHON_PACKAGE_INDEX_URL to PIP_INDEX_URL and UV_DEFAULT_INDEX internally. In normal deployments, set only the three variables listed above instead of maintaining pip/uv internal variables directly.
Database
| Variable | Default | Description |
|---|---|---|
POSTGRES_DB | postgres | Database name used by Django; the Postgres container also uses it during initialization. |
POSTGRES_USER | postgres | Database username. |
POSTGRES_PASSWORD | password | Database password. The official Postgres image requires this variable; production must use a strong password. |
POSTGRES_HOST | db | Database host used by Django. In Compose, keep this as db. |
POSTGRES_PORT | 5432 | Database port used by Django. |
Django Core
| Variable | Default | Description |
|---|---|---|
DJANGO_DEBUG | false | Enables debug mode. Use true only for development. |
DJANGO_SECRET_KEY | none | Django secret key. Required when DJANGO_DEBUG=false; development debug mode falls back to a dummy key if unset. |
DJANGO_ALLOWED_HOSTS | localhost,127.0.0.1,backend,10.0.2.2 | Comma-separated allowed Host values. The production settings module overrides this to an empty list when unset. |
CSRF_DOMAINS | empty | Production CSRF trusted origins, including protocol, e.g. https://example.com; comma-separated. |
CORS_ALLOWED_ORIGINS | http://localhost:5173,http://localhost:3000,http://localhost | Comma-separated frontend origins allowed to call the API with cookies. |
LOGIN_THROTTLE_RATE | 5/minute | Login endpoint throttle rate. |
SM2 Login Encryption
| Variable | Default | Description |
|---|---|---|
SM2_PUBLIC_KEY | none | Public key used by the frontend to encrypt login passwords. |
SM2_PRIVATE_KEY | none | Private key used by the backend to decrypt login passwords. The backend can start without it, but login will not work. |
WebAuthn and TOTP
| Variable | Default | Description |
|---|---|---|
TOTP_ISSUER_NAME | MyUCSpace | Issuer name shown in authenticator apps. |
WEBAUTHN_RP_ID | empty | WebAuthn Relying Party ID, usually the production domain. |
WEBAUTHN_RP_NAME | MyUCSpace | WebAuthn Relying Party name. |
WEBAUTHN_ORIGIN | http://localhost:8000 | WebAuthn origin. Use the HTTPS production domain in production. |
File Storage
| Variable | Default | Description |
|---|---|---|
FILE_STORAGE_BACKEND | local | File storage backend, local or s3. |
LOCAL_UPLOAD_DIR | /data/uploads | Local upload directory. |
LOCAL_UPLOAD_URL_PREFIX | /media/uploads/ | URL prefix for locally stored uploads. |
S3_ACCESS_KEY_ID | none | Access key for S3-compatible object storage. |
S3_SECRET_ACCESS_KEY | none | Secret key for S3-compatible object storage. |
S3_BUCKET_NAME | none | S3 bucket name. |
S3_REGION | none | S3 region. |
S3_ENDPOINT_URL | none | Endpoint for S3-compatible services. |
S3_BASE_URL | none | Public base URL for objects. In S3 mode, either S3_BASE_URL or S3_ENDPOINT_URL must be usable for building object URLs. |
WeChat Mini Program and Signage
| Variable | Default | Description |
|---|---|---|
WECHAT_APP_ID | empty | WeChat Mini Program App ID. |
WECHAT_APP_SECRET | empty | WeChat Mini Program App Secret. |
SIGNAGE_BASE_URL | http://10.0.2.2:8000/api/v1/ | Base backend API URL used by Android signage clients. |
SIGNAGE_APK_DIR | /data/signageapk/ | Directory containing signage APK files. |
SIGNAGE_APK_URL_PREFIX | /media/signageapk/ | Download URL prefix for signage APK files. |
Redis and Celery
| Variable | Default | Description |
|---|---|---|
REDIS_URL | redis://localhost:6379/2 | Redis URL used by Django cache. In Compose, usually redis://redis:6379/2. |
CELERY_BROKER_URL | redis://localhost:6379/0 | Celery broker URL. In Compose, usually redis://redis:6379/0. |
CELERY_RESULT_BACKEND | redis://localhost:6379/1 | Celery result backend URL. In Compose, usually redis://redis:6379/1. |
Face Recognition
| Variable | Default | Description |
|---|---|---|
FACE_SERVICE_URL | http://face-service:9000 | URL used by Django to call the face-service. The current core backend and Android signage flow do not strictly depend on this service. |
FACE_MATCH_THRESHOLD | 0.45 | Backend face matching threshold. |
INSIGHTFACE_HOME | /models/insightface | Root directory where face-service loads InsightFace models; production Compose sets it to /app/insightface. |
CUDA_VISIBLE_DEVICES | unset | Runtime device selection for face-service; production Compose currently sets -1 to disable CUDA. |
PYTHONUNBUFFERED | unset | Enables unbuffered Python log output; production face-service sets 1. |
PYTHONDONTWRITEBYTECODE | unset | Disables .pyc writes; production face-service sets 1. |
Example Production .env
DEBIAN_MIRROR_HOST=mirrors.tuna.tsinghua.edu.cn
PYTHON_PACKAGE_INDEX_URL=https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
PYTHON_PACKAGE_TRUSTED_HOST=mirrors.tuna.tsinghua.edu.cn
POSTGRES_DB=myucspace
POSTGRES_USER=postgres
POSTGRES_PASSWORD=change_me_to_a_strong_password
POSTGRES_HOST=db
POSTGRES_PORT=5432
DJANGO_DEBUG=false
DJANGO_SECRET_KEY=change_me_to_a_long_random_secret
DJANGO_ALLOWED_HOSTS=example.com,localhost,127.0.0.1
CSRF_DOMAINS=https://example.com
CORS_ALLOWED_ORIGINS=https://example.com
SM2_PUBLIC_KEY=your_sm2_public_key
SM2_PRIVATE_KEY=your_sm2_private_key
REDIS_URL=redis://redis:6379/2
CELERY_BROKER_URL=redis://redis:6379/0
CELERY_RESULT_BACKEND=redis://redis:6379/1
WECHAT_APP_ID=your_wechat_app_id
WECHAT_APP_SECRET=your_wechat_app_secret