Environment Variables
Environment Variables
This reference lists environment variables used by the production Docker Compose variants.
Each variant has a committed example env file in deployment/env/:
deployment/env/.env.prod.example, deployment/env/.env.prod.local.example, deployment/env/.env.prod.external-keycloak.example, and deployment/env/.env.prod.traefik.example.
Deployment Variant Summary
| Compose File | Purpose | Notes |
|---|---|---|
compose.prod.yaml | Default production (no Traefik, bundled Keycloak) | Direct host ports (3000, 8080, 8090), localhost-bound by default |
compose.prod.external-keycloak.yaml | Production with external Keycloak (no Traefik) | Requires explicit Keycloak URLs/realm envs, localhost-bound ports by default |
compose.prod.traefik.yaml | Advanced/secondary production (Traefik + LetsEncrypt) | Requires DNS and TLS-related envs |
compose.prod.local.yaml | Production-like local stack | Uses local defaults and *.localhost |
BFF Exposure Model
LAREX frontend runs a Nuxt BFF layer. Browser traffic is expected to hit the frontend service (/api/* on the same origin), while the frontend talks to backend via NUXT_API_BASE_INTERNAL.
Direct public backend exposure is deployment-specific (for example debugging/legacy API routing), not required for normal frontend operation.
Shared Production Variables
PostgreSQL
| Variable | Default | Description |
|---|---|---|
POSTGRES_USER | - | Database username (required) |
POSTGRES_PASSWORD | - | Database password (required) |
POSTGRES_DB | larexdb | Database name |
LAREX_PUBLISH_IP | 127.0.0.1 (no-Traefik presets) | Host interface for published frontend/app/Keycloak ports |
LAREX_LOCAL_BIND_IP | 127.0.0.1 (local preset) | Host interface for local Traefik and Mailpit ports |
Application / Backend
| Variable | Default | Description |
|---|---|---|
CORS_ALLOWED_ORIGIN | - | Allowed frontend origin (required for production variants) |
KEYCLOAK_ADMIN_CLIENT_SECRET | - | Backend service client secret (required) |
KEYCLOAK_RESOURCE_CLIENT_ID | larex-backend (bundled presets) | Backend resource client ID |
MAIL_ENABLED | true | Enable email functionality |
MAIL_HOST | smtp.example.com | SMTP server hostname |
MAIL_PORT | 587 | SMTP port |
MAIL_USERNAME | - | SMTP username |
MAIL_PASSWORD | - | SMTP password |
MAIL_FROM | noreply@example.com | Sender address |
MAIL_SMTP_AUTH | true | Enable SMTP authentication |
MAIL_SMTP_STARTTLS | true | Enable STARTTLS |
Bundled Keycloak Variables
Used by compose.prod.yaml, compose.prod.traefik.yaml, and compose.prod.local.yaml.
| Variable | Default | Description |
|---|---|---|
KEYCLOAK_ADMIN | - | Keycloak bootstrap admin username |
KEYCLOAK_ADMIN_PASSWORD | - | Keycloak bootstrap admin password |
KEYCLOAK_HOSTNAME | Variant-specific | Public Keycloak hostname (or localhost:8090 in default no-Traefik preset) |
KEYCLOAK_ADMIN_SERVER_URL | http://keycloak:8080 (bundled presets) | Backend admin client URL override (internal service URL) |
KEYCLOAK_ADMIN_REALM | larex-prod (prod presets), larex-dev (local preset) | Realm used by backend admin client |
External Keycloak Variables
Required for compose.prod.external-keycloak.yaml.
| Variable | Default | Description |
|---|---|---|
KEYCLOAK_ADMIN_SERVER_URL | - | External Keycloak admin base URL |
KEYCLOAK_ADMIN_REALM | - | Realm used by the backend admin client |
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI | - | JWT issuer URI used by Spring Security |
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI | Computed by Spring (optional) | Optional override for JWK endpoint |
Traefik-Only Variables (Advanced/Secondary Preset)
Used by compose.prod.traefik.yaml.
| Variable | Default | Description |
|---|---|---|
ACME_EMAIL | - | Email used by LetsEncrypt/ACME |
FRONTEND_HOSTNAME | - | Public frontend hostname used by Traefik routers |
API_HOSTNAME | - | Public API hostname used by Traefik app router (only needed when exposing backend directly) |
KEYCLOAK_HOSTNAME | - | Public Keycloak hostname used by Traefik routers |
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI | - | Public Keycloak issuer URI (recommended explicit setting) |
NUXT_OAUTH_KEYCLOAK_SERVER_URL | - | Public Keycloak URL for frontend OAuth flows |
NUXT_OAUTH_KEYCLOAK_REDIRECT_URL | - | OAuth redirect URL for frontend |
Frontend Runtime OAuth Variables
These are used by production compose variants to configure Nuxt runtime auth settings.
| Variable | Default | Description |
|---|---|---|
NUXT_SESSION_PASSWORD | - | Session encryption secret for nuxt-auth-utils (required, 32+ chars) |
NUXT_API_BASE_INTERNAL | http://app:8080/api/v1 | Internal backend URL used by the frontend container |
NUXT_OAUTH_KEYCLOAK_SERVER_URL | Variant-specific | Public Keycloak URL used by the browser |
NUXT_OAUTH_KEYCLOAK_SERVER_URL_INTERNAL | Variant-specific | Internal Keycloak URL used by server-side token refresh/logout |
NUXT_OAUTH_KEYCLOAK_REALM | Variant-specific | Keycloak realm name |
NUXT_OAUTH_KEYCLOAK_CLIENT_ID | Variant-specific | Frontend OAuth client ID |
NUXT_OAUTH_KEYCLOAK_CLIENT_SECRET | - | Frontend OAuth client secret |
NUXT_OAUTH_KEYCLOAK_REDIRECT_URL | Variant-specific | OAuth callback URL |
Backend / Spring Override Variables
These can be used to override values from application-prod.yaml without editing code.
| Variable | Default | Description |
|---|---|---|
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI | Profile config / compose override | JWT issuer URI expected by backend |
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI | Derived from issuer (unless overridden) | JWK endpoint override (useful with internal Keycloak network URL) |
KEYCLOAK_ADMIN_SERVER_URL | Profile config / compose override | Keycloak admin API URL |
KEYCLOAK_ADMIN_REALM | Profile config / compose override | Keycloak admin realm |
KEYCLOAK_RESOURCE_CLIENT_ID | Profile config / compose override | Backend resource client ID |
Variant Examples
The examples below are also available as ready-to-copy files in deployment/env/.
Example: Default Production (compose.prod.yaml)
POSTGRES_USER=larex_prod
POSTGRES_PASSWORD=your-secure-password
KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=your-admin-password
KEYCLOAK_ADMIN_CLIENT_SECRET=your-backend-client-secret
KEYCLOAK_RESOURCE_CLIENT_ID=larex-backend
CORS_ALLOWED_ORIGIN=http://localhost:3000
NUXT_SESSION_PASSWORD=replace-with-random-32-plus-character-secret
NUXT_OAUTH_KEYCLOAK_CLIENT_SECRET=your-frontend-client-secret
NUXT_OAUTH_KEYCLOAK_SERVER_URL=http://localhost:8090
NUXT_OAUTH_KEYCLOAK_SERVER_URL_INTERNAL=http://keycloak:8080
NUXT_OAUTH_KEYCLOAK_REALM=larex-prod
NUXT_OAUTH_KEYCLOAK_CLIENT_ID=larex-frontend
NUXT_OAUTH_KEYCLOAK_REDIRECT_URL=http://localhost:3000/auth/keycloak
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI=http://localhost:8090/realms/larex-prod
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI=http://keycloak:8080/realms/larex-prod/protocol/openid-connect/certs
Example: External Keycloak (compose.prod.external-keycloak.yaml)
POSTGRES_USER=larex_prod
POSTGRES_PASSWORD=your-secure-password
CORS_ALLOWED_ORIGIN=https://app.example.org
KEYCLOAK_RESOURCE_CLIENT_ID=larex-backend
KEYCLOAK_ADMIN_CLIENT_SECRET=your-backend-client-secret
KEYCLOAK_ADMIN_SERVER_URL=https://auth.example.org
KEYCLOAK_ADMIN_REALM=larex-prod
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI=https://auth.example.org/realms/larex-prod
NUXT_SESSION_PASSWORD=replace-with-random-32-plus-character-secret
NUXT_OAUTH_KEYCLOAK_SERVER_URL=https://auth.example.org
NUXT_OAUTH_KEYCLOAK_SERVER_URL_INTERNAL=https://auth.example.org
NUXT_OAUTH_KEYCLOAK_REALM=larex-prod
NUXT_OAUTH_KEYCLOAK_CLIENT_ID=larex-frontend
NUXT_OAUTH_KEYCLOAK_CLIENT_SECRET=your-frontend-client-secret
NUXT_OAUTH_KEYCLOAK_REDIRECT_URL=https://app.example.org/auth/keycloak
Example: Advanced/Secondary Traefik (compose.prod.traefik.yaml)
POSTGRES_USER=larex_prod
POSTGRES_PASSWORD=your-secure-password
KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=your-admin-password
KEYCLOAK_ADMIN_CLIENT_SECRET=your-backend-client-secret
KEYCLOAK_RESOURCE_CLIENT_ID=larex-backend
FRONTEND_HOSTNAME=app.example.org
API_HOSTNAME=api.example.org
KEYCLOAK_HOSTNAME=auth.example.org
CORS_ALLOWED_ORIGIN=https://app.example.org
ACME_EMAIL=admin@example.org
SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI=https://auth.example.org/realms/larex-prod
NUXT_SESSION_PASSWORD=replace-with-random-32-plus-character-secret
NUXT_OAUTH_KEYCLOAK_SERVER_URL=https://auth.example.org
NUXT_OAUTH_KEYCLOAK_SERVER_URL_INTERNAL=http://keycloak:8080
NUXT_OAUTH_KEYCLOAK_REALM=larex-prod
NUXT_OAUTH_KEYCLOAK_CLIENT_ID=larex-frontend
NUXT_OAUTH_KEYCLOAK_CLIENT_SECRET=your-frontend-client-secret
NUXT_OAUTH_KEYCLOAK_REDIRECT_URL=https://app.example.org/auth/keycloak
Example: Production-Like Local (compose.prod.local.yaml)
# Optional: most values have local defaults in compose.prod.local.yaml
NUXT_SESSION_PASSWORD=replace-with-random-32-plus-character-secret
KEYCLOAK_ADMIN_CLIENT_SECRET=PLEASE_CHANGE_IN_PRODUCTION
NUXT_OAUTH_KEYCLOAK_CLIENT_SECRET=PLEASE_CHANGE_IN_PRODUCTION
Resource Limits
Modify resource limits in the relevant compose file (compose.prod.yaml, compose.prod.traefik.yaml, etc.) under deploy.resources.
Security Considerations
Sensitive Variables
Never commit these to version control:
POSTGRES_PASSWORDKEYCLOAK_ADMIN_PASSWORDKEYCLOAK_ADMIN_CLIENT_SECRETNUXT_SESSION_PASSWORDNUXT_OAUTH_KEYCLOAK_CLIENT_SECRETMAIL_PASSWORD
Use a secrets management tool or Docker secrets for production.
Variable Security
# Use environment file with restricted permissions
chmod 600 .env.prod
Validation
Verify variables are set correctly:
# Check configured variables
grep -E "^[A-Z_]+=.+$" .env.prod | sort
# Validate compose variants with explicit env files
docker compose --env-file .env.prod -f compose.prod.yaml config
docker compose --env-file .env.prod.external-keycloak -f compose.prod.external-keycloak.yaml config
docker compose --env-file .env.prod.traefik -f compose.prod.traefik.yaml config
docker compose --env-file .env.prod.local -f compose.prod.local.yaml config