Environment variables behind the Self-Hosting deployment.
For source development, use Local Setup and the repository's .env.sample. Many values can embed the literal string <subdomain>, which getEnv (utils.ts) replaces with the request tenant at runtime; useful for per-tenant URLs and keys.
Runtime vs build-time
Backend services read everything below from the container environment at startup; restart to apply changes. The Core UI container is different: its entrypoint writes every REACT_APP_* variable into a browser-readable js/env.js at startup, so REACT_APP_* values behave as runtime configuration for erxes/erxes-next-ui even though the same names are baked into the bundle as fallbacks. The standalone apps (client-portal-template, help-center, posclient-front) read NEXT_PUBLIC_* values at their own build or entrypoint time; see their app pages.
Core runtime
Variable
Read by
Required
Default
Notes
NODE_ENV
All backend + UI
Yes
none
production in deployment; development enables dev remotes, router download, and CORS extras
Must match the Redis container's requirepass; there is no REDIS_URL
SKIP_REDIS
posclient sync utils
No
none
When set, POS config sync throws token not found instead of creating a config for an unknown token
Redis holds service discovery (erxes-service-*, erxesservice:config:*), session tokens (user_token_*), plugin lists (erxes-active-plugins), and every BullMQ queue. Persist it (--appendonly yes) and use noeviction.
URLs, domains, and CORS
Variable
Read by
Required
Default
Notes
DOMAIN
gateway, core-api, services
Yes
http://localhost:3000
Public UI origin; also the CORS allow-list anchor and the stored hostname fallback
GATEWAY_URL
core-api email links
No
${DOMAIN}/gateway
Public gateway prefix used in emails, unsubscribe links, webhooks
WIDGETS_DOMAIN
gateway, core-api
No
http://localhost:3200
Widgets origin added to CORS
ALLOWED_DOMAINS
gateway, core-api, services
No
none
Extra comma-separated CORS origins
ALLOWED_ORIGINS
gateway, core-api, services
No
none
Comma-separated regexes appended to the CORS origin list
CLIENT_PORTAL_DOMAINS
logs, automations services
No
none
Extra origins for the background services' CORS
TRUST_PROXY
All backend services
No
loopback, linklocal, uniquelocal
Express trust proxy; widen only if your LB appends client IPs
Auth and sessions
Variable
Read by
Required
Default
Notes
JWT_TOKEN_SECRET
gateway, core-api, plugins
Yes
SECRET
Signs and verifies user, portal, and app JWTs. Change it and keep it identical on every backend service
SAME_SITE
core-api
No
none
Set to none to emit cross-site auth cookies where the code supports it
WORKOS_API_KEY, WORKOS_PROJECT_ID
core-api
For WorkOS SSO
none
SSO login mutations
OAUTH_DEVICE_VERIFICATION_URI
core-api
No
built-in
OAuth device-flow verification page override
Plugin and service selection
Variable
Read by
Required
Default
Notes
ENABLED_PLUGINS
gateway, core-api, dev scripts
For plugins
none
Comma-separated base names (sales,operation); controls gateway waits and /get-frontend-plugins
ENABLED_PLUGINS_ONLY_API
gateway, dev scripts
No
none
Backend-only plugins without frontend remotes
ENABLED_SERVICES
scripts/start-api-dev.js
Dev only
none
automations,logs → *-service Nx projects; not read by Docker images
MAX_PLUGIN_RETRY
gateway
No
unlimited
Bounds plugin-join and /graphql readiness retries at startup
Gateway tuning
Variable
Read by
Required
Default
Notes
APOLLO_ROUTER_PORT
gateway
No
50000
Loopback port for the internal router
INTROSPECTION
gateway
No
off in production
true enables GraphQL introspection in production
GRAPHQL_LIMITER
gateway
No
off
When set, applies depth/alias/character limits to /graphql
SUPERGRAPH_POLL_INTERVAL_MS
gateway (dev)
No
10000
Dev-mode recompose interval
DEBUG_GATEWAY_AUTH
gateway
No
false
Verbose auth, proxy, and limiter request logs
Workers and retention
Variable
Read by
Required
Default
Notes
LOG_RETENTION_DAYS
erxes-api-shared logs schema
No
365
TTL index on the _logs database logs collection
REVERT_AUTO_JOURNAL_MAX
erxes-api-shared
No
1000
Max documents snapshotted per bulk write for the undo journal
Variables on the standalone apps include NEXT_PUBLIC_ERXES_API_URL (client-portal-template, help-center; the latter injects it into env.js via its own docker-entrypoint.sh), NEXT_PUBLIC_ERXES_CP_TOKEN (client-portal-template only), and NEXT_PUBLIC_MAIN_API_DOMAIN, NEXT_PUBLIC_APP_VERSION (posclient-front). Check each app's Dockerfile/entrypoint: a container env override only works where the app injects runtime env; otherwise rebuild after changing them.
Storage and upload settings are system configs stored in the database, read via configs.getConfigs: UPLOAD_SERVICE_TYPE, AWS_BUCKET, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_COMPATIBLE_SERVICE_ENDPOINT, AWS_FORCE_PATH_STYLE, AWS_PREFIX, GOOGLE_CLOUD_STORAGE_BUCKET, GOOGLE_APPLICATION_CREDENTIALS, GOOGLE_PROJECT_ID, CLOUDFLARE_*, AZURE_STORAGE_*, FILE_SYSTEM_PUBLIC. Set them in Settings → file upload, not in .env.