# ───────────────────────────────────────────────────────────────────────── # traefik.env.template — AUTHORITATIVE template for traefik/traefik.env # (rendered by deploy/provision-stack.py per secrets/secrets-map.yaml) # # - This file IS the complete key list for traefik.env. The whole file is # rendered on every provisioning run — no line surgery, so a key can # never silently go missing. # - Non-secret config lives here as LITERAL values (visible, reviewable). # - Secret values are dollar-brace placeholders resolved from the CI env # (Woodpecker from_secret vars) at provisioning time. provision-stack.py # FAILS HARD if any placeholder is missing/empty. # - The rendered traefik/traefik.env exists only on the host (gitignored). # - Rendered by provision-stack.py, NOT Woodpecker's yaml preprocessor — # single-dollar placeholders are safe here (deploy.yml's double-dollar # rule does NOT apply to this file). # # Consumed by traefik/traefik.yaml (KEEPALIVED_PASSWORD, KEEPALIVED_VIRTUAL_IPS). # DOMAIN comes from deploy/global.env, not here. # # ⚠️ HIGH RISK: Traefik is the entry point for all homelab services, and the # Keepalived VIP (192.168.4.30) depends on this stack. KEEPALIVED_PASSWORD # MUST be identical across keepalived-master and keepalived-backup — both # consume this same rendered value — or VRRP auth fails and the VIP # becomes unstable (this is exactly what the 2026-09-12 incident was: # a committed literal "***REDACTED***" placeholder in git, restored every # time the file was deleted/re-synced, diverging from -backup's stale but # correct in-memory value). # # Classic VRRP simple-auth is silently truncated to 8 characters by # keepalived itself. Set TRAEFIK_KEEPALIVED_PASSWORD in Woodpecker to a # value 8 characters or fewer (or accept that only the first 8 chars are # actually significant) so the effective negotiated value is unambiguous. # ───────────────────────────────────────────────────────────────────────── # ── Keepalived (non-secret config) ──────────────────────────────────────── KEEPALIVED_VIRTUAL_IPS="#PYTHON2BASH:['192.168.4.30']" # ── Keepalived (secret) ──────────────────────────────────────────────────── KEEPALIVED_PASSWORD=${TRAEFIK_KEEPALIVED_PASSWORD}