Files
Kenji M 7c4c786e7b zet.home.arpa: document all services and SSL/nginx setup
- Server overview (README.md) with services, storage, and network summary
- Storage layout with disk/fstab/mount details (storage.md)
- Service docs: Samba, NFS, Squid, Pi-hole (with DHCP/split-DNS notes)
- Let's Encrypt cert via acme.sh + GoDaddy DNS-01 (ssl/)
- nginx SSL reverse proxy config and virtual host guide (nginx/)
- Pi-hole moved to port 8081; split DNS overrides documented for both
  Pi-hole and pfSense Unbound to avoid hairpin NAT issues

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 14:37:04 +00:00
..

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 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:

# 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

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

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:

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.