Installed April 19, 2026 on CT102 at 192.168.8.53. Serves DNS + ad blocking to the entire LAN and all NetBird peers.
| Container | CT102 pihole |
| IP | 192.168.8.53 |
| Version | Pi-hole v6.4.1 (FTL 6.6, Web 6.5) |
| Upstream DNS | Unbound on CT100 (192.168.8.100:5335, primary recursive resolver) + Cloudflare (1.1.1.1) + Quad9 (9.9.9.9) as fallbacks |
| Blocklists | StevenBlack unified (87,771 domains) |
| Admin UI | https://pihole.edmd.me (alias: dns.edmd.me) |
| Raw admin | http://192.168.8.53/admin/ |
| Container root password | /root/pihole-root-password.txt on Proxmox |
| Web admin password | /root/pihole-admin-password.txt on Proxmox |
- All LAN devices โ router’s DHCP hands out
192.168.8.53as primary DNS - All NetBird peers โ NetBird web UI โ Networks โ Nameservers โ
192.168.8.53registered
Any device connected to home wifi OR to the NetBird mesh gets ad blocking + short names automatically. No per-device config.
Pi-hole resolves friendly short names for every major LAN service. Adds both bare and .home variants.
Infrastructure: hpve, proxmox, ct100, docker-host, ct101, immich, studio, mac-studio, pihole, vps, edge01
Services (all on CT100 at 192.168.8.100): portainer, plex, calibre, lidarr, sonarr, radarr, prowlarr, bookshelf, audiobookshelf, navidrome, n8n, kuma, uptime-kuma, gotify, freshrss, homepage, convertx, readarr, shelfmark, paperless, paperless-ai
Farm network: farm-pve (192.168.0.191), ha / home-assistant (192.168.0.10), slzb (192.168.0.16)
Bare names (no suffix) work from NetBird peers because they append
.netbird.cloudas a search domain. For LAN devices where the router drops bare names, use.homesuffix โ e.g.http://portainer.home:9443. For real HTTPS with clean URLs, use.edmd.mevia Caddy on CT103 โ e.g.https://portainer.edmd.me.
Resolution chain: Client โ Router (192.168.8.1) โ Pi-hole (CT102, 192.168.8.53) โ Unbound (CT100, 192.168.8.100:5335) โ root servers
Unbound is a recursive resolver running as a Docker container on CT100 (mvance/unbound). It resolves queries directly from the DNS root servers rather than forwarding to Cloudflare or Quad9 โ this means no single upstream provider sees all your DNS queries. Pi-hole uses Unbound as its primary upstream with Cloudflare (1.1.1.1) and Quad9 (9.9.9.9) configured as fallbacks.
Config: Custom unbound.conf mounted at /opt/unbound/conf/unbound.conf (overrides the image’s auto-generated config). Key settings: msg-cache-size: 50m, rrset-cache-size: 100m, num-threads: 2, log-servfail: yes, verbosity: 1. DNSSEC validation enabled.
May 10 2026 fix: The mvance/unbound Docker image auto-calculates cache sizes from the host’s total RAM. Running inside a memory-limited LXC container (CT100), it was allocating ~33GB for DNS caching, causing periodic OOM and SERVFAIL responses. Pi-hole cached those SERVFAILs instead of falling back to working upstreams. The old health check (drill @127.0.0.1 google.com) was useless because SERVFAIL counted as a valid response. Fixed by:
- Mounting a custom
unbound.confwith sane cache sizes - Updating the Docker health check to verify
NOERRORstatus:drill @127.0.0.1 google.com | grep -q 'NOERROR' - Enabling
log-servfail: yesandverbosity: 1for future debugging - Flushing Pi-hole’s cached SERVFAILs via
systemctl restart pihole-FTL
Add a new short-name DNS record โ use the web UI (Settings โ Local DNS โ DNS Records) or the API:
# From Proxmox host
ADMIN_PW=$(cat /root/pihole-admin-password.txt)
SID=$(curl -sk -X POST http://192.168.8.53/api/auth \
-H "Content-Type: application/json" \
-d "{\"password\":\"$ADMIN_PW\"}" | grep -oE '"sid":"[^"]+"' | cut -d'"' -f4)
curl -sk -X PUT "http://192.168.8.53/api/config/dns/hosts/192.168.8.100%20newservice?sid=$SID"
Update blocklists โ web UI โ Gravity โ “Update”
Or CLI from within the container:
pct exec 102 -- pihole -g
View query log โ web UI โ Query Log
Or from container: tail -f /var/log/pihole/pihole.log
Reload after config changes โ pct exec 102 -- pihole reloaddns
- Pi-hole v6 uses embedded FTL as web server (NOT lighttpd โ unlike v5). Port 80 and 443 handled by pihole-FTL.
- v6 migrated from
setupVars.confto/etc/pihole/pihole.toml. - Custom DNS records live at
/etc/pihole/hosts/custom.listbut Pi-hole v6 regenerates this file on some config changes. Use the admin UI or API to add records โ do not edit the file directly. - Loading custom dnsmasq directives โ set
misc.etc_dnsmasq_d = trueinpihole.toml, then drop config into/etc/dnsmasq.d/. The*.edmd.mewildcard (/etc/dnsmasq.d/03-edmd-wildcard.confโaddress=/edmd.me/192.168.8.54) is loaded this way. NOTE: whenetc_dnsmasq_d=false(the default), files in/etc/dnsmasq.d/are silently ignored. We’ve changed our default totrueafter the Apr 29 cutover. - The
bogusPriv=truesetting inpihole.tomlrejects RFC1918 answers from upstream โ but does NOT affect locally-configured wildcards in/etc/dnsmasq.d/. So the wildcard works even withbogusPrivon. .netbird.cloudnames are NOT resolved by Pi-hole โ NetBird client intercepts those on each peer locally. Don’t try to forward.netbird.cloudfrom Pi-hole (CT102 can’t reach NetBird’s internal DNS at 100.123.31.199 because CT102 isn’t a NetBird peer).