# PD Pi-hole / Unbound / Keepalived Stack Primary-node stack for the Pi-hole HA plan. - **Repo stack path:** `/home/fizzlepoof/repos/truenas-stacks/pihole` - **Live PD stack path:** `/mnt/docker-ssd/docker/compose/pihole` - **Node role:** PD primary / MASTER - **VIP target:** `10.5.1.53/24` This stack intentionally covers the **PD primary** plus PD-hosted sync: - Pi-hole - Unbound - Keepalived - Nebula Sync NOMAD replica deployment is now documented and live; only the RPi4 replica remains future work. ## 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 ```bash 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: ```bash /usr/bin/bash bin/prepare_pd.sh --up ``` ## Current live topology - **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.1.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` - LAN admin URL: `http://10.5.1.16:8954/admin/` - **VIP for client DNS:** `10.5.1.53` - **Shared Pi-hole admin password:** stored in the local `.env` files; Nebula and both nodes use the same current value. ## Important notes - `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.1.16:8954`. - 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.