Install Pi-hole on VPS: Network-Wide DNS Ad Blocker
Pi-hole is an open-source DNS sinkhole that blocks ads and trackers at the network level — before any request ever reaches your devices. Unlike browser extensions, Pi-hole protects every device on your network: smartphones, tablets, Smart TVs, and IoT devices alike.
Running Pi-hole on a VPS instead of a Raspberry Pi gives you 24/7 uptime without worrying about hardware failure, remote access from anywhere via VPN, and a scalable platform. This guide walks you through the complete setup from scratch to a fully functional Pi-hole instance.
Prerequisites
- VPS running Ubuntu 22.04/24.04 or Debian 11/12
- At least 512 MB RAM (1 GB recommended)
- Root or sudo access
- Port 53 (DNS) and port 80 (Web UI) accessible
Step 1: Prepare the System
Update packages and install dependencies:
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl wget git
Check if port 53 is already in use by systemd-resolved:
sudo ss -tulpn | grep :53
If systemd-resolved is listening on port 53, disable the stub listener first:
sudo sed -i 's/#DNSStubListener=yes/DNSStubListener=no/' /etc/systemd/resolved.conf
sudo systemctl restart systemd-resolved
sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
Step 2: Install Pi-hole
Run the official Pi-hole automated installer:
curl -sSL https://install.pi-hole.net | sudo bash
The installer will prompt you with several questions:
- Upstream DNS: Choose Cloudflare (1.1.1.1) or Google (8.8.8.8)
- Blocklists: Select StevenBlack's Unified Hosts (default, recommended)
- Web Admin Interface: On
- Web Server (lighttpd): On
- Log queries: On
- Privacy mode: Show everything
At the end of installation, note down your admin password.
Step 3: Open Firewall Ports with UFW
sudo ufw allow 53/tcp
sudo ufw allow 53/udp
sudo ufw allow 80/tcp
sudo ufw reload
sudo ufw allow from 10.0.0.0/8 to any port 53Step 4: Access the Web Admin Panel
Open your browser and navigate to http://YOUR-VPS-IP/admin. Log in with the password shown during installation.
To change the password at any time:
pihole -a -p YOUR_NEW_PASSWORD
Step 5: Configure DNS on Your Devices
Change the DNS settings on your router or individual devices to point to your VPS IP:
- Primary DNS:
YOUR-VPS-IP - Secondary DNS:
1.1.1.1(fallback)
For remote access from outside your network, set up WireGuard or OpenVPN on the same VPS and configure DNS to use the VPN interface IP.
Step 6: Add Extra Blocklists
Add additional blocklists via the Web UI (Group Management → Adlists) or via the command line:
# Add a blocklist URL to the database
sqlite3 /etc/pihole/gravity.db "INSERT INTO adlist (address, enabled) VALUES ('https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts', 1);"
# Update gravity to fetch the new lists
pihole -g
Recommended blocklists:
| Blocklist | Domains blocked | Best for |
|---|---|---|
| StevenBlack Unified | ~130,000 | General use (default) |
| OISD Full | ~150,000 | Broader coverage |
| Hagezi Pro | ~200,000 | Ads + Malware |
| 1Hosts Pro | ~300,000 | Maximum blocking |
Step 7: Enable DNS-over-HTTPS (DoH)
Improve privacy by using cloudflared as an encrypted upstream DNS resolver:
# Install cloudflared
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared-linux-amd64.deb
# Configure cloudflared for DoH proxy mode
sudo mkdir -p /etc/cloudflared
sudo tee /etc/cloudflared/config.yml << 'EOF'
proxy-dns: true
proxy-dns-port: 5053
proxy-dns-upstream:
- https://1.1.1.1/dns-query
- https://1.0.0.1/dns-query
EOF
# Install and start the service
sudo cloudflared service install
sudo systemctl enable --now cloudflared
Then in Pi-hole Web UI: Settings → DNS → Custom upstream DNS server → 127.0.0.1#5053
Verify Pi-hole is Working Correctly
# Check service status
pihole status
systemctl status pihole-FTL
# Test that ads are blocked (should return 0.0.0.0 or NXDOMAIN)
dig doubleclick.net @YOUR-VPS-IP
# Tail the query log in real time
pihole -t
# Show statistics summary
pihole -c
dig doubleclick.net returns 0.0.0.0 or NXDOMAIN, Pi-hole is blocking correctly. If it returns a real IP, that domain is not in your current blocklists — add a more comprehensive list and run pihole -g to update.Troubleshooting Common Issues
Error: "Port 53 already in use"
systemd-resolved's stub listener is occupying port 53. Disable it before Pi-hole can use the port:
sudo systemctl stop systemd-resolved
sudo sed -i 's/#DNSStubListener=yes/DNSStubListener=no/g' /etc/systemd/resolved.conf
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
sudo systemctl restart systemd-resolved
pihole restartdns
Error: "pihole-FTL failed to start"
The FTL daemon can fail due to port conflicts or missing PID directory permissions:
sudo systemctl stop pihole-FTL
sudo rm -f /run/pihole/FTL.pid
sudo chmod 755 /run/pihole
sudo systemctl start pihole-FTL
journalctl -u pihole-FTL -n 50 --no-pager
Error: "gravity.db: database is locked"
Happens when multiple gravity update processes run simultaneously, or a previous run got stuck:
# Find the process holding the lock
sudo lsof /etc/pihole/gravity.db
# Kill the stuck process
sudo kill -9 PID_NUMBER
# Re-run gravity update
pihole -g
Error: "Web interface not loading" (ERR_CONNECTION_REFUSED)
The lighttpd web server may have stopped. Restart it and verify the config:
sudo systemctl status lighttpd
sudo systemctl restart lighttpd
# Test configuration syntax
sudo lighttpd -t -f /etc/lighttpd/lighttpd.conf
Error: "SERVFAIL" when querying DNS
The upstream DNS server is unreachable, or the DoH proxy is not running:
# Test upstream DNS directly
dig @1.1.1.1 google.com
# Test cloudflared DoH proxy
dig @127.0.0.1 -p 5053 google.com
# Check cloudflared logs
journalctl -u cloudflared -n 30 --no-pager
Frequently Asked Questions
What is the difference between Pi-hole on a VPS vs a Raspberry Pi?
The functionality is identical. The key differences are reliability and accessibility: a VPS runs 24/7 without risk of SD card failure or power outages, and it can be accessed remotely via VPN from anywhere. The trade-off is a monthly cost vs the one-time cost of Raspberry Pi hardware. For most users who want truly always-on filtering, a VPS wins on reliability.
Will Pi-hole slow down my Internet speed?
No — Pi-hole actually speeds up DNS resolution thanks to its local cache. Blocked domains are answered immediately with NXDOMAIN without being forwarded upstream. Real-world users typically see DNS latency drop by 20–40% after enabling Pi-hole.
How do I update Pi-hole to the latest version?
Run a single command — Pi-hole handles the rest automatically with minimal downtime:
pihole -up