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:
- Open
/etc/systemd/resolved.confin an editor:bash sudo nano /etc/systemd/resolved.conf - 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 - Symlink
/etc/resolv.confto a static file to ensure local DNS resolution still works:bash sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf - 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
- In the AdGuard Home UI, go to Settings > Encryption settings.
- Check Enable Encryption.
- Set Server name to your domain (e.g.,
dns.example.com). - Provide the paths to the certificate and private key inside the container:
- Certificate path:
/etc/letsencrypt/live/dns.example.com/fullchain.pem - Private key path:
/etc/letsencrypt/live/dns.example.com/privkey.pem - 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.