| title |
| Environment Variables |
Environment Variables Reference
Environment variables configure your Frappe Docker setup. They can be set directly in the container or defined in a .env file referenced by Docker Compose.
Getting Started:
cp example.env .env
Then edit .env and set variables according to your needs.
Required Variables
| Variable |
Purpose |
Example |
Notes |
FRAPPE_PATH |
Frappe framework path |
https://github.com/frappe/frappe |
|
FRAPPE_BRANCH |
Frappe Branch |
version-15 |
See Frappe releases |
ERPNEXT_VERSION |
ERPNext release version |
v15.67.0 |
Required although its never used |
DB_PASSWORD |
Password for database root (MariaDB or Postgres) |
secure_password_123 |
Not needed if using DB_PASSWORD_SECRETS_FILE |
Database Configuration
| Variable |
Purpose |
Default |
When to Set |
DB_PASSWORD |
Database root user password |
123 |
Always (unless using secrets file) |
DB_PASSWORD_SECRETS_FILE |
Path to file containing database password |
— |
Setup mariadb-secrets overrider |
DB_HOST |
Database hostname or IP |
db (service name) |
Only if using external database |
DB_PORT |
Database port |
3306 (MariaDB) / 5432 (Postgres) |
Only if using external database |
Redis Configuration
| Variable |
Purpose |
Default |
When to Set |
REDIS_CACHE |
Redis hostname for caching |
redis-cache (service name) |
Only if using external Redis instance |
REDIS_QUEUE |
Redis hostname for job queues and real-time updates |
redis-queue (service name) |
Only if using external Redis instance |
Reverse Proxy and SSL (HTTPS) Configuration
Traefik (compose.proxy.yaml / compose.https.yaml)
| Variable |
Purpose |
Default |
When to Set |
LETSENCRYPT_EMAIL |
Email for Let's Encrypt certificate registration |
- |
Required for compose.https.yaml |
SITES_RULE |
Domains for routing (Traefik rule expression) |
- |
Required for Traefik routing/HTTPS overrides |
Format for SITES_RULE:
# Single site
SITES_RULE=Host(`mysite.example.com`)
# Multiple sites
SITES_RULE=Host(`a.example.com`) || Host(`b.example.com`)
Note: The Traefik v3 migration is complete. Use SITES_RULE as a full v3 rule expression; SITES is deprecated.
Rule syntax now defaults to v3, so no core.defaultRuleSyntax or per-router ruleSyntax settings are required.
nginx-proxy + acme-companion (compose.nginxproxy*.yaml)
| Variable |
Purpose |
Default |
When to Set |
LETSENCRYPT_EMAIL |
Email for Let's Encrypt certificate |
- |
Required for compose.nginxproxy-ssl.yaml |
NGINX_PROXY_HOSTS |
Comma-separated hostnames for nginx-proxy |
- |
Required for compose.nginxproxy*.yaml |
Example:
NGINX_PROXY_HOSTS=example.com,www.example.com
Note: Automatic certificates require port 80 to be reachable (HTTP-01).
Published Ports (Traefik and nginx-proxy)
| Variable |
Purpose |
Default |
When to Set |
HTTP_PUBLISH_PORT |
Published HTTP port |
80 (proxy) / 8080 (noproxy) |
Change if port is in use |
HTTPS_PUBLISH_PORT |
Published HTTPS port |
443 |
Change if port 443 is in use |
Site Configuration
| Variable |
Purpose |
Default |
When to Set |
FRAPPE_SITE_NAME_HEADER |
Site name for multi-tenant setup |
$host (resolved from request hostname) |
When accessing by IP or need explicit site name |
Examples:
If your site is named mysite but you want to access it via 127.0.0.1:
FRAPPE_SITE_NAME_HEADER=mysite
If your site is named example.com and you access it via that domain, no need to set this (defaults to hostname).
Image Configuration
| Variable |
Purpose |
Default |
Notes |
CUSTOM_IMAGE |
Custom Docker image repository |
Frappe official image |
Leave empty to use default |
CUSTOM_TAG |
Custom Docker image tag |
Latest stable |
Corresponds to FRAPPE_VERSION |
PULL_POLICY |
Image pull behavior |
always |
Options: always, never, if-not-present |
RESTART_POLICY |
Container restart behavior |
unless-stopped |
Options: no, always, unless-stopped, on-failure |
Backend (Gunicorn) Configuration
| Variable |
Purpose |
Default |
When to Set / Allowed Values |
GUNICORN_WORKERS |
Number of worker processes handling web requests |
2 |
Scale up for multi-core CPUs. Formula: (2 x Cores) + 1 |
GUNICORN_THREADS |
Number of concurrent threads per worker process |
4 |
Increase to handle more simultaneous I/O-bound requests without high memory cost |
GUNICORN_TIMEOUT |
Max time a worker can spend on a single request before restart |
120 |
Increase if long-running reports or data imports time out |
Frontend Nginx Configuration (inside the frontend container)
| Variable |
Purpose |
Default |
Allowed Values |
BACKEND |
Backend service address and port |
0.0.0.0:8000 |
{host}:{port} |
SOCKETIO |
Socket.IO service address and port |
0.0.0.0:9000 |
{host}:{port} |
PROXY_READ_TIMEOUT |
Upstream request timeout |
120s |
Any nginx timeout value (e.g., 300s, 5m) |
CLIENT_MAX_BODY_SIZE |
Maximum upload file size |
50m |
Any nginx size value (e.g., 100m, 1g) |
Real IP Configuration (Behind Proxy)
Use these variables when running behind a reverse proxy or load balancer:
| Variable |
Purpose |
Default |
UPSTREAM_REAL_IP_ADDRESS |
Trusted upstream IP address for real IP detection |
127.0.0.1 |
UPSTREAM_REAL_IP_HEADER |
Request header containing client IP |
X-Forwarded-For |
UPSTREAM_REAL_IP_RECURSIVE |
Enable recursive IP search |
off |
Migration Service
| Variable |
Purpose |
Default |
Allowed Values |
MIGRATE_SITES |
Switch auto migration on or off |
true - auto migration on |
true , false |