Skip to main content

How to Self-Host AdGuard Home: DNS Ad Blocker (Pi-hole Alternative) 2026

·OSSAlt Team
adguard-homednsad-blockerprivacyself-hostingdocker2026

TL;DR

AdGuard Home (GPL 3.0, ~24K GitHub stars, Go) is a network-wide DNS ad and tracker blocker — every device on your network (phone, TV, smart home) gets ads blocked without installing anything per-device. Compare AdGuard Home vs Pi-hole: AdGuard Home has a better UI, built-in DNS-over-HTTPS/TLS, per-client rules, and parental controls; Pi-hole has a larger community and more integrations. Both work. AdGuard Home wins for new installs in 2026.

Key Takeaways

  • AdGuard Home: GPL 3.0, ~24K stars — network-wide DNS blocker, better than Pi-hole UI
  • DNS-over-HTTPS/TLS: Built-in encrypted DNS server (no need for external dnscrypt-proxy)
  • Per-device rules: Allow YouTube on the TV but block it everywhere else
  • Parental controls: Block adult content or specific categories by device
  • DHCP server: Can replace your router's DHCP (assigns DNS automatically)
  • Statistics: Detailed query logs, blocked per domain, per client

AdGuard Home vs Pi-hole

FeatureAdGuard HomePi-hole
LicenseGPL 3.0EUPL 1.2
GitHub Stars~24K~48K
LanguageGoPHP + Python
UIModern, polishedFunctional
DNS-over-HTTPSBuilt-inVia dnscrypt-proxy
DNS-over-TLSBuilt-inVia Unbound
Per-client rulesYesLimited (groups)
Parental controlsYesVia external lists
DHCP serverYesYes
Regex blockingYesYes
RAM~30MB~150MB
Raspberry PiYesYes (default)

Part 1: Docker Setup

# docker-compose.yml
services:
  adguardhome:
    image: adguard/adguardhome:latest
    container_name: adguardhome
    restart: unless-stopped
    network_mode: host    # Required for DNS (port 53)
    volumes:
      - adguard_work:/opt/adguardhome/work
      - adguard_conf:/opt/adguardhome/conf
    # network_mode: host means ports aren't mapped here

volumes:
  adguard_work:
  adguard_conf:
docker compose up -d

Visit http://your-server:3000 → setup wizard.


Without Host Networking (if port 53 is taken)

services:
  adguardhome:
    image: adguard/adguardhome:latest
    restart: unless-stopped
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "3000:3000/tcp"    # Admin UI
      - "80:80/tcp"        # HTTP
      - "443:443/tcp"      # HTTPS
      - "853:853/tcp"      # DNS-over-TLS
    volumes:
      - adguard_work:/opt/adguardhome/work
      - adguard_conf:/opt/adguardhome/conf

If port 53 is in use (systemd-resolved on Ubuntu):

# Disable systemd-resolved's DNS stub:
sudo sed -i 's/#DNSStubListener=yes/DNSStubListener=no/' /etc/systemd/resolved.conf
sudo systemctl restart systemd-resolved

Part 2: HTTPS Web UI with Caddy

adguard.yourdomain.com {
    reverse_proxy localhost:3000
}

Part 3: Setup Wizard

  1. Visit http://your-server:3000
  2. Set admin username and password
  3. Set listen interfaces
  4. Finish setup

Then visit http://your-server:3000/install or the main dashboard.


Part 4: Point Your Network at AdGuard Home

Option A: Router DNS (Entire Network)

Log into your router → DHCP settings → Set DNS server to your AdGuard Home IP:

DNS Server 1: 192.168.1.X   (your server's LAN IP)
DNS Server 2: 1.1.1.1       (Cloudflare as fallback)

Every device that uses DHCP now uses AdGuard Home for DNS.

Option B: Per-Device DNS

Configure specific devices to use your server's IP as DNS:

# macOS:
# System Preferences → Network → Advanced → DNS → add your server IP

# iPhone:
# Settings → Wi-Fi → [Network] → Configure DNS → Manual → add IP

# Linux:
# /etc/resolv.conf or systemd-resolved configuration

Option C: AdGuard Home as DHCP Server

Replace your router's DHCP with AdGuard Home:

  1. Settings → DHCP → Enable DHCP server
  2. Set IP range, gateway, DNS (itself: 192.168.1.X)
  3. Disable DHCP on your router

Every device auto-receives AdGuard Home as DNS.


Part 5: Blocklists

Settings → Filters → Blocklists → Add Blocklist

Recommended lists:

AdGuard DNS filter (built-in — good default)
https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts   # Steven Black's combined list
https://raw.githubusercontent.com/hagezi/dns-blocklists/main/adblock/pro.txt  # HaGeZi Pro
https://adaway.org/hosts.txt                                         # Mobile ads
https://raw.githubusercontent.com/DandelionSprout/adfilt/master/GameConsoleAdblockList.txt  # Gaming

After adding lists: Settings → Filters → Update Now

Custom block rules:

# /etc/adguardhome/conf/AdGuardHome.yaml
# Or in the UI: Filters → Custom Filtering Rules

# Block a domain:
||analytics.example.com^

# Allow a domain (override blocklist):
@@||youtube.com^$important

# Block all subdomains:
||*.ads.example.com^

# Regex block:
/tracking|analytics|telemetry/

Part 6: DNS-over-HTTPS (DoH)

Enable encrypted DNS for privacy:

  1. Settings → Encryption → Enable HTTPS / DNS-over-HTTPS
  2. Add your domain certificate (or let AdGuard use Let's Encrypt)
  3. DoH URL: https://adguard.yourdomain.com/dns-query

Configure on clients:

  • iOS 14+: Settings → Wi-Fi → DNS → DNS-over-HTTPS
  • Firefox: Network Settings → Enable DNS-over-HTTPS → Custom → your URL
  • macOS: .mobileconfig profile installation

Or use DNS-over-TLS on port 853: adguard.yourdomain.com:853


Part 7: Per-Client Rules

Set different rules for different devices:

  1. Client Settings → + Add Client
  2. Identify by: MAC address, IP, or client name (from DHCP)
  3. Per-client settings:
    • Use custom upstreams: Point to a different DNS resolver
    • Safe search: Force safe search on Google/YouTube
    • Parental control: Block adult content categories
    • Custom filter rules: Allow/block specific domains only for this device

Example setup:

TV (192.168.1.10): Block social media, allow streaming services
Kids' iPad (MAC: AA:BB:CC:DD:EE:FF): Parental control: on, safe search: on
Work laptop: No restrictions

Part 8: Query Log and Statistics

Dashboard → Statistics:

  • Total DNS queries per day
  • % blocked
  • Top blocked domains
  • Top clients by query count
  • Top queried domains

Query Log → Filter by client, status, domain:

# Find what a specific device is querying:
Filter: client = 192.168.1.15

# Find all blocked queries:
Filter: status = blocked

# Find if a domain was blocked or allowed:
Filter: domain = analytics.google.com

Maintenance

# Update AdGuard Home:
docker compose pull
docker compose up -d

# Logs:
docker compose logs -f adguardhome

# Backup config:
tar -czf adguard-config-$(date +%Y%m%d).tar.gz \
  $(docker volume inspect adguardhome_adguard_conf --format '{{.Mountpoint}}')

# Update blocklists:
# Filters → Update Now (or set auto-update schedule)

# Check DNS resolution:
dig @192.168.1.X ads.google.com    # Should return 0.0.0.0
dig @192.168.1.X google.com         # Should return real IP

See all open source privacy and networking tools at OSSAlt.com/categories/privacy.

Comments