AdGuard Home Setup
Why AdGuard Home?
AdGuard Home was my first "real" service after Portainer. Three main reasons:
- Privacy:
- Local DNS:
- Security:
The eye-opening part
After one week of running AdGuard Home: 254,800 queries, of which 15.7% were blocked. That's roughly 40,000 blocked requests in 7 days — and I noticed zero downsides.
Docker Compose Setup
The Problem: Port 53 Already in Use
When I first tried to start the container, I got this error:
Error response from daemon: failed to bind host port 0.0.0.0:53/tcp: address already in use
Running ss -tulpn | grep :53 revealed the culprit: systemd-resolved
was already listening on port 53.
The solution
Instead of disabling systemd-resolved entirely, I bound AdGuard Home
to my server's LAN IP only. This way:
systemd-resolvedkeeps port 53 on loopback (for the host itself)- AdGuard Home gets port 53 on the LAN interface (for all other devices)
Docker Compose File
services:
adguardhome:
image: adguard/adguardhome
container_name: adguardhome
restart: always
ports:
# Bind to LAN IP only (not 0.0.0.0) to avoid conflict with systemd-resolved
- "192.168.178.<HOST_ID>:53:53/tcp"
- "192.168.178.<HOST_ID>:53:53/udp"
# IPv6 ULA address
- "[fd00::53]:53:53/tcp"
- "[fd00::53]:53:53/udp"
# Web UI for initial setup (keep 80/443 free for Traefik later)
- "3000:3000/tcp"
volumes:
- ./appdata/adguardhome/conf:/opt/adguardhome/conf
- ./appdata/adguardhome/work:/opt/adguardhome/work
logging:
driver: json-file
options:
max-size: "3m"
max-file: "3"
Why Port 3000 for the Web UI?
I kept the admin interface on port 3000 instead of 80/443 because I want to use those ports for Traefik later as a reverse proxy.
Configuration
Upstream DNS Servers
I use privacy-focused, security-enhanced upstream resolvers:
-
Primary:
https://dns.quad9.net/dns-query -
Fallback:
https://security.cloudflare-dns.com/dns-query
Blocklists
My current blocklist setup (total rules: ~594,000):
- AdGuard DNS filter
- HaGeZi's Pro Blocklist
- HaGeZi's Threat Intelligence Feeds
- Phishing URL Blocklist
- HaGeZi's Apple Tracker Blocklist
- HaGeZi's Windows/Office Tracker Blocklist
- Smart-TV Blocklist
A note on blocklists
More rules != better. Overlapping lists waste resources, and overly aggressive lists can break legitimate services. Start with AdGuard DNS filter + HaGeZi Pro, then add specific lists based on your devices.
Network Integration
The Dilemma: 100% Filtering vs. Redundancy
I had two options for integrating AdGuard Home into my network:
Option 1: Server as DNS for all clients
Set the homeserver as the DNS server in router settings (DHCP). All clients get it directly.
Pro:
- 100% of traffic goes through AdGuard
- Per-client statistics
Con:
- If server is down → no DNS → no internet for entire network
Option 2: Router uses AdGuard as upstream (my choice)
Router stays as DNS for clients, but forwards queries to AdGuard Home. External DNS (e.g., Quad9) as fallback.
Pro:
- Redundancy: network works even if server is down
Con:
- All queries appear to come from router IP (no per-client stats)
- Fallback DNS bypasses filtering
My Decision
I chose Option 2. Redundancy matters more to me than perfect statistics (which I don't really care about anyway). If my NUC is down for maintenance, the network shouldn't grind to a halt.
Current DNS path:
Device → Router → AdGuard Home → Quad9/Cloudflare
↘ (fallback) → Quad9 directly
IPv6: A Detour I Didn't Plan
Initially, I wanted to disable IPv6 entirely in my router settings. My reasoning: keep things simple, avoid the complexity of setting up static IPv6 addresses, and prevent clients from potentially bypassing AdGuard Home via IPv6 DNS servers.
However, I had to re-enable IPv6 later when I set up VPN access to my home network. Due to CGNAT (Carrier-Grade NAT), I don't have a static public IPv4 address, which meant I couldn't reliably connect from outside via IPv4. IPv6 was the solution.
This meant I had to configure AdGuard Home properly for IPv6 as well:
- Set a static IPv6 address for the NUC (ULA:
fd00::53) - Configure the router to use the NUC as the primary DNS resolver for both IPv4 and IPv6
- Ensure both address families route through AdGuard Home to maintain filtering coverage
Lessons Learned
- Port conflicts are common:
- Bind to specific IPs:
- Plan for failure:
- Start with fewer blocklists:
- 15% blocked is normal:
What's Next
- [x] Set up local DNS rewrites for
local hostnames - [ ] Integrate with Traefik for HTTPS access to the admin UI
- [x] Document setup