# Entra ID / OIDC ENTRA_TENANT_ID= ENTRA_CLIENT_ID= ENTRA_CLIENT_SECRET= # Base URL the app is reachable at (no trailing slash). # Used to build the OIDC redirect URI {APP_BASE_URL}/auth/callback APP_BASE_URL=http://localhost:8080 # Path to the SQLite database file inside the container. Leave as-is unless # you have a specific reason to change it. The parent dir is the mounted # volume (/var/www/data). DB_PATH=/var/www/data/app.sqlite # Session handler files directory. SESSION_PATH=/var/www/data/sessions # 'production' disables verbose error output. Anything else is treated as dev. APP_ENV=production # --------------------------------------------------------------------------- # Reverse-proxy trust (R01-N05 / R01-N07). Comma-separated list of CIDRs of # the proxies in front of the app. When the immediate peer (`REMOTE_ADDR`) # matches one of these: # * `X-Forwarded-For` is walked to find the real client IP — used for the # audit log and the local-admin login throttle bucket; # * `X-Forwarded-Proto: https` is honoured for cookie `Secure` / HSTS # decisions, so a TLS-terminating proxy can mark requests as HTTPS. # Leave blank when the app is exposed directly with no reverse proxy. Examples: # TRUSTED_PROXIES=10.0.0.0/8,192.168.0.0/16 # TRUSTED_PROXIES=172.16.0.5,2001:db8::/32 # --------------------------------------------------------------------------- TRUSTED_PROXIES= # --------------------------------------------------------------------------- # OIDC bootstrap admin (optional) — nominate the very first administrator up # front, so a public-facing first deploy can't be land-grabbed by another # tenant member who happens to sign in before you. Auto-promotion to admin # happens via OIDC iff no admin exists yet AND the signing user matches one # of the values below (case-insensitive). With both variables blank, the # OIDC path NEVER auto-promotes — seed the first admin via the local-admin # fallback below, or by manually flipping is_admin in the database. # Set BOOTSTRAP_ADMIN_OID to the Entra `oid` claim (a GUID, immutable) when # you know it; BOOTSTRAP_ADMIN_EMAIL is accepted as a fallback when you only # have the email. # --------------------------------------------------------------------------- BOOTSTRAP_ADMIN_OID= BOOTSTRAP_ADMIN_EMAIL= # --------------------------------------------------------------------------- # Local admin (optional) — lets you sign in without Entra, e.g. during initial # setup or for a fully on-prem deployment. Set BOTH email and the password # hash to enable; leave blank to disable. The password is verified with PHP's # password_verify() against LOCAL_ADMIN_PASSWORD_HASH, so .env never contains # the password itself. Generate the hash with: # docker run --rm php:8.3-cli php -r \ # 'echo password_hash(readline("Password: "), PASSWORD_DEFAULT), PHP_EOL;' # (Or `php -r '...'` directly if you have PHP 8 on the host.) Paste the # resulting `$2y$...` string verbatim. Single quotes recommended in .env so # the `$` in the hash isn't interpreted by the shell. # The resulting user is stored with entra_oid = "local:" and is_admin=1. # This path is itself an explicit env-bootstrap and does not require the # BOOTSTRAP_ADMIN_* variables above. # --------------------------------------------------------------------------- LOCAL_ADMIN_EMAIL= LOCAL_ADMIN_PASSWORD_HASH= LOCAL_ADMIN_NAME=Local Admin