Pi-hole Setup Guide — Block Ads on Your Entire Network
Install and configure Pi-hole on Raspberry Pi to block ads and trackers across all devices. Includes Docker setup, custom blocklists, and router configuration.
- 1 How to Install Docker on Raspberry Pi (Step-by-Step)
- 2 Headless Raspberry Pi Setup — SSH & WiFi Without a Monitor
- 3 Turn Your Raspberry Pi into a Home Server (Complete Guide)
- 4 Pi-hole Setup Guide — Block Ads on Your Entire Network
Introduction
Pi-hole is a network-wide ad blocker that operates at the DNS level. Instead of blocking ads in your browser, Pi-hole intercepts DNS queries from every device on your network—phones, tablets, smart TVs, laptops—and filters out requests to known ad servers before they even reach your devices. The result is faster, cleaner browsing across your entire network without installing extensions or apps on individual devices.
Unlike browser-based ad blockers, Pi-hole works on all devices, even those that can't run extensions (like smart home devices and smart TVs). It also blocks trackers, malware domains, and other unwanted content at the DNS level, providing both privacy and performance benefits.
In this guide, we'll walk through installing Pi-hole on a Raspberry Pi using both traditional and Docker methods, configuring it with custom blocklists, and setting up your router to use it as the primary DNS server.
Prerequisites
Before starting, you'll need:
- Raspberry Pi 4 or newer (2GB RAM minimum; 4GB+ recommended for better performance)
- MicroSD card (32GB+ recommended)
- Raspberry Pi OS Lite (latest version, 64-bit preferred)
- Static IP address for your Pi-hole instance (we'll configure this)
- Access to your router to change DNS settings
- Network connectivity via Ethernet (recommended) or Wi-Fi
- Basic Linux command-line knowledge
Pi-hole typically uses 40-70 MB of RAM and handles 1000+ DNS queries per minute without issues. For most home networks, a Pi 4 with 2GB RAM is sufficient.
Step 1 — Set Up a Static IP Address
Pi-hole must have a static IP address so devices can reliably use it as their DNS server. SSH into your Raspberry Pi and edit the dhcpcd configuration:
sudo nano /etc/dhcpcd.conf
Add these lines at the end of the file (replace with your actual network settings):
# Static IP configuration for Pi-hole
interface eth0
static ip_address=192.168.1.50/24
static routers=192.168.1.1
static domain_name_servers=1.1.1.1 8.8.8.8
For Wi-Fi (wlan0), use the same format with the interface name. Save with Ctrl+X, then Y, then Enter.
Restart the networking service:
sudo systemctl restart dhcpcd
Verify the static IP:
ip addr show eth0
You should see inet 192.168.1.50/24 in the output.
Step 2 — Choose Your Installation Method
Pi-hole offers two installation paths: traditional bare-metal install and containerized Docker install. Both are equally valid—choose based on your preference.
Bare-metal is simpler for beginners and integrates deeply with the system. Docker is cleaner, easier to update, and keeps dependencies isolated. I'll cover both.
Step 3 — Bare-Metal Installation
Download and Run the Installer
Pi-hole provides an automated installer that handles all dependencies:
curl -sSL https://install.pi-hole.net | bash
The installer will:
- Prompt you to choose an upstream DNS provider (use Cloudflare 1.1.1.1 or Quad9 9.9.9.9 for privacy)
- Set up dnsmasq and lighttpd
- Create the Pi-hole admin interface
- Configure firewall rules
Choose your upstream DNS carefully—this is the provider your Pi-hole will query for non-blocked domains. Popular privacy-focused options:
- Cloudflare (1.1.1.1): Fast, privacy-focused
- Quad9 (9.9.9.9): Blocks malware, DNSSEC validation
- Mullvad (194.242.2.2): Strong privacy guarantees
Verify Installation
After installation completes, check that Pi-hole services are running:
sudo systemctl status pihole-FTL
sudo systemctl status lighttpd
Both should show active (running). Access the admin dashboard by opening your browser and navigating to:
http://192.168.1.50/admin/
Note the randomly generated admin password from the installation output—you'll need it to log in.
Step 4 — Docker Installation (Alternative)
Install Docker and Docker Compose
If Docker isn't installed, set it up:
curl -sSL https://get.docker.com | sh
sudo usermod -aG docker $USER
sudo apt update && sudo apt install docker-compose -y
Log out and back in for Docker group permissions to take effect.
Create Docker Compose File
Create a directory for Pi-hole and its configuration:
mkdir -p ~/pihole
cd ~/pihole
Create a docker-compose.yml file:
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
pihole:
image: pihole/pihole:latest
container_name: pihole
restart: unless-stopped
ports:
- "53:53/tcp"
- "53:53/udp"
- "80:80/tcp"
- "443:443/tcp"
environment:
TZ: 'America/Chicago'
WEBPASSWORD: 'your_secure_password_here'
PIHOLE_DOMAIN: 'pi.hole'
DNS1: '1.1.1.1'
DNS2: '8.8.8.8'
CONDITIONAL_FORWARDING: 'true'
CONDITIONAL_FORWARDING_DOMAIN: 'local.home'
CONDITIONAL_FORWARDING_IP: '192.168.1.1'
DNSSEC: 'true'
volumes:
- './etc-pihole/:/etc/pihole/'
- './etc-dnsmasq.d/:/etc/dnsmasq.d/'
networks:
- pihole
healthcheck:
test: ["CMD", "dig", "@localhost", "google.com"]
interval: 30s
timeout: 10s
retries: 3
networks:
pihole:
driver: bridge
EOF
Replace your_secure_password_here with a strong password and adjust TZ to your timezone.
Start the Container
docker-compose up -d
Verify it's running:
docker-compose ps
Access the admin interface at http://192.168.1.50/admin/ and log in with your password.
Step 5 — Configure Upstream DNS Servers
Upstream DNS servers are where Pi-hole forwards queries for non-blocked domains. Configure them in the admin dashboard:
- Navigate to Settings → DNS
- Under Upstream DNS Servers, select or add your preferred providers
- Recommended settings for privacy:
- Primary:
1.1.1.1(Cloudflare) - Secondary:
9.9.9.9(Quad9)
- Primary:
You can also add DoH (DNS over HTTPS) upstream providers for encrypted queries:
https://cloudflare-dns.com/dns-query(Cloudflare DoH)https://dns9.quad9.net/dns-query(Quad9 DoH)
Test your upstream DNS:
nslookup google.com 192.168.1.50
Should return Google's IP address(es).
Step 6 — Configure Router DNS Settings
For Pi-hole to block ads on all devices, your router must use it as the primary DNS server.
Access Your Router
Open your browser and navigate to your router's IP (usually 192.168.1.1 or 192.168.0.1). Log in with your router credentials.
Update DHCP DNS Settings
Look for DHCP Settings or LAN Settings:
- Find the section for Primary DNS Server (or DNS 1)
- Set it to your Pi-hole IP:
192.168.1.50 - Optionally set Secondary DNS Server to a backup (like
1.1.1.1) - Save and apply settings
Restart Your Router (Optional)
For changes to take effect on connected devices, either:
# On your Pi-hole, flush the DNS cache
sudo systemctl restart pihole-FTL
Or restart your router from its admin interface.
Verify Router Configuration
Check your router's DHCP settings to confirm:
# From any device on your network
nslookup pi.hole
Should resolve to your Pi-hole's IP address.
Step 7 — Add and Manage Blocklists
Blocklists are the heart of Pi-hole's filtering. The default list blocks ~140K domains, but you can add custom lists for better filtering.
Add Blocklists
In the admin dashboard:
- Navigate to Adlists
- Click Add new Adlist
- Paste a blocklist URL and save
Recommended Blocklists
# Comprehensive ad and tracker blocking
https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
# Ads and tracking
https://adaway.org/hosts.txt
https://someonewhocares.org/hosts/hosts
# Malware and phishing
https://raw.githubusercontent.com/lightswitch05/hosts/master/docs/domains/malware-domains.txt
https://raw.githubusercontent.com/DandelionSprout/adfilt/master/Alternate%20versions%20MobileAdblockList%20%(Regular%20AdBlock%20List%29.txt
# Tracking and telemetry
https://raw.githubusercontent.com/ookangzheng/dbl-iana-cname/master/dbl.txt
# Spyware and unwanted software
https://gitlab.com/quidsup/notrack-blocklists/raw/master/notrack-blocklist.txt
Pi-hole automatically updates blocklists on a schedule. Check the update status in Adlists → Blocklist Gravity.
Performance Impact
Each blocklist adds latency. Monitor performance in the Dashboard:
- Query volume: Should be 50-200 QPS (queries per second) for most homes
- Blocked queries: Typically 15-25% with moderate blocklists
- Pi-hole load: Monitor under System in the admin interface
If performance degrades, remove or disable less critical blocklists.
Step 8 — Whitelist and Blacklist Management
Pi-hole lets you fine-tune blocking with whitelists (allow specific domains) and blacklists (block specific domains).
Add to Whitelist
Navigate to Whitelist in the admin interface:
- Enter a domain you want to allow (e.g.,
ads.google.com) - Click Add to whitelist
Example whitelist entries:
# Allow services that require ads/trackers to function
doubleclick.net
googlesyndication.com
youtube.com (if you want YouTube ads)
Add to Blacklist
Navigate to Blacklist:
- Enter a domain you want to block
- Click Add to blacklist
Example blacklist entries:
# Block unwanted services
tracking-domain.com
telemetry.service.local
Regex Filters
For advanced filtering, use Regex Filter to match domain patterns:
# Block all subdomains of a domain
^(.+\.)?ads-domain\.com$
# Block specific tracking patterns
^(.+\.)?telemetry\.microsoft\.com$
Step 9 — Custom Blocklists Section
Creating your own blocklist gives you fine-grained control. Here's how:
Generate a Custom Blocklist
Create a text file with domains, one per line:
# Create your custom blocklist
cat > /tmp/custom-blocklist.txt << 'EOF'
# My custom blocklist
unwanted-ad-server.com
tracking.service.net
analytics-collector.io
telemetry.vendor.com
EOF
Host this file on a web server or GitHub, then add its URL to Adlists.
Alternative: Local Adlist via Dnsmasq
For bare-metal installations, add a local adlist directly:
sudo nano /etc/dnsmasq.d/custom-blocklist.conf
Add:
# Load custom domains from a local file
addn-hosts=/etc/pihole/custom-blocklist.txt
Edit the hosts file:
sudo nano /etc/pihole/custom-blocklist.txt
Add entries:
0.0.0.0 unwanted-domain.com
0.0.0.0 tracking.service.net
Restart dnsmasq:
sudo systemctl restart dnsmasq
Step 10 — Monitor and Troubleshoot
Dashboard Metrics
The Pi-hole dashboard shows:
- Total queries: Number of DNS queries in the last 24 hours
- Blocked queries: How many were filtered
- Gravity update: Last time blocklists were updated
- CPU/Memory/Disk: System resource usage
Typical metrics on a Pi 4:
- RAM: 40-70 MB baseline, up to 150 MB under load
- CPU: <10% at rest, <30% during peak queries
- Query speed: 1-5ms typical response time
Query Logging
To debug blocking issues, check the query log:
- Go to Query Log in the admin dashboard
- Search for a domain that seems blocked incorrectly
- Click on the domain to see which blocklist blocked it
- Whitelist if necessary
SSH Log Inspection
For deeper troubleshooting, check Pi-hole logs:
# View FTL (dnsmasq) logs
sudo journalctl -u pihole-FTL -f
# Check lighttpd (web server) errors
sudo tail -f /var/log/lighttpd/error.log
# View dnsmasq query log
sudo grep "queries\|replies" /var/log/dnsmasq.log
Troubleshooting
Issue 1: Devices Not Using Pi-hole DNS
Symptom: Ads still appear, or nslookup shows wrong DNS server.
Solution:
- Verify router is configured with Pi-hole IP as primary DNS
- Restart DHCP service on router
- Restart devices to pick up new DHCP lease
- Force DHCP renewal on device:
# Linux/Mac sudo dhclient -r eth0 && sudo dhclient eth0 # Or disconnect/reconnect Wi-Fi on mobile devices - Check devices' DNS settings directly:
nslookup google.com # Should show your Pi-hole IP as the resolver
Issue 2: Slow DNS Queries or Timeouts
Symptom: Web pages load slowly, or DNS queries timeout.
Solution:
- Check Pi-hole load and memory:
top free -h - If RAM usage >80%, restart Pi-hole:
sudo systemctl restart pihole-FTL - Reduce blocklists (disable less critical ones)
- Check if upstream DNS is responding:
nslookup google.com 1.1.1.1 - Switch to faster upstream DNS:
- Cloudflare (1.1.1.1) is usually fastest
- Test response times in Settings → DNS
Issue 3: Some Legitimate Sites Are Blocked
Symptom: A website won't load, even though it's not an ad network.
Solution:
- Find which blocklist is blocking it:
- In Query Log, search for the domain
- Click on the blocked domain to see which list blocked it
- Add to whitelist if it's a false positive
- Disable the problematic blocklist if it has many false positives
- Use regex whitelist for patterns:
^(.+\.)?legitimate-domain\.com$
Issue 4: Admin Interface Won't Load
Symptom: Can't access http://192.168.1.50/admin/
Solution:
- Check if lighttpd is running:
sudo systemctl status lighttpd sudo systemctl restart lighttpd - Verify Pi-hole IP is still 192.168.1.50:
hostname -I - Check if port 80 is in use:
sudo netstat -tlnp | grep :80 - Try accessing without
/admin/:http://192.168.1.50
Advanced Configuration
Enable DNSSEC Validation
For added DNS security, enable DNSSEC:
- Navigate to Settings → DNS
- Enable Use DNSSEC
- Restart Pi-hole:
sudo systemctl restart pihole-FTL
Conditional Forwarding
To resolve local network hostnames (like .local domains):
- In Settings → DNS → Conditional forwarding
- Enable it and set:
- Local network in CIDR:
192.168.1.0/24 - Conditional forwarding IP:
192.168.1.1(your router IP)
- Local network in CIDR:
Backup and Restore
Backup your Pi-hole configuration:
# Export settings (bare-metal)
sudo pihole -a -t
# Or manually backup
sudo cp -r /etc/pihole /backups/pihole-$(date +%Y%m%d)
sudo cp -r /etc/dnsmasq.d /backups/dnsmasq-$(date +%Y%m%d)
For Docker:
docker-compose exec pihole pihole -a -t
Summary
You now have a fully functional network-wide ad blocker running on your Raspberry Pi. Pi-hole removes ads and trackers at the DNS level, protecting all devices on your network without requiring individual configuration.
Key takeaways:
- Setup: Static IP + installer makes configuration straightforward
- Blocklists: Start with 2-3 quality lists, avoid list bloat
- Monitoring: Check the dashboard weekly for blocked query patterns
- Maintenance: Update blocklists weekly (automatic), restart if needed
- Performance: Pi 4 with 4GB RAM handles most home networks easily
For ongoing management, check your admin dashboard weekly, monitor the query log for false positives, and fine-tune blocklists based on your network's needs. With proper configuration, Pi-hole reduces ad loading by 70-90% across your entire network while maintaining excellent DNS performance.
If you run into issues, check the logs, verify router DNS settings, and remember that a whitelist entry is often better than disabling an entire blocklist. Happy ad-free browsing.