Pi-hole is a network-wide ad blocker that directs all your DNS queries through it, filtering out ads and trackers before they even hit your devices.
Let’s see it in action. Imagine you have a home network and you want to block ads on all your devices without installing software on each one. You can spin up a Pi-hole instance in a Docker container using docker-compose.
Here’s a typical docker-compose.yml file:
version: "3.7"
services:
pihole:
image: pihole/pihole:latest
container_name: pihole
ports:
- "53:53/tcp"
- "53:53/udp"
- "67:67/udp" # Required for DHCP
- "80:80/tcp"
- "443:443/tcp" # For the web interface
environment:
TZ: 'America/New_York'
WEBPASSWORD: 'your_strong_password' # Change this!
# VIRTUAL_HOST: 'pihole.mydomain.com' # Optional: For accessing via a domain
# PIHOLE_DNS_: '1.1.1.1' # Optional: Primary upstream DNS server
# PIHOLE_DNS_2: '1.0.0.1' # Optional: Secondary upstream DNS server
volumes:
- './pihole/etc-pihole/:/etc/pihole/'
- './pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/'
restart: unless-stopped
With this docker-compose.yml in place, you’d run docker-compose up -d. This command downloads the pihole/pihole:latest image and starts a container named pihole. It maps ports 53 (DNS), 67 (DHCP), 80 (web interface), and 443 (web interface with SSL) from your host machine into the container. The volumes section ensures that Pi-hole’s configuration (/etc/pihole/) and custom DNS configurations (/etc/dnsmasq.d/) persist even if the container is recreated. The WEBPASSWORD environment variable sets the password for the Pi-hole web admin interface.
The problem Pi-hole solves is the pervasive nature of online advertising and tracking. Traditionally, ad-blocking happened at the browser level with extensions. Pi-hole elevates this to the network level. By acting as your network’s DNS server, it intercepts every DNS request. If a requested domain is on its blocklist (which can be thousands of domains long), Pi-hole simply doesn’t resolve it, effectively preventing your device from ever connecting to the ad server. This means ads are blocked on all devices on your network – smart TVs, game consoles, phones, tablets – everything that uses your network’s DNS.
Internally, Pi-hole uses dnsmasq as its DNS server by default. When a DNS request comes in, dnsmasq checks it against its configured blocklists. If it’s a match, the request is dropped. If it’s not a match, dnsmasq forwards the request to one of your specified upstream DNS servers (like Cloudflare, Google DNS, or your ISP’s DNS). The response is then sent back to the requesting device. The web interface provides a dashboard to monitor queries, see blocked requests, and manage blocklists.
The key levers you control are:
- Blocklists: You can add or remove lists of domains to block. Pi-hole comes with a default set, but you can subscribe to many community-maintained lists for comprehensive blocking.
- Upstream DNS Servers: You choose where Pi-hole sends legitimate DNS queries. This impacts privacy and potentially speed.
- DHCP Server: Pi-hole can also act as your network’s DHCP server. If you enable this, it assigns IP addresses to devices on your network and automatically configures them to use Pi-hole for DNS. This is a powerful way to ensure all devices use Pi-hole without manual configuration on each one.
- Conditional Forwarding: This feature allows Pi-hole to query your router for local hostnames, so you can see device names in the Pi-hole logs instead of just IP addresses.
When you configure your router or devices to use the Docker host’s IP address as their DNS server, you’re telling them, "When you need to find out where example.com is, ask Pi-hole." Pi-hole then does the heavy lifting of checking its blocklists and forwarding to upstream servers.
A common point of confusion is how Pi-hole handles DHCP. If you enable Pi-hole’s DHCP server (by checking the box in the web UI and setting your network’s IP range), it takes over assigning IP addresses. When it assigns an IP, it also tells the device to use Pi-hole itself as the DNS server. This is a self-reinforcing loop that guarantees all devices getting an IP from Pi-hole will use Pi-hole for DNS. If you don’t enable Pi-hole’s DHCP, you must manually configure your router to use Pi-hole’s IP as the DNS server for all clients, or configure each client individually.
After setting up Pi-hole and configuring your network to use it for DNS, the next thing you’ll likely want to explore is custom DNS records.