# Dorfteich stage configuration. Copy to `.env` (mode 600, never in git) # next to docker-compose.yml and adjust the values. # --- required --------------------------------------------------------------- # PostgreSQL password for the `dorfteich` database user. POSTGRES_PASSWORD=change-me # ROOT key of the token key hierarchy (ADR 0020, issue #188): every token # purpose (collaboration tokens, digest unsubscribe links) derives its own # HKDF subkey from this value — nothing signs with it directly. The api and # collab services share this one value; use a long random string # (e.g. `openssl rand -base64 32`). Min length 16. Rotating it rotates all # derived keys at once and invalidates outstanding tokens. COLLAB_TOKEN_SECRET=change-me-to-a-long-random-string # --- images ----------------------------------------------------------------- # Image name prefix. Stages pull from the Gitea registry, e.g. # gitea.101010.cloud/stwaidele/dorfteich — local builds use the default. IMAGE_PREFIX=dorfteich # Image tag to run: a git SHA, `test`, `int`, or a release tag like v1.2.0. TAG=latest # Registry prefix for THIRD-PARTY images (postgres, pandoc, gotenberg, # caddy) — for airgapped sites pulling from an internal mirror # (issue #218, ADR 0024). Must end with a slash, e.g. # `registry.example.gov/mirror/`. Empty = public registries. Own images # are covered by IMAGE_PREFIX above, which may equally carry a registry. REGISTRY_PREFIX= # --- ports (localhost only; the host reverse proxy routes to these) --------- # Suggested per stage on the shared host (ONE): test 8100/8101/8102, # int 8110/8111/8112, prod 8120/8121/8122 (web/api/collab). WEB_PORT=8100 API_PORT=8101 # collab (Hocuspocus) WebSocket server; the proxy routes /collab here. COLLAB_PORT=8102 # --- behavior ---------------------------------------------------------------- # pino log level: fatal|error|warn|info|debug|trace LOG_LEVEL=info # Session bounds in hours (issue #190). ABSOLUTE caps the total session # lifetime from login (also the cookie maxAge) — activity never extends it. # IDLE ends sessions unused for that long; activity renews it, enforced # server-side. Unset = defaults: 168 (7 days) absolute, 72 (3 days) idle. # VS-NfD reference operation (hardening guide): 12 absolute, 1 idle. #SESSION_ABSOLUTE_HOURS=168 #SESSION_IDLE_HOURS=72 # Compose project name; set per stage (dorfteich-test, dorfteich-int, …). COMPOSE_PROJECT_NAME=dorfteich # --- public URL + mail -------------------------------------------------------- # Public base URL of the stage (scheme + host). E-mail links and the CSRF # origin check are derived from it — it must match what browsers use. APP_BASE_URL=https://wiki.example.com # SMTP relay for outgoing mail (verification, password reset). Optional: # leave everything unset and configure the relay in the browser during the # first-run setup wizard instead (stored on the `secrets` volume, issue #80). # Values set here always win over wizard-stored ones. SMTP_HOST=mail.example.com SMTP_PORT=465 SMTP_SECURE=true SMTP_USER=wiki@example.com SMTP_PASS=change-me SMTP_FROM=Dorfteich # --- optional TLS ingress (`caddy` profile, issue #88) ------------------------- # Only when you have no reverse proxy of your own: start with # `docker compose --profile caddy up -d`. Caddy terminates TLS for DOMAIN # via Let's Encrypt (80+443 must be reachable from the internet; keep # APP_BASE_URL=https:// in sync). The `localhost` default issues # an internal-CA certificate instead — good for smoke tests only. #DOMAIN=wiki.example.com # Published ports; change only when 80/443 are taken on the host. #CADDY_HTTP_PORT=80 #CADDY_HTTPS_PORT=443 # --- external authentication (issues #214–#216, ADR 0021) --------------------- # Deploy-level on purpose — a Site Admin cannot change these. All unset = # local username/password login only. Full reference: # docs/architecture/security.md §External authentication. # OIDC (Authorization Code + PKCE) is enabled iff ISSUER + CLIENT_ID are set; # CLIENT_SECRET stays empty for a public client. Redirect URI to register at # the IdP: $APP_BASE_URL/api/v1/auth/oidc/callback #OIDC_ISSUER=https://idp.example.com/realms/example #OIDC_CLIENT_ID=dorfteich-web #OIDC_CLIENT_SECRET= #OIDC_SCOPES=openid profile email #OIDC_PROVIDER_LABEL=Single Sign-On # Hard switch (#216): false turns EVERY local credential flow off (404) — # sign-in only via OIDC or the trusted proxy. Complete the first-run setup # BEFORE flipping it. #AUTH_LOCAL_ENABLED=false # Perimeter authentication (#215): identity from a proxy header, honoured # only when the TCP peer is on the allowlist; the proxy MUST strip the # header from incoming traffic. Unset = feature off, the header is inert. #AUTH_PROXY_HEADER=X-Auth-User #AUTH_PROXY_TRUSTED_PEERS=10.0.0.5 #AUTH_PROXY_MAP=username #AUTH_PROXY_MODE=plain #AUTH_PROXY_DN_ATTRIBUTE=CN # --- backups (ADR 0015, issue #83) -------------------------------------------- # The backup sidecar dumps the database and archives the data volumes # (uploads, plugins, custom fonts, branding) nightly onto the `backups` # volume; restore via deploy/backup/restore.sh . All values # optional. # Daily run time HH:MM in TZ (default 03:00; set TZ for stage-local time, # e.g. TZ=Europe/Berlin — unset means UTC). #TZ=Europe/Berlin #BACKUP_TIME=03:00 # Local retention in days: 30 (default) for Prod, 7 for Test/Int (ADR 0015). # A Site Admin can override this in the admin UI (issue #103) — the saved # setting then wins over this value. #BACKUP_RETENTION_DAYS=30 # Off-host copies to a Nextcloud (issue #103) are configured entirely in the # admin UI (Admin -> System -> Backups) — no env values needed here. # Failure alert: recipient (unset = no mail, failures only in the logs and # status.json), mail language (de|en), and the label used in the subject # (defaults to the compose project name). #BACKUP_MAIL_TO=ops@example.com #BACKUP_MAIL_LOCALE=en #BACKUP_INSTANCE_LABEL=dorfteich-test # Deploy-level allowlist of permissible backup destination HOSTS (issue # #192, ADR 0026), comma-separated — e.g. "cloud.example.org,172.30.1.10". # EMPTY (the default) DISABLES every remote target, the admin-configured # WebDAV/Nextcloud upload and the rsync mirror alike; backups then stay # local only (the VS-NfD reference configuration). BREAKING: existing # deployments with a remote target must list its host here, or uploads and # mirror stop. Deploy-level on purpose: Site-Admins cannot widen it. #BACKUP_ALLOWED_TARGETS=cloud.example.org,172.30.1.10 # VS-NfD hardening-profile mode (issue #243, ADR 0027): how the application # treats configuration that violates the reference profile of # docs/vs-nfd/50-haertungsleitfaden.md. off (default) = VS-NfD is not a # topic, no marking anywhere; marked = violations are marked in the admin # UI; hidden = violating options disappear (the hiding is marked); # enforced = violating writes are rejected server-side. The treatments # roll out with #244–#246; until then every non-off mode shows the profile # card in the admin settings. Deploy-level on purpose: Site-Admins cannot # widen it. #VS_NFD_MODE=marked # Optional rsync mirror of the backup sets to a private host (issue #84): # rsync-over-ssh target plus the private key file INSIDE the container — # put the key on the secrets volume (docker compose cp), never in the repo. # Full setup walkthrough: deploy/backup-basel.md. Unset = no mirror. #BACKUP_MIRROR_TARGET=dorfteich-backup@172.30.1.10:/home/RAID/BACKUPS/dorfteich-prod/ #BACKUP_MIRROR_SSH_KEY=/data/secrets/backup_mirror_ed25519 #BACKUP_MIRROR_SSH_PORT=22 # --- first-run setup (optional pre-seeding, issue #80) ------------------------ # A fresh (empty) database makes the instance require the browser setup # wizard. Automated deploys can skip it entirely by pre-seeding the Site # Admin here; the wizard then completes and locks itself at first boot. # All three SETUP_ADMIN_* values are required for pre-seeding to trigger. #SETUP_ADMIN_USERNAME=admin #SETUP_ADMIN_EMAIL=admin@example.com #SETUP_ADMIN_PASSWORD=change-me-please #SETUP_ADMIN_DISPLAY_NAME=Admin #SETUP_INSTANCE_NAME=Dorfteich #SETUP_DEFAULT_LOCALE=en #SETUP_REGISTRATION_MODE=open