Setting Up Pi-hole for Network-Wide Ad Blocking
Pi-hole is a network-wide ad blocker that works at the DNS level, blocking ads and trackers before they even reach your devices. Instead of installing ad blockers on every device, Pi-hole protects your entire network—computers, phones, tablets, smart TVs, and even IoT devices that can't run traditional ad blockers.
What is Pi-hole and How Does It Work?
Pi-hole acts as a DNS server for your network. When devices request website addresses, Pi-hole checks if the domain is on a blocklist. If it is, Pi-hole blocks it. If not, Pi-hole forwards the request to your real DNS server.
The flow:
- Your device asks: "What's the IP address of ad-tracker.com?"
- Pi-hole checks: "Is ad-tracker.com on my blocklist?"
- If yes: Pi-hole responds with a blank page (blocked)
- If no: Pi-hole asks a real DNS server and passes the answer back
Benefits:
- Blocks ads on all devices simultaneously
- Faster browsing (no ad content to download)
- Reduced data usage
- Blocks tracking and telemetry
- Works on devices that can't run ad blockers (smart TVs, mobile apps)
- Privacy improvement
- Can block malware domains
Limitations:
- Can't block YouTube ads (they come from same domain as videos)
- Some sites detect and complain about ad blocking
- Requires some maintenance
- Can accidentally block legitimate sites (easy to fix)
Prerequisites
Before starting, ensure you have:
- Raspberry Pi with Docker installed (from our previous guides)
- Static IP address configured for your Pi
- Basic networking knowledge
- Access to your router's admin panel
- 10-15 minutes
Part 1: Installing Pi-hole with Docker
We'll use Docker for easy installation and management.
Step 1: Create Pi-hole Directory
mkdir -p ~/docker/pihole
cd ~/docker/pihole
Step 2: Create Docker Compose File
nano docker-compose.yml
Add this configuration:
version: '3.8'
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
hostname: pihole
ports:
- "53:53/tcp"
- "53:53/udp"
- "67:67/udp"
- "80:80/tcp"
environment:
TZ: 'America/New_York'
WEBPASSWORD: 'YourSecurePassword123'
FTLCONF_LOCAL_IPV4: '192.168.1.100' # Your Pi's IP
PIHOLE_DNS_: '1.1.1.1;1.0.0.1' # Cloudflare DNS (or change to your preference)
DNSMASQ_LISTENING: 'all'
volumes:
- './etc-pihole:/etc/pihole'
- './etc-dnsmasq.d:/etc/dnsmasq.d'
cap_add:
- NET_ADMIN
restart: unless-stopped
Important configuration notes:
TZ: Your timezone (affects log timestamps)
WEBPASSWORD: Choose a strong password for the admin interface
FTLCONF_LOCAL_IPV4: Your Raspberry Pi's static IP address
PIHOLE_DNS_: Upstream DNS servers to use:
- Cloudflare:
1.1.1.1;1.0.0.1 - Google:
8.8.8.8;8.8.4.4 - Quad9:
9.9.9.9;149.112.112.112 - OpenDNS:
208.67.222.222;208.67.220.220
Step 3: Deploy Pi-hole
docker-compose up -d
Check if it's running:
docker-compose logs -f
You should see Pi-hole starting up and initializing blocklists.
Step 4: Access the Web Interface
Open your browser and visit:
http://192.168.1.100/admin
(Replace with your Pi's IP address)
Log in with the password you set in WEBPASSWORD.
First-time dashboard:
- You'll see statistics (currently zero)
- Blocklists are already active
- Pi-hole is ready but not yet being used
Part 2: Configuring Your Network
Now you need to tell your devices to use Pi-hole as their DNS server.
Option 1: Configure Your Router (Recommended)
This automatically applies Pi-hole to all devices on your network.
Steps (varies by router):
- Log into your router's admin panel (usually
192.168.1.1or192.168.0.1) - Find the DHCP or LAN settings
- Look for "Primary DNS" or "DNS Server"
- Change it to your Pi-hole's IP:
192.168.1.100 - Optional: Set secondary DNS to
1.1.1.1(fallback if Pi-hole is down) - Save settings
- Restart router or wait for DHCP leases to renew
Common router interfaces:
TP-Link:
- Advanced → Network → DHCP Server → Primary DNS
Netgear:
- Advanced → Setup → LAN Setup → Primary DNS
ASUS:
- LAN → DHCP Server → DNS Server 1
Google Wifi:
- Settings → Network & General → Advanced networking → DNS
pfSense/OPNsense:
- Services → DHCP Server → DNS servers
Option 2: Configure Individual Devices
If you can't access your router or want to test first:
Windows:
- Settings → Network & Internet → Change adapter options
- Right-click your connection → Properties
- Select "Internet Protocol Version 4 (TCP/IPv4)"
- Click Properties
- Select "Use the following DNS server addresses"
- Preferred DNS:
192.168.1.100(your Pi-hole) - Alternate DNS:
1.1.1.1
Mac:
- System Preferences → Network
- Select your connection → Advanced
- DNS tab
- Click "+" and add
192.168.1.100 - Move it to the top of the list
iPhone/iPad:
- Settings → WiFi
- Tap the (i) next to your network
- Configure DNS → Manual
- Remove existing servers
- Add Server:
192.168.1.100
Android:
- Settings → Network & Internet → WiFi
- Long-press your network → Modify
- Advanced Options → IP Settings → Static
- DNS 1:
192.168.1.100 - DNS 2:
1.1.1.1
Option 3: Configure Via DHCP Reservation
Some routers let you set specific DNS for specific devices:
- Create DHCP reservation for device's MAC address
- Assign custom DNS for that reservation
- Force device to renew DHCP lease
Part 3: Verify Pi-hole is Working
Test 1: Check Dashboard
Visit Pi-hole admin panel. After a few minutes of browsing:
- "Total queries" should be increasing
- "Queries blocked" should show blocked ads
- You should see percentage of blocked queries (typically 15-30%)
Test 2: Browse Known Ad-Heavy Sites
Visit sites with lots of ads:
- News sites (CNN, Forbes)
- Streaming sites
- Tech blogs
You should see:
- Fewer ads (or none)
- Faster page loads
- Blank spaces where ads would be
Test 3: Use Pi-hole's Tools
In Pi-hole admin:
- Go to Tools → Query Log
- Browse a website in another tab
- Watch queries appear in real time
- See which domains are blocked (red) vs allowed (green)
Test 4: Command Line DNS Query
nslookup doubleclick.net 192.168.1.100
Should return 0.0.0.0 (blocked) instead of a real IP.
Part 4: Customizing Pi-hole
Adding More Blocklists
Default lists are good, but you can add more.
Popular additional lists:
Steven Black's Unified Hosts:
- Blocks ads, malware, and adult content
- Very comprehensive
OISD (Our Choice):
- Well-maintained, low false positives
- Blocks ads and malware
- Updated daily
Add a blocklist:
- Pi-hole admin → Adlists
- Add this URL:
https://big.oisd.nl - Click "Add"
- Tools → Update Gravity
- Click "Update" (takes 1-2 minutes)
Other useful lists:
- EasyList:
https://v.firebog.net/hosts/Easylist.txt - AdGuard DNS:
https://v.firebog.net/hosts/AdguardDNS.txt - Malicious sites:
https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
Warning: Too many lists can cause false positives. Start with 3-5 good lists.
Whitelisting (Allowing Blocked Domains)
Sometimes Pi-hole blocks legitimate sites.
Symptoms:
- Website partially broken
- Can't log in to a service
- Missing images or content
To whitelist:
- Pi-hole admin → Whitelist
- Add the domain (without http://)
- Click "Add to whitelist"
Common domains to whitelist:
- Amazon:
s.amazon-adsystem.com(for Prime Video) - Facebook:
graph.facebook.com(for social sharing) - Microsoft:
msftconnecttest.com(Windows network test) - Apple:
ocsp.apple.com(certificate checking)
Tip: Check Query Log to see what was blocked when site broke, then whitelist it.
Blacklisting (Blocking Additional Domains)
Block domains not on your lists:
- Pi-hole admin → Blacklist
- Add domain (supports wildcards)
- Examples:
facebook.com(exact match)*.facebook.com(blocks all Facebook subdomains)ad.*.com(blocks any domain starting with "ad")
Common custom blocks:
- Telemetry:
telemetry.microsoft.com - Analytics:
google-analytics.com - Smart TV ads:
ads.roku.com,ads.samsung.com
Local DNS Records
Create custom DNS entries for devices on your network:
- Local DNS → DNS Records
- Add domain and IP
- Example:
homeserver.local→192.168.1.100
Use case:
- Easy names for local services:
pihole.local,plex.local,homeassistant.local - Override external domains (advanced)
CNAME Records
Create aliases for domains:
- Local DNS → CNAME Records
- Point one domain to another
- Example:
media.local→plex.local
Part 5: Advanced Features
Group Management
Organize devices and apply different blocklists:
Use case: Block adult content for kids' devices, but not adults' devices
Setup:
- Groups → Add group (e.g., "Kids Devices")
- Clients → Add client (device IP or MAC)
- Assign client to group
- Adlists → Assign different lists to different groups
- Domains → Create group-specific blacklists/whitelists
Conditional Forwarding
Makes local hostnames work (see "John's-iPhone" instead of IP addresses):
- Settings → DNS → Advanced DNS settings
- Enable "Conditional forwarding"
- Local network:
192.168.1.0/24(your subnet) - Router IP:
192.168.1.1 - Local domain:
localor your domain
DNSSEC
Validates DNS responses for security:
- Settings → DNS
- Enable "Use DNSSEC"
- Protects against DNS spoofing
Note: Some upstream DNS servers don't support DNSSEC. Use Cloudflare or Quad9.
Query Logging Privacy
Anonymize queries:
- Settings → Privacy
- Set "Privacy level" to Anonymous or higher
- Hides client IPs in logs
Disable logging:
- Good for maximum privacy
- Bad for troubleshooting
- Settings → Privacy → "0 Show everything"
Part 6: Mobile DNS (Outside Your Network)
Pi-hole only works on your home network. For protection on the go:
Option 1: WireGuard VPN
Set up a VPN server on your Pi (separate guide), configure devices to use it. When connected to VPN, you use your Pi-hole.
Pros: Full protection anywhere, secure connection Cons: Requires VPN setup, battery drain on mobile
Option 2: Tailscale
Easier VPN alternative:
- Install Tailscale on Pi and devices
- Configure Tailscale to use Pi-hole as DNS
- Automatic connection
Option 3: Cloud Pi-hole
Host Pi-hole on a cloud VPS accessible from anywhere:
- DigitalOcean droplet ($5/month)
- Same setup process
- Change all devices to use cloud Pi-hole IP
Option 4: NextDNS or Cloudflare Gateway
Use a hosted DNS filtering service:
- Not Pi-hole, but similar concept
- Works anywhere automatically
- Less control, but easier
Part 7: Monitoring and Maintenance
Dashboard Overview
Key statistics to watch:
- Total queries: Should increase steadily
- Queries blocked: Typically 15-30% of total
- Blocklist size: Number of blocked domains (~100k-1M typical)
- Top permitted/blocked domains: See what's popular
Long-term stats:
- Settings → API / Web interface
- View 24 hours, 7 days, 30 days graphs
- See usage patterns (peak times, etc.)
Regular Maintenance
Weekly:
- Check Query Log for false positives
- Verify blocking percentage is reasonable
- Ensure Pi-hole is responding
Monthly:
- Update Gravity (blocklists): Tools → Update Gravity
- Update Pi-hole:
docker-compose pull && docker-compose up -d - Check disk usage:
docker exec pihole df -h
Quarterly:
- Review and prune blocklists (remove duplicates)
- Clean up old whitelists/blacklists
- Backup configuration
Backup Your Configuration
Export settings:
- Settings → Teleporter
- Click "Backup"
- Downloads a
.tar.gzfile with all settings
Restore on new installation:
- Fresh Pi-hole install
- Settings → Teleporter
- Upload backup file
- All settings, lists, whitelists restored
Alternative - Docker volumes:
cd ~/docker/pihole
tar -czf pihole-backup-$(date +%Y%m%d).tar.gz etc-pihole/ etc-dnsmasq.d/
Store backup off-site or on cloud storage.
Performance Monitoring
Check Pi-hole performance:
docker exec pihole pihole -c
Shows:
- Memory usage
- Queries processed
- CPU load
System performance:
htop
Pi-hole is lightweight, but if slow:
- Reduce number of blocklists
- Increase Pi's RAM
- Use SSD instead of SD card
Part 8: Troubleshooting
Internet Not Working After Enabling Pi-hole
Symptom: No websites load
Causes and fixes:
-
Pi-hole is down:
- Check:
docker ps- is pihole running? - Fix:
docker-compose restart
- Check:
-
DNS not forwarding:
- Check: Pi-hole admin → Settings → DNS → Are upstream servers set?
- Fix: Set to
1.1.1.1and1.0.0.1
-
Firewall blocking:
- Check:
sudo ufw status- is port 53 allowed? - Fix:
sudo ufw allow 53
- Check:
Some Sites Are Broken
Symptom: Site loads but images missing, can't log in, functionality broken
Cause: Pi-hole blocked a legitimate domain
Fix:
- Open Query Log while loading the broken site
- Look for recently blocked (red) domains
- Try whitelisting them one by one
- Reload site after each whitelist
Common culprits:
- CDNs (content delivery networks)
- Analytics required for site function
- Third-party authentication
Very Few Queries Blocked
Symptom: Only 1-5% of queries blocked
Causes:
-
Devices not using Pi-hole:
- Verify: Check each device's DNS settings
- Fix: Set DNS to Pi-hole's IP
-
Devices using hardcoded DNS:
- Some devices (Chromecast, smart TVs) use Google DNS (8.8.8.8) regardless of settings
- Fix: Block port 53 outbound on router (forces them to use Pi-hole)
-
Not enough blocklists:
- Add more lists (OISD, Steven Black)
-
Apps using encrypted DNS:
- Some apps use DoH (DNS over HTTPS)
- Can't be blocked without advanced router configs
Pi-hole Dashboard Won't Load
Symptom: Can't access web interface
Causes:
-
Pi is offline:
- Check: Ping Pi's IP
- Fix: Reboot Pi
-
Docker container crashed:
- Check:
docker ps -a- is pihole exited? - Fix:
docker-compose up -d
- Check:
-
Port 80 conflict:
- Another service using port 80
- Fix: Change Pi-hole to port 8080 in docker-compose
-
Wrong password:
- Reset:
docker exec pihole pihole -a -p newpassword
- Reset:
High Memory Usage
Pi-hole using lots of RAM:
Normal: 100-200MB for container High: 500MB+
Causes:
- Too many blocklists (millions of domains)
- Very high query rate
- Long query log retention
Fixes:
- Reduce blocklists
- Settings → API / Web interface → Set max log entries to lower number
- Restart Pi-hole weekly with cron
Part 9: Optional Enhancements
DHCP Server in Pi-hole
Let Pi-hole handle DHCP instead of your router:
Benefits:
- Easier DNS assignment (automatic)
- See hostnames in dashboard
- More control
Setup:
- Disable DHCP on your router
- Pi-hole → Settings → DHCP
- Enable DHCP server
- Set IP range (e.g.,
192.168.1.100to192.168.1.250) - Set router/gateway IP
- Save
Warning: Do this carefully. If misconfigured, network won't work.
Unbound Recursive DNS
Run your own DNS resolver for maximum privacy:
Why: Instead of Cloudflare/Google knowing your queries, you query root DNS servers directly
Setup:
cd ~/docker/pihole
nano docker-compose.yml
Add unbound service:
unbound:
container_name: unbound
image: mvance/unbound:latest
hostname: unbound
volumes:
- './unbound:/opt/unbound/etc/unbound/'
ports:
- "5335:53/tcp"
- "5335:53/udp"
restart: unless-stopped
Update and configure:
docker-compose up -d
In Pi-hole:
- Settings → DNS
- Upstream DNS:
172.17.0.1#5335(Docker bridge IP) - Save
Now Pi-hole uses your own recursive resolver.
Multiple Pi-holes (Redundancy)
Run a second Pi-hole for backup:
Setup:
- Install Pi-hole on another Raspberry Pi
- Configure with same blocklists
- Set router DNS:
- Primary: First Pi-hole IP
- Secondary: Second Pi-hole IP
Benefits:
- Network keeps working if one Pi-hole goes down
- Split load between two Pis
Dark Mode
For night browsing:
- Settings → Web Interface → Admin theme
- Select "Dark"
API Access
Access Pi-hole data programmatically:
# Get summary
curl http://192.168.1.100/admin/api.php
# Get top blocked domains
curl http://192.168.1.100/admin/api.php?topBlocked
Use in scripts, dashboards, or monitoring tools.
Typical Performance Expectations
After proper setup:
Query blocking: 20-35% of queries blocked Speed improvement: Pages load 20-40% faster Data savings: 15-25% less data downloaded Privacy: Hundreds of trackers blocked daily
Your network:
- Smart TV: 40-60% queries blocked (they're ad-heavy)
- Smartphone: 25-35% queries blocked
- Computer: 15-25% queries blocked
- IoT devices: 50-80% blocked (lots of telemetry)
Next Steps
Your network is now protected from ads and trackers! Consider these additions:
- Set up WireGuard VPN - Use Pi-hole when away from home
- Add Home Assistant - Integrate Pi-hole stats into home automation
- Configure local DNS - Easy names for all your home services
- Monitor with Grafana - Beautiful graphs of Pi-hole stats
- Automate updates - Cron jobs for updating Gravity and Docker images
Quick Reference
Access admin panel:
http://your-pi-ip/admin
Update Pi-hole:
cd ~/docker/pihole
docker-compose pull
docker-compose up -d
Update blocklists: Pi-hole admin → Tools → Update Gravity
Restart Pi-hole:
docker-compose restart
View logs:
docker-compose logs -f pihole
Reset admin password:
docker exec pihole pihole -a -p newpassword
Backup configuration: Settings → Teleporter → Backup
