diff --git a/.gitea/workflows/nightly.yml b/.gitea/workflows/nightly.yml index ab0ee276..63ec0b03 100644 --- a/.gitea/workflows/nightly.yml +++ b/.gitea/workflows/nightly.yml @@ -136,13 +136,12 @@ jobs: # Gitea is always the single source of truth for secret rotation. # Non-secret config lives in infra/observability/obs.env (tracked in git). run: | - mkdir -p /opt/familienarchiv/infra - cp -r infra/observability /opt/familienarchiv/infra/ + mkdir -p /opt/familienarchiv/infra/observability + rsync -a --delete infra/observability/ /opt/familienarchiv/infra/observability/ cp docker-compose.observability.yml /opt/familienarchiv/ cat > /opt/familienarchiv/obs-secrets.env <<'EOF' GRAFANA_ADMIN_PASSWORD=${{ secrets.GRAFANA_ADMIN_PASSWORD }} GLITCHTIP_SECRET_KEY=${{ secrets.GLITCHTIP_SECRET_KEY }} - POSTGRES_USER=archiv POSTGRES_PASSWORD=${{ secrets.STAGING_POSTGRES_PASSWORD }} POSTGRES_HOST=archiv-staging-db-1 EOF @@ -154,6 +153,9 @@ jobs: # Dry-run: resolves all variable substitutions and reports any missing # required keys before containers start. Catches undefined variables and # YAML errors in config files updated by the previous step. + # --env-file order: obs.env first (git-tracked defaults), obs-secrets.env + # second (CI-written secrets). Later files win on duplicate keys, so + # obs-secrets.env overrides POSTGRES_HOST set in obs.env. run: | docker compose \ -f /opt/familienarchiv/docker-compose.observability.yml \ @@ -165,7 +167,8 @@ jobs: # Runs with absolute paths so bind mounts resolve to stable host paths # that survive workspace wipes between nightly runs (see ADR-016). # Non-secret config from obs.env (git-tracked); secrets from obs-secrets.env - # (written fresh from Gitea secrets above). + # (written fresh from Gitea secrets above). --env-file order: obs.env first, + # obs-secrets.env second — later file wins on duplicate keys. run: | docker compose \ -f /opt/familienarchiv/docker-compose.observability.yml \ diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index b180b667..041ffa09 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -104,13 +104,12 @@ jobs: # then writes obs-secrets.env fresh from Gitea secrets. # Non-secret config lives in infra/observability/obs.env (tracked in git). run: | - mkdir -p /opt/familienarchiv/infra - cp -r infra/observability /opt/familienarchiv/infra/ + mkdir -p /opt/familienarchiv/infra/observability + rsync -a --delete infra/observability/ /opt/familienarchiv/infra/observability/ cp docker-compose.observability.yml /opt/familienarchiv/ cat > /opt/familienarchiv/obs-secrets.env <<'EOF' GRAFANA_ADMIN_PASSWORD=${{ secrets.GRAFANA_ADMIN_PASSWORD }} GLITCHTIP_SECRET_KEY=${{ secrets.GLITCHTIP_SECRET_KEY }} - POSTGRES_USER=archiv POSTGRES_PASSWORD=${{ secrets.PROD_POSTGRES_PASSWORD }} POSTGRES_HOST=archiv-production-db-1 EOF @@ -122,6 +121,9 @@ jobs: # Dry-run: resolves all variable substitutions and reports any missing # required keys before containers start. Catches undefined variables and # YAML errors in config files updated by the previous step. + # --env-file order: obs.env first (git-tracked defaults), obs-secrets.env + # second (CI-written secrets). Later files win on duplicate keys, so + # obs-secrets.env overrides POSTGRES_HOST set in obs.env. # Keep in sync with the equivalent step in nightly.yml. run: | docker compose \ @@ -134,7 +136,8 @@ jobs: # Runs with absolute paths so bind mounts resolve to stable host paths # that survive workspace wipes between runs (see ADR-016). # Non-secret config from obs.env (git-tracked); secrets from obs-secrets.env - # (written fresh from Gitea secrets above). + # (written fresh from Gitea secrets above). --env-file order: obs.env first, + # obs-secrets.env second — later file wins on duplicate keys. # Keep in sync with the equivalent step in nightly.yml. run: | docker compose \ diff --git a/infra/observability/obs.env b/infra/observability/obs.env index ace1da3a..1c46a8fe 100644 --- a/infra/observability/obs.env +++ b/infra/observability/obs.env @@ -14,6 +14,8 @@ PORT_PROMETHEUS=9090 GF_SERVER_ROOT_URL=https://grafana.archiv.raddatz.cloud GLITCHTIP_DOMAIN=https://glitchtip.archiv.raddatz.cloud +POSTGRES_USER=archiv + # PostgreSQL hostname for GlitchTip db-init and workers. # The actual value depends on the Compose project name — it is not a fixed string. # CI sets POSTGRES_HOST in obs-secrets.env per environment: