Self Hosting 9 min read

Pi-hole Guide: Self-Hosted Network-Wide Ad Blocking & DNS

Suresh S Suresh S
Pi-hole Guide: Self-Hosted Network-Wide Ad Blocking & DNS

Browser ad blockers only protect the browser you installed them in — your smart TV, your phone’s apps, your game console, and every other device on your network are still loading ads and trackers unfiltered. Pi-hole solves this at the network level: it’s a DNS server that sits between every device on your network and the internet, and simply refuses to resolve domains known to serve ads, trackers, and telemetry. Block it once at the router level, and every device on the network benefits, with no extension to install anywhere.

It’s free, open-source, and light enough to run on the Raspberry Pi it’s named after — though a small Docker container on any always-on machine works just as well.

This guide walks through the full Docker deployment, DNS configuration, blocklist management, and securing the admin dashboard.


1. How Pi-hole Works

Every time a device on your network wants to reach a website or app service, it first asks a DNS server to translate the domain name into an IP address. Normally that request goes straight to your ISP’s DNS server or a public one like Google’s. Pi-hole inserts itself into that step: once you point your router (or individual devices) at Pi-hole as their DNS server, every lookup passes through it first.

Pi-hole checks each requested domain against its blocklists — large, regularly updated files of known ad and tracker domains. If the domain is on a blocklist, Pi-hole returns a null response instead of the real IP address, and the ad or tracker simply never loads. Everything else is forwarded on to an upstream DNS provider you choose and resolved normally, so the vast majority of your browsing is unaffected. The whole process adds negligible latency, and because it happens before a connection is ever made, it blocks trackers that browser-based ad blockers can miss entirely, like those embedded in smart TV firmware or mobile apps.

  • DNS Resolver: Answers DNS queries for every device pointed at it, forwarding legitimate requests upstream and sinkholing blocked ones.
  • Blocklist Engine: Maintains and periodically updates lists of ad, tracker, and malware domains from sources you subscribe to.
  • Query Logging: Records every DNS request in a local database, letting you see exactly what each device on your network is trying to reach.
  • Admin Dashboard: A web UI for reviewing statistics, whitelisting/blacklisting domains, and managing blocklists in real time.
  • DHCP Server (optional): Can replace your router’s built-in DHCP server so every device is automatically configured to use Pi-hole for DNS.

2. System Prerequisites

Pi-hole is one of the lightest self-hosted services you can run — its namesake hardware is a Raspberry Pi, after all.

  • CPU: Any single-core ARM or x86_64 processor comfortably handles DNS for a typical home network.
  • RAM: 512 MB minimum; the query log and blocklists rarely push usage much higher on a home network.
  • Storage: Under 1 GB for the application and blocklists; the query database grows slowly and can be pruned.
  • Network: A static local IP for the machine running Pi-hole — devices need a stable address to point their DNS settings at.
  • Software: Docker and Docker Compose installed on a Linux host.

If you haven’t set up Docker yet, our guide on installing Docker on Ubuntu covers the full setup from a clean system.


3. Step-by-Step Docker Installation

Create a dedicated directory for the deployment:

mkdir -p ~/pihole
cd ~/pihole

The Docker Compose File

nano docker-compose.yml
version: "3.8"

services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    environment:
      TZ: "America/New_York"
      WEBPASSWORD: "change-this-password"
    volumes:
      - ./etc-pihole:/etc/pihole
      - ./etc-dnsmasq.d:/etc/dnsmasq.d
    ports:
      - 53:53/tcp
      - 53:53/udp
      - 80:80
    restart: unless-stopped
    cap_add:
      - NET_ADMIN

Explaining the Configuration

  • WEBPASSWORD environment variable: Sets the initial admin dashboard password. Change this to something strong before deploying, since the dashboard controls DNS for your entire network.
  • ./etc-pihole volume: Persists blocklists, query history, and core configuration across restarts and upgrades.
  • ./etc-dnsmasq.d volume: Stores custom DNS configuration, including any local domain overrides you add later.
  • Port 53: The standard DNS port, exposed on both TCP and UDP — this is what devices actually query. It must not conflict with another DNS service already running on the host (systemd-resolved is a common culprit on Ubuntu).
  • Port 80: Serves the admin web dashboard. Like the other guides in this series, you’ll place this behind a reverse proxy in step 6 rather than exposing it directly.
  • NET_ADMIN capability: Required for Pi-hole to manage network-level settings correctly inside the container.

Launch the stack:

sudo docker compose up -d

Check the logs to confirm a clean startup:

sudo docker compose logs -f

4. Initial Setup & Pointing Your Network at Pi-hole

  1. Navigate to http://<YOUR_SERVER_IP>/admin in your browser and log in with the password you set in WEBPASSWORD.
  2. Review the dashboard — it starts blocking immediately using a default blocklist, but no devices are using it yet.
  3. Decide how devices on your network will start using Pi-hole for DNS:
MethodHow It WorksBest For
Router-wide (recommended)Set Pi-hole’s IP as the primary DNS server in your router’s settingsCovers every device automatically, including ones you can’t configure individually
Pi-hole as DHCP serverDisable your router’s DHCP and let Pi-hole assign addresses and DNS togetherNetworks where the router’s DHCP options are too limited to set a custom DNS server
Per-deviceManually set the DNS server in each device’s network settingsTesting on a single device before rolling it out network-wide
  1. After applying the change, run a quick check from a client device — visiting a known ad-heavy site should show noticeably fewer ads, and the Query Log in the Pi-hole dashboard should start showing requests from that device’s IP.

5. Managing Blocklists

Pi-hole ships with a solid default blocklist, but its real strength is how easily you can extend it.

Adding Blocklists

  1. Go to Group Management > Adlists.
  2. Paste in the URL of a reputable blocklist — community-maintained lists covering ads, trackers, and malware domains are widely available and easy to find with a search.
  3. Save, then go to Tools > Update Gravity to pull in and apply the new list.

Whitelisting and Blacklisting

Occasionally a legitimate site breaks because one of its own domains gets caught by a blocklist. Under Domains, you can whitelist that specific domain to exempt it, or manually blacklist an individual domain that’s slipping through your existing lists. Whitelist changes take effect immediately — no need to re-run Gravity.


6. Securing the Dashboard with a Reverse Proxy

Even though the admin dashboard runs on your local network, it’s worth putting it behind the same protection as your other self-hosted services, especially if you ever expose it for remote management. If you’re already running Nginx Proxy Manager for other self-hosted services, our Nginx Proxy Manager security guide covers hardening it properly — the same proxy host pattern applies here:

  1. In Nginx Proxy Manager, add a new Proxy Host.
  2. Set the domain (e.g., pihole.yourdomain.com), forward hostname to your server’s internal IP, and forward port 80.
  3. Enable Force SSL and request a Let’s Encrypt certificate.
  4. Keep the DNS ports (53/tcp and 53/udp) reachable only from your local network — never forward them to the internet, since an openly accessible DNS resolver can be abused for DNS amplification attacks.

Our Linux security commands guide and Fail2Ban guide are useful next steps for locking down the host this container runs on.


7. Adding Redundancy

If the machine running Pi-hole goes offline, every device pointed at it for DNS loses internet name resolution — not just ad blocking. There are two common ways to avoid that single point of failure:

  • Secondary DNS fallback: Set a second DNS server (either a public resolver or a second Pi-hole instance) as the secondary DNS entry on your router. Ad blocking is lost if the primary goes down, but internet access keeps working.
  • A second Pi-hole instance: Running two Pi-hole containers on separate machines, with their block/allow lists kept in sync via Pi-hole’s built-in Teleporter export/import feature, keeps both DNS resolution and ad blocking available even if one host is down.

8. Backing Up Your Pi-hole Data

Pi-hole’s built-in Teleporter feature bundles your blocklists, whitelist/blacklist entries, and settings into a single archive, which is the simplest way to back up or migrate a configuration:

#!/bin/bash
BACKUP_DIR="/home/suresh/pihole/backups"
TIMESTAMP=$(date +%F)
mkdir -p "$BACKUP_DIR"

# Export the Teleporter archive from inside the container
docker exec pihole pihole-FTL --teleporter "$BACKUP_DIR/pihole_$TIMESTAMP.tar.gz"

# Retain only the last 14 days of backups
find "$BACKUP_DIR" -type f -name "pihole_*.tar.gz" -mtime +14 -delete

Schedule it with cron for daily execution, and sync the backup directory offsite using the same rsync pattern covered in our self-hosted backup strategies guide.


9. Troubleshooting & Maintenance

Issue / SymptomPrimary CauseTroubleshooting / Diagnostic Action
Container won’t bind to port 53Another DNS service already running on the hostDisable or reconfigure systemd-resolved (common on Ubuntu) before starting the container.
Devices still show ads after setupRouter or device not actually using Pi-hole for DNSConfirm the device’s DNS server in its network settings, and check the Query Log to see if its requests appear at all.
Legitimate website breaks or fails to loadA domain it depends on is caught by a blocklistCheck the Query Log for the blocked domain and whitelist it if it’s necessary for the site to function.
Dashboard unreachable after updateContainer failed to restart cleanlyCheck docker compose logs -f for errors and confirm the etc-pihole volume wasn’t corrupted during the update.
Query Log grows very largeLong-term logging with no retention limit setSet a log retention period under Settings > Privacy to automatically prune older entries.

10. Pi-hole vs. Alternatives

Feature / MetricPi-holeAdGuard HomeRouter-Level Ad Blocking
Hosting ModelSelf-hostedSelf-hostedBuilt into router firmware
DNS + DHCP ServerYesYesVaries by router
Blocklist CustomizationExtensive, community listsExtensive, community listsUsually limited or fixed
HTTPS/DNS-over-HTTPS SupportVia add-on configurationBuilt-inRare
InterfaceDashboard-focused, detailed query logDashboard-focused, similar depthMinimal, router-dependent
CostFreeFreeFree (included with router)

11. Conclusion

Pi-hole turns network-level ad and tracker blocking from a per-browser chore into a one-time setup that covers every device you own, including the ones you can’t install an extension on. Paired with a hardened reverse proxy, a second DNS fallback, and a regular Teleporter backup, it becomes one of the lowest-maintenance, highest-impact pieces of a self-hosted stack.

Once your network-wide blocking is live, make sure the rest of your self-hosted stack is watching over it too. Check out our guides on setting up Uptime Kuma monitoring and the complete home server security checklist to keep tabs on what’s running alongside Pi-hole.

Suresh S

Written by Suresh S

Systems Engineer & Tech Educator with 10+ years of experience in Linux Administration, Cloud Computing, and Cybersecurity. Founder of FreeTechLearner, dedicated to creating practical tutorials that help students and professionals build real-world skills.

Share this post:

Discussion

Loading comments...