How to Self-Host Pi-hole for Network-Wide Ad Blocking
Block ads and trackers for every device on your network at the DNS level. Install Pi-hole on a VPS with Docker and point your router at it.

Pi-hole is a DNS sinkhole: it answers DNS queries for your whole network and refuses to resolve known ad and tracker domains. Run it on a VPS and every device that uses it — phones, TVs, laptops — gets ad blocking with no per-device software. This guide installs it with Docker and, importantly, secures it so it doesn't become an open resolver.
How Pi-hole works
When a device asks "where is ads.example.com?", Pi-hole checks its blocklists. If the domain is on one, it returns nothing and the ad never loads. Legitimate domains are forwarded to an upstream resolver. If DNS itself is new to you, how DNS works is a quick primer.
Prerequisites
- A VPS with Docker installed — see how to run Docker on a VPS.
- Your server's public IP.
- A plan to reach it privately: never expose port 53 to the whole internet. Open resolvers get abused for DNS amplification attacks. The clean way is to only allow your own IP, or better, run Pi-hole over a VPN.
Deploy Pi-hole with Compose
mkdir -p ~/pihole && cd ~/pihole
services:
pihole:
image: pihole/pihole:latest
container_name: pihole
restart: unless-stopped
ports:
- "53:53/tcp"
- "53:53/udp"
- "8080:80/tcp"
environment:
- TZ=Europe/London
- WEBPASSWORD=change-me
- FTLCONF_LOCAL_IPV4=your-server-ip
volumes:
- ./etc-pihole:/etc/pihole
- ./etc-dnsmasq.d:/etc/dnsmasq.d
docker compose up -d
The admin dashboard is now on http://your-server-ip:8080/admin.

Lock down DNS — the critical step
An open DNS resolver is a liability. Restrict port 53 to trusted sources only. If you have a static home IP:
sudo ufw allow OpenSSH
sudo ufw allow from YOUR.HOME.IP.ADDR to any port 53
sudo ufw deny 53
sudo ufw enable
The far safer pattern is to reach Pi-hole through a VPN and let only the VPN interface query it. Set up WireGuard on a VPS first, then point clients at Pi-hole's private VPN address. That way DNS is never exposed publicly at all.
Point your devices at Pi-hole
- Whole network: set your router's DNS server to the Pi-hole IP so every device inherits it.
- Single device: set the DNS manually in its network settings.
Then confirm blocking works — the query log in the dashboard fills up immediately, showing blocked domains in red.
Add and manage blocklists
Pi-hole ships with a solid default list. Add more under Adlists, then update gravity:
docker compose exec pihole pihole -g
Whitelist anything that breaks (some sites need their analytics domains to function). The dashboard's query log makes it easy to spot and allow a domain.
Bonus: local DNS for your other services
Because Pi-hole is a full DNS server, it can also resolve custom names for the other apps you host. Add records under *Local DNS → DNS Records* so nextcloud.home, grafana.home and friends resolve to your servers' addresses — no more memorising IPs. This pairs beautifully with a VPN: connect to WireGuard, use Pi-hole as your resolver, and reach every private service by a friendly name while ad blocking follows you everywhere you go.
Keeping blocklists effective
Out of the box Pi-hole blocks the worst offenders, but you can tune it:
- Add reputable adlists under *Adlists*, then rebuild with
pihole -g. Don't go overboard — huge combined lists cause more false positives than they're worth. - Watch the query log for a day or two and whitelist any domain that breaks a site you rely on.
- Review the dashboard regularly; the *Top Blocked Domains* and *Clients* panels reveal what's quietly phoning home on your network, which is often eye-opening.
Update gravity on a schedule so lists stay current:
docker compose exec pihole pihole -g
Test that blocking actually works
After pointing a device at Pi-hole, confirm it's really filtering. The quickest check is the dashboard's live query log — it fills instantly, showing allowed queries in green and blocked ones in red. You can also run a lookup against a known ad domain and see it resolve to 0.0.0.0:
nslookup doubleclick.net your-server-ip
If it returns 0.0.0.0, blocking is working. If your devices don't seem to be filtering, the usual cause is that they cached DNS or picked up a secondary resolver — flush the client's DNS cache and make sure Pi-hole is the *only* DNS server configured.
Upstream DNS and encryption
By default Pi-hole forwards allowed queries to a public resolver in plain text. For extra privacy, pair Pi-hole with an encrypted upstream (DNS-over-HTTPS or DNS-over-TLS) so your ISP can't see your lookups — a small companion resolver container handles the encryption, and you point Pi-hole at it as the upstream. Combined with a VPN, this gives you private, encrypted, ad-free DNS everywhere you go.
FAQ
Is it safe to run Pi-hole on a public VPS?
Only if you restrict port 53. An unrestricted resolver will be abused for amplification attacks and may get your server flagged. Limit it to your IP or, best, tunnel it through a VPN.
Will Pi-hole block YouTube or in-app ads?
It blocks ads served from known ad domains, which covers most web and many app ads. Ads served from the same domain as the content (like some YouTube ads) can't be blocked at DNS level.
Does Pi-hole slow down browsing?
No — it usually speeds it up slightly, because blocked requests never load and cached answers return instantly.
Can I use Pi-hole as my only DNS?
Yes, but set a sensible upstream (like a public resolver) and consider a second Pi-hole or fallback so DNS keeps working during maintenance.
Pi-hole pairs perfectly with a private VPN. Host both on a low-latency VPN server VPS, or start small with an affordable VPS plan.