01Why Run Local DNS?
Pi-hole and AdGuard Home are both excellent choices. Pi-hole has more community blocklists; AdGuard has a more modern UI and built-in DoH/DoT.
02Pi-hole Setup
1services: 2 pihole: 3 image: pihole/pihole:latest4 container_name: pihole5 hostname: pihole6 environment: 7 - TZ=Europe/London8 - WEBPASSWORD=${PIHOLE_PASSWORD}9 # Use Cloudflare DNS upstream10 - PIHOLE_DNS_=1.1.1.1;1.0.0.111 - DNSSEC=true12 - QUERY_LOGGING=true13 volumes: 14 - ./pihole/etc-pihole:/etc/pihole15 - ./pihole/etc-dnsmasq.d:/etc/dnsmasq.d16 ports: 17 - "53:53/tcp"18 - "53:53/udp"19 - "8053:80/tcp" # Web UI20 cap_add: 21 - NET_ADMIN # Required for DHCP (optional)22 restart: unless-stopped2324# Access web UI at http://your-server:8053/adminPort 53 may conflict with systemd-resolved on Linux. Disable it first: sudo systemctl disable --now systemd-resolved
03AdGuard Home Setup
1services: 2 adguard: 3 image: adguard/adguardhome:latest4 container_name: adguard5 environment: 6 - TZ=Europe/London7 volumes: 8 - ./adguard/work:/opt/adguardhome/work9 - ./adguard/conf:/opt/adguardhome/conf10 ports: 11 - "53:53/tcp"12 - "53:53/udp"13 - "3000:3000/tcp" # Initial setup UI14 - "8080:80/tcp" # Web UI after setup15 - "443:443/tcp" # HTTPS (optional)16 - "853:853/tcp" # DNS-over-TLS17 restart: unless-stopped1819# First run: access http://your-server:3000 for setup wizard20# After setup: http://your-server:8080AdGuard Home's first-run wizard configures everything. Choose your admin credentials and upstream DNS servers during setup.
04Adding Local DNS Records
1# Pi-hole: Add via command line or /etc/pihole/custom.list2# Format: IP HOSTNAME3192.168.1.50 nextcloud.home4192.168.1.50 jellyfin.home5192.168.1.50 homeassistant.home6192.168.1.51 nas.home78# Or add via dnsmasq config (/etc/dnsmasq.d/custom.conf)9address=/home/192.168.1.50 # All *.home goes to this IP10address=/nextcloud.local/192.168.1.501112# AdGuard: Configure in the web UI under Filters → DNS rewrites13# Or edit AdGuardHome.yaml:14filtering:15 rewrites:16 - domain: "*.home"17 answer: 192.168.1.5005Combining with Reverse Proxy
1services: 2 # DNS - points *.home to this server3 pihole: 4 image: pihole/pihole:latest5 volumes: 6 - ./pihole:/etc/pihole7 - ./dnsmasq:/etc/dnsmasq.d8 ports: 9 - "53:53/tcp"10 - "53:53/udp"11 - "8053:80"1213 # Reverse Proxy - handles *.home requests14 traefik: 15 image: traefik:v3.016 command: 17 - --providers.docker=true18 - --entrypoints.web.address=:8019 ports: 20 - "80:80"21 volumes: 22 - /var/run/docker.sock:/var/run/docker.sock:ro2324 # Service with automatic routing25 nextcloud: 26 image: nextcloud:latest27 labels: 28 - "traefik.enable=true"29 - "traefik.http.routers.nextcloud.rule=Host(`nextcloud.home`)"30 volumes: 31 - ./nextcloud:/var/www/htmlAdd 'address=/home/192.168.1.50' to dnsmasq to route ALL *.home domains to your Docker host.
06DHCP Integration
1# Pi-hole with DHCP enabled2services: 3 pihole: 4 image: pihole/pihole:latest5 environment: 6 - PIHOLE_DNS_=1.1.1.1;1.0.0.17 - WEBPASSWORD=${PIHOLE_PASSWORD}8 # Enable DHCP9 - DHCP_ACTIVE=true10 - DHCP_START=192.168.1.10011 - DHCP_END=192.168.1.20012 - DHCP_ROUTER=192.168.1.113 volumes: 14 - ./pihole:/etc/pihole15 - ./dnsmasq.d:/etc/dnsmasq.d16 ports: 17 - "53:53/tcp"18 - "53:53/udp"19 - "67:67/udp" # DHCP20 - "8053:80"21 cap_add: 22 - NET_ADMIN # Required for DHCP23 network_mode: host # Recommended for DHCPNever run two DHCP servers on the same network. Disable your router's DHCP before enabling it in Pi-hole/AdGuard.
07Managing Blocklists
1# Pi-hole: Add blocklists via web UI or gravity command2pihole -g # Update blocklists34# Popular blocklist URLs to add:5# https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts6# https://dbl.oisd.nl/7# https://v.firebog.net/hosts/lists.php?type=tick89# Whitelist domains10pihole -w s.youtube.com11pihole -w cdn.optimizely.com1213# AdGuard: Add via Filters → DNS Blocklists14# Or edit AdGuardHome.yaml:15filters:16 - enabled: true17 url: https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt18 name: AdGuard DNS filterStart with fewer blocklists and add more gradually. The OISD list is a great single list that balances blocking with compatibility.