# Pi-hole — zet.home.arpa Network-wide DNS ad blocker and DHCP server. Runs as a Docker container. ## Overview | Field | Value | |-------|-------| | **Image** | `pihole/pihole:latest` | | **Container name** | `pihole` | | **Compose file** | `/home/kenjim/docker-pi-hole/docker-compose.yml` | | **Config directory** | `/home/kenjim/docker-pi-hole/` | | **Restart policy** | `always` | | **Timezone** | `America/Chicago` | ## Versions (as of 2026-06-19) | Component | Running | Latest | |-----------|---------|--------| | Core | v6.1.4 | v6.4.2 | | Web | v6.2.1 | v6.5.1 | | FTL | v6.2.3 | v6.6.2 | **Updates are available** — see [Upgrading](#upgrading) below. ## Ports | Port | Protocol | Purpose | Accessible from | |------|----------|---------|-----------------| | 53 | TCP + UDP | DNS | LAN (pfSense points clients here) | | 67 | UDP | DHCP | LAN only (broadcast, not routable to WAN) | | 8081 | TCP | Web admin UI | LAN only (pfSense does not forward this port) | **Admin UI**: `http://172.27.0.35:8081/admin` ## Role: DHCP Server for Untrusted Devices Pi-hole acts as the DHCP server for untrusted LAN devices — Alexa/Echo devices, IoT, and children's machines. By serving DHCP, Pi-hole automatically assigns itself as the DNS server for those clients, ensuring DNS-level ad/content blocking applies without any per-device configuration. pfSense should have its own DHCP server **disabled** (or scoped to a different subnet/VLAN) for any segment where Pi-hole is authoritative for DHCP, to avoid conflicts. ### DHCP + Docker caveat Pi-hole's own docs recommend `network_mode: host` for reliable DHCP from Docker (broadcast packets don't traverse Docker NAT cleanly). The current setup uses port mappings + `NET_ADMIN` capability instead, which works in practice. If DHCP stops responding after a container restart or image upgrade, switching to host networking is the fix: ```yaml # Alternative compose config if DHCP becomes unreliable: services: pihole: network_mode: host # replaces all port: mappings # remove the ports: section entirely # admin UI returns to port 80, but WAN can't reach it # since pfSense won't forward port 80 to this host ``` ## Volume Mounts | Host path | Container path | Contents | |-----------|----------------|----------| | `./etc-pihole` | `/etc/pihole` | Pi-hole config, gravity DB, DHCP leases | | `./etc-dnsmasq.d` | `/etc/dnsmasq.d` | Custom DNS/DHCP overrides | Both paths are relative to `/home/kenjim/docker-pi-hole/`. ## docker-compose.yml ```yaml version: "3" services: pihole: container_name: pihole image: pihole/pihole:latest ports: - "53:53/tcp" - "53:53/udp" - "67:67/udp" - "8081:80/tcp" environment: TZ: 'America/Chicago' FTLCONF_MAXCONCURRENTQUERIES: 300 volumes: - './etc-pihole:/etc/pihole' - './etc-dnsmasq.d:/etc/dnsmasq.d' cap_add: - NET_ADMIN restart: always ``` ## Service Management ```bash cd ~/docker-pi-hole docker compose up -d # start docker compose down # stop docker compose pull && docker compose up -d # update image docker compose logs -f pihole # follow logs # Run pihole commands inside container docker exec pihole pihole status docker exec pihole pihole -g # update gravity (blocklists) docker exec pihole pihole version ``` ## Upgrading Pi-hole updates are released as new Docker image versions: ```bash cd ~/docker-pi-hole docker compose pull # pull latest image docker compose up -d # recreate container docker exec pihole pihole version # verify new version ``` The volumes (`etc-pihole/`, `etc-dnsmasq.d/`) persist config across upgrades. ## Migration Notes To move Pi-hole to a new server: 1. Stop the container: `docker compose down` 2. Copy the entire `/home/kenjim/docker-pi-hole/` directory to the new host 3. Install Docker on the new host 4. Run `docker compose up -d` from the copied directory 5. Update pfSense DNS server setting to point to the new host IP Key data to preserve: - `etc-pihole/gravity.db` — blocklists - `etc-pihole/dhcp.leases` — DHCP lease table - `etc-pihole/pihole.toml` — main config (v6+ format) - `etc-pihole/local.list` — local DNS overrides - `etc-dnsmasq.d/` — custom dnsmasq config ## Network Integration Pi-hole is one of two DNS resolvers on the LAN — some devices use Pi-hole (`172.27.0.35:53`), others use pfSense's built-in Unbound resolver directly. ## Split DNS — Local Overrides To avoid hairpin NAT issues (LAN clients connecting to the public WAN IP for local services), DNS overrides are configured in **both** resolvers so that `kenjim.com` subdomains resolve directly to `172.27.0.35` from inside the LAN. ### Pi-hole (Local DNS → DNS Records) | Domain | IP | |--------|----| | `git.kenjim.com` | `172.27.0.35` | | `www.kenjim.com` | `172.27.0.35` | | `kenji.kenjim.com` | `172.27.0.35` | ### pfSense DNS Resolver (Services → DNS Resolver → Host Overrides) Same three entries as above — covers clients that use pfSense Unbound instead of Pi-hole. Without these overrides, LAN clients resolving `git.kenjim.com` get the public WAN IP and connect to pfSense's own HTTPS interface rather than nginx on zet.