AdGuard Home Setup: Deploy a Network-Wide Ad Blocker via Docker

Take control of your network traffic. Deploy AdGuard Home on a VPS with Docker Compose to block advertisements and trackers at the DNS level.

Prerequisites and Port Requirements

Before deploying AdGuard Home, ensure your VPS has Docker and Docker Compose installed. Additionally, verify that the following ports are open in your cloud provider's firewall (security group) and host firewall (e.g., UFW):

Port Protocol Service Required For
53 TCP/UDP DNS Plain DNS resolution
80 TCP HTTP Admin panel setup / Let's Encrypt validation
443 TCP/UDP HTTPS / HTTP/3 DNS-over-HTTPS (DoH) & secure admin panel
853 TCP DNS-over-TLS (DoT) Encrypted DoT client connections
853 UDP DNS-over-QUIC (DoQ) Encrypted DoQ client connections
3000 TCP HTTP Initial setup wizard

Step 1: Resolving the systemd-resolved Conflict

Most modern Linux VPS distributions (like Ubuntu and Debian) run systemd-resolved, which binds to port 53 on the loopback interface (127.0.0.53). This prevents AdGuard Home from binding to port 53.

To disable systemd-resolved's DNS stub listener:

  1. Open /etc/systemd/resolved.conf in an editor: bash sudo nano /etc/systemd/resolved.conf
  2. Uncomment or add the line DNSStubListener=no: ini [Resolve] #DNS= #FallbackDNS= #Domains= #LLMNR=no #MulticastDNS=no #DNSSEC=no #DNSOverTLS=no #Cache=no-negative DNSStubListener=no
  3. Symlink /etc/resolv.conf to a static file to ensure local DNS resolution still works: bash sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
  4. Restart the service: bash sudo systemctl restart systemd-resolved

Step 2: Creating the Docker Compose Configuration

Create a dedicated directory for AdGuard Home and construct the docker-compose.yml file.

mkdir -p ~/adguardhome && cd ~/adguardhome

Define the service configuration in docker-compose.yml:

version: '3.8'

services:
  adguardhome:
    image: adguard/adguardhome:latest
    container_name: adguardhome
    restart: unless-stopped
    # Use host networking or map ports directly. Host networking is recommended for optimal performance,
    # but port mapping allows easier co-existence with other containers on the same VPS.
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "80:80/tcp"
      - "443:443/tcp"
      - "443:443/udp"
      - "3000:3000/tcp"
      - "853:853/tcp"
      - "853:853/udp"
      - "784:784/udp"
      - "8853:8853/udp"
    volumes:
      - ./workdir:/opt/adguardhome/work
      - ./confdir:/opt/adguardhome/conf
    environment:
      - TZ=UTC

Step 3: Launching the Service and Initial Setup

Run the container in detached mode:

docker compose up -d

Verify that the container is running and listening on the expected ports:

docker ps

To complete the initial setup: 1. Navigate to http://your-vps-ip:3000 in your web browser. 2. Follow the wizard. Set the Admin Web Interface to listen on all interfaces or a specific port (e.g., 3000 or 80). 3. Set the DNS Server to listen on all interfaces (port 53). 4. Create your administrator account.

Once completed, the admin panel will be accessible at http://your-vps-ip.

Step 4: Configuring SSL for DoH, DoT, and DoQ

To secure your DNS queries outside your local network, configure encryption using Let's Encrypt certificates.

Option A: Using Certbot on the Host

Install Certbot and request a certificate for your domain (e.g., dns.example.com):

sudo apt update
sudo apt install certbot -y
sudo certbot certonly --standalone -d dns.example.com

This generates certificates in /etc/letsencrypt/live/dns.example.com/.

To allow AdGuard Home inside the container to access these certificates, mount the directory in docker-compose.yml:

    volumes:
      - ./workdir:/opt/adguardhome/work
      - ./confdir:/opt/adguardhome/conf
      - /etc/letsencrypt:/etc/letsencrypt:ro

Recreate the container:

docker compose up -d --force-recreate

Option B: Enabling Encryption in AdGuard Settings

  1. In the AdGuard Home UI, go to Settings > Encryption settings.
  2. Check Enable Encryption.
  3. Set Server name to your domain (e.g., dns.example.com).
  4. Provide the paths to the certificate and private key inside the container:
  5. Certificate path: /etc/letsencrypt/live/dns.example.com/fullchain.pem
  6. Private key path: /etc/letsencrypt/live/dns.example.com/privkey.pem
  7. Click Save Configuration.

Now, DoH (https://dns.example.com/dns-query) and DoT (dns.example.com) are fully enabled.

Step 5: Essential Post-Installation Settings

Upstream DNS Servers

Go to Settings > DNS settings. Configure high-performance, secure upstream resolvers:

https://dns.cloudflare.com/dns-query
https://dns.quad9.net/dns-query
tls://1.1.1.1
tls://9.9.9.9

Select Parallel queries for the fastest resolution times.

Rate Limiting and Security

To prevent your public DNS server from being abused in DNS amplification attacks: 1. Scroll down to DNS server configuration. 2. Set Rate limit to 20 (queries per second per IP). 3. Enable EDNS client subnet to route queries optimally if upstream servers support it.