🛡️ AdGuard Home — Network‑wide DNS blocking (Docker)
AdGuard Home is a DNS resolver and blocker that removes ads, trackers and malware domains for your whole network. This document shows a clear Docker Compose setup for Raspberry Pi, how to configure volumes and ports, recommended settings, backup/update procedures and troubleshooting tips.
✅ Prerequisites
- Raspberry Pi with Docker & Docker Compose installed
- Administrative access to your router (to change DHCP/DNS) or ability to set DNS per client
- Basic knowledge of Docker and networking
- Optional: a domain and reverse proxy (for secure web UI via HTTPS)
Quick overview
- AdGuard Home listens on port 53 (DNS) and provides a web UI on port 3000 by default.
- Deploy on host networking for simplest DNS handling, or map ports when using bridge mode.
- Persist configuration to a host directory so settings survive container upgrades.
Example Docker Compose (recommended)
Place this in a project folder (e.g. ~/docker/adguardhome) as docker-compose.yml. The example uses environment variables commonly defined in a .env file.
services:
adguardhome:
container_name: ${CONTAINER_PREFIX}adguardhome
image: adguard/adguardhome:latest
restart: ${RESTART_POLICY:-unless-stopped}
network_mode: "${NETWORK_MODE:-bridge}" # use "host" for easiest DNS handling
ports:
- "53:53/udp" # DNS
- "53:53/tcp" # DNS over TCP
- "80:80/tcp" # web UI (HTTP) - optional if using reverse proxy
- "443:443/tcp" # web UI (HTTPS) - optional if not using reverse proxy
- "3000:3000/tcp" # AdGuard Home admin UI (default)
volumes:
- ${CONFIG_PATH:-./config}/adguardhome/conf:/opt/adguardhome/conf
- ${CONFIG_PATH:-./config}/adguardhome/work:/opt/adguardhome/work
environment:
- TZ=${TZ:-UTC}
Notes:
- If you set
network_mode: "host", you do not need to map port 53; the container will bind directly to host network interfaces. Host mode is recommended for DNS servers on a Pi. ${CONFIG_PATH}should be a persistent folder on the host (e.g.~/docker/appdata/adguardhome).- Keep
${CONTAINER_PREFIX},${TZ}and${RESTART_POLICY}in a.envfile in the same folder (not checked into git).
Example .env:
CONTAINER_PREFIX=gh_
CONFIG_PATH=/home/pi/docker/appdata
TZ=Europe/Oslo
RESTART_POLICY=unless-stopped
NETWORK_MODE=host
Secure .env:
chmod 600 .env
Initial setup and first run
- Create directories and files:
mkdir -p ~/docker/appdata/adguardhome/{conf,work}
cd ~/docker/appdata/adguardhome
# create .env as above
nano docker-compose.yml - Start:
docker compose up -d - Open the web UI:
- If mapped: http://PI-IP:3000 (or 3000 may be redirected to 80/443 depending on image version)
- If host mode and default ports: http://PI-IP:3000 or http://PI-IP:80 (check container logs)
- Follow the web installer to set admin password, upstream DNS and blocking lists.
Recommended AdGuard settings
- Upstream DNS: use reliable providers (Cloudflare 1.1.1.1, Google 8.8.8.8, Quad9, or DNS-over-HTTPS providers).
- Filters: enable default ad/tracker lists, and optionally regional lists.
- DNS-over-HTTPS/TLS: enable for upstream privacy if supported.
- DHCP: keep DHCP on router unless you want Pi to serve DHCP — enabling DHCP on AdGuard requires disabling router DHCP and careful configuration.
DNS deployment options
- Router DHCP: configure router to hand out the Pi’s IP as primary DNS. Clients will then use AdGuard Home automatically.
- Per-client DNS: set DNS manually on devices if you cannot change router settings.
- Host networking: simplest on Pi — run AdGuard with
network_mode: hostto avoid port mapping quirks.
Reverse proxy & HTTPS
- If you want a public or TLS‑secured admin UI, put AdGuard behind a reverse proxy (nginx, Traefik) and obtain a certificate (Let's Encrypt).
- When using a reverse proxy, avoid exposing ports 80/443 from the AdGuard container (bind to localhost or disable).
Example: do not map 80/443 in compose when using a reverse proxy; route the proxy to the container's admin socket or to port 3000.
Backup & restore
Backup config and state directories:
cd ~/docker/appdata
tar czf adguardhome-backup-$(date +%F).tar.gz adguardhome
To restore, stop the container, extract archive and start container again. Test in staging first.
Update procedure
- Pull new image and restart:
docker compose pull adguardhome
docker compose up -d - Verify settings and logs:
docker logs -f ${CONTAINER_PREFIX}adguardhome
Because data persists in host volumes, upgrades are generally safe. Still, take a backup before major upgrades.
Troubleshooting
- Port 53 already in use: stop any local DNS (Pi-hole, systemd-resolved) or run AdGuard in host mode and ensure nothing else binds port 53. Use
ss -ulpn | grep :53. - DNS resolving fails: check AdGuard upstream DNS configuration and that the container can reach the internet. Inspect logs.
- Web UI unreachable: confirm mapped port (3000) or reverse proxy settings, and check
docker logs. - High CPU or memory: check filter lists, query logs and client load. Consider a more powerful device for heavy networks.
Useful commands:
docker ps -a
docker logs -f ${CONTAINER_PREFIX}adguardhome
docker compose down
docker compose up -d
Security & privacy notes
- Keep the admin password strong and enable HTTPS via reverse proxy for external access.
- Limit external exposure: ideally, do not expose the admin UI to the internet. Use VPN or SSH tunnel if remote access is required.
- Be mindful of DNS logging; AdGuard can log client queries — configure retention according to privacy needs.
Optional: Advanced topics
- DNS-over-HTTPS (DoH) and DNS-over-TLS (DoT) upstreams for privacy.
- Client filtering and per-client rules (useful to whitelist development devices).
- Conditional forwarding for local domains (forward queries for local LAN names to your router).
- Integrate with Pi-hole or replace Pi-hole entirely — choose one DNS filter solution per network to avoid conflicts.
AdGuard Home running in Docker on a Raspberry Pi gives network‑wide ad and tracker blocking with a small resource footprint. Persist configuration, secure access, and route client DNS queries to the Pi for the best experience.