Files
truenas-stacks/pihole
Fizzlepoof 24c6a29273
Some checks failed
secret-guardrails / artifact-secret-scan (push) Has been cancelled
secret-guardrails / gitleaks (push) Has been cancelled
docs: record full Pi-hole retirement
2026-05-27 21:14:15 +00:00
..
2026-05-27 21:14:15 +00:00
2026-05-27 21:14:15 +00:00
2026-05-15 03:17:56 +00:00

PD Pi-hole / Unbound / Keepalived Stack

Historical primary-node stack for the retired Pi-hole HA plan.

  • Repo stack path: /home/fizzlepoof/repos/truenas-stacks/pihole
  • Former live PD stack path: /mnt/docker-ssd/docker/compose/pihole
  • Former node role: PD primary / MASTER
  • Former VIP target: 10.5.30.53/24

Status: retired on 2026-05-27 after cutover to the Technitium trio (10.5.30.8, 10.5.30.9, 10.5.30.10).

This stack intentionally covers the PD primary plus PD-hosted sync:

  • Pi-hole
  • Unbound
  • Keepalived
  • Nebula Sync

NOMAD replica deployment is documented here for historical reference; only the RPi4 replica remains optional future work if you ever revive a separate backup-DNS design.

Files

  • docker-compose.yaml — primary-node stack
  • .env.example — required variables
  • unbound.conf — shared recursive resolver config
  • keepalived.conf.template — rendered into keepalived.conf
  • bin/render_keepalived_conf.py — generates keepalived.conf from .env
  • bin/prepare_pd.sh — creates appdata dirs, downloads root hints, renders config, validates compose, optional --up

First-time setup on PD

cd /mnt/docker-ssd/docker/compose/pihole
cp .env.example .env
nano .env   # set real passwords + verify LAN_INTERFACE
/usr/bin/bash bin/prepare_pd.sh

If that validates cleanly, bring it up:

/usr/bin/bash bin/prepare_pd.sh --up

Retired topology snapshot

  • PD primary
    • service root: /mnt/docker-ssd/docker/compose/pihole
    • Pi-hole container: pihole-primary
    • Unbound container: unbound-pihole-primary
    • Keepalived container: keepalived-pihole-primary
    • Nebula Sync container: nebula-sync
    • LAN admin URL: http://10.5.30.6:8953/admin/
  • NOMAD backup
    • service root: /opt/pihole-nomad
    • Pi-hole container: pihole-nomad
    • Unbound container: unbound-pihole-nomad
    • Keepalived container: keepalived-pihole-nomad (staged, disabled by default)
    • LAN admin URL: http://10.5.30.7:8954/admin/
  • VIP for client DNS: 10.5.30.53
  • Shared Pi-hole admin password: stored in the local .env files; Nebula and both nodes use the same current value.

Important notes

  • This stack is no longer live. Keep it only as a historical build/repair reference.
  • KEEPALIVED_PASSWORD must be 8 chars or fewer because VRRP PASS auth is annoying and old.
  • Verify LAN_INTERFACE on PD before deployment (ip link show).
  • FTLCONF_dns_listeningMode=LOCAL is set because TrueNAS binds loopback on port 53.
  • Pi-hole NTP is explicitly disabled here because PD host chronyd already owns UDP 123.
  • Nebula Sync runs on PD and uses NEBULA_SYNC_PRIMARY / NEBULA_SYNC_REPLICAS from .env.
  • Current replica target is NOMAD at http://10.5.30.7:8954.
  • NOMAD no longer participates in the old Trusted-side 10.5.30.53/24 Keepalived VIP after moving to Servers VLAN. Re-enable Keepalived there only after a same-subnet HA design exists.
  • Nebula Sync is intentionally set to selective mode with gravity sync toggles enabled for groups, adlists, and domain lists so replica-specific runtime/network settings are not clobbered.
  • keepalived.conf is generated and should stay local/untracked.