ci/woodpecker/push/deploy Pipeline was successful
traefik/traefik.env did not exist on the host after PR #21 merged. Root cause: provisioning only renders on a push touching traefik/, and traefik is bootstrap-tier (stack-deploy.sh runs manually, never via the pipeline). A manual stack-deploy.sh traefik run apparently happened while the env file was absent, causing Swarm's own interpolation to render KEEPALIVED_PASSWORD/KEEPALIVED_VIRTUAL_IPS as empty strings on keepalived-master. This comment-only change re-triggers provision-secrets; a manual stack-deploy.sh traefik run is still required afterward to apply the freshly-rendered env to the running services.
53 lines
3.6 KiB
Bash
53 lines
3.6 KiB
Bash
# ─────────────────────────────────────────────────────────────────────────
|
|
# 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.
|
|
#
|
|
# 2026-09-12 RE-TRIGGER: traefik.env was found MISSING on disk after the
|
|
# Pattern C migration merged — the manifest-driven provisioning render only
|
|
# happens on a push that changes traefik/, and traefik is bootstrap-tier
|
|
# (stack-deploy.sh must be run manually; the pipeline never auto-deploys
|
|
# this stack). A manual `stack-deploy.sh traefik` had apparently been run
|
|
# while traefik.env was absent, causing Swarm's own interpolation to
|
|
# silently render KEEPALIVED_PASSWORD/KEEPALIVED_VIRTUAL_IPS as EMPTY
|
|
# STRINGS on keepalived-master (not missing — empty, which is worse,
|
|
# since it's a valid-looking VRRP auth string that mismatches everything).
|
|
# This comment-only change re-triggers provision-secrets to re-render and
|
|
# re-ship traefik.env; a manual `stack-deploy.sh traefik` must still be run
|
|
# afterward to actually apply it to the running services.
|
|
# ─────────────────────────────────────────────────────────────────────────
|
|
|
|
# ── Keepalived (non-secret config) ────────────────────────────────────────
|
|
KEEPALIVED_VIRTUAL_IPS="#PYTHON2BASH:['192.168.4.30']"
|
|
|
|
# ── Keepalived (secret) ────────────────────────────────────────────────────
|
|
KEEPALIVED_PASSWORD=${TRAEFIK_KEEPALIVED_PASSWORD}
|