Prerequisite for running more than one PiHole replica. A second replica with a fresh PVC would have come up serving DNS and blocking nothing, with a different admin password -- answers varying by which pod replied. pihole.toml's own ### CHANGED markers gave the exact inventory: four settings already came from env (declared), one came from the image, and exactly ONE operator-set value lived only on the PVC -- webserver.api.pwhash, a one-way hash nobody could recover. Separately the adlists were undeclared: one list and 72,234 gravity domains that nothing in this repo named. Declares both: - A SOPS secret feeding FTLCONF_webserver_api_password. webserver.api.password takes cleartext and FTL hashes it itself (verified: pihole setpassword IS setFTLConfigValue on that key), so the PVC's pwhash becomes derived state. - A level-triggered postStart hook that reconciles the declared adlist set into gravity.db -- adds, re-enables, and disables (never deletes) undeclared lists, running pihole -g only when something moved. A file would not work: v6's adlists.list import is migration-only, guarded on the DB not existing. The rendered hook was run in the live pod against throwaway copies of gravity.db, exercising all four paths. A fresh DB built from the image's own schema template has ZERO adlists, confirming this is load-bearing rather than cosmetic. Password kept rather than set empty: the pihole Service still publishes port 80 past the oauth2-proxy, closed only by policy, and default-deny has drifted here before. Multi-replica is phase 2 and deliberately not in this branch -- it needs a schema field, a StatefulSet (the config PVC is RWO), anti-affinity and a PDB. Adds a *.sops.yaml -- a sensitive path -- so approval-policy will block pending an operator /approve-override. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
31 lines
1.1 KiB
YAML
31 lines
1.1 KiB
YAML
---
|
|
# Wave 0 of the app tier — GENERATED by `catalog/render.py --emit-waves`.
|
|
# Reconciled by the Flux Kustomization `apps-wave-0` (clusters/base/apps-wave-0.yaml), which dependsOn `platform-config` and health-gates
|
|
# (wait:true) ONLY this wave — a crashloop here cannot stall an earlier wave.
|
|
# DO NOT hand-edit: re-run `render.py --emit-waves` after onboarding a service.
|
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
resources:
|
|
- gitea-bootstrap-secret.sops.yaml
|
|
- gitea.yaml
|
|
- jackett-oauth2-proxy-credentials.sops.yaml
|
|
- jackett.yaml
|
|
- nextcloud-db-app.sops.yaml
|
|
- nextcloud-db-backup-credentials-prod.sops.yaml
|
|
- nextcloud-db-backup-credentials.sops.yaml
|
|
- nextcloud-db.yaml
|
|
- pihole-bootstrap-secret.sops.yaml
|
|
- pihole-dns.yaml
|
|
- pihole-oauth2-proxy-credentials.sops.yaml
|
|
- pihole.yaml
|
|
- plex-claim-secret.sops.yaml
|
|
- plex-remote.yaml
|
|
- plex.yaml
|
|
- qbittorrent-bootstrap-secret.sops.yaml
|
|
- qbittorrent-oauth2-proxy-credentials.sops.yaml
|
|
- qbittorrent.yaml
|
|
- semaphore-db-app.sops.yaml
|
|
- semaphore-db-backup-credentials-prod.sops.yaml
|
|
- semaphore-db-backup-credentials.sops.yaml
|
|
- semaphore-db.yaml
|