Pi-hole Complete Setup Guide 2026: Network-Wide Ad Blocking & DNS Management
Published on January 12, 2026
Introduction
Pi-hole is a powerful, open-source network-wide ad blocker that acts as a DNS sinkhole, protecting all devices on your network from unwanted advertisements, trackers, and malicious domains. Unlike browser-based ad blockers, Pi-hole works at the DNS level, blocking ads before they even reach your devices—including smart TVs, IoT devices, and mobile apps where traditional ad blockers cannot be installed.
Pi-hole is free, open-source (licensed under GPLv2), and community-driven, ensuring no data collection beyond what’s needed for operation. It supports IPv4 and IPv6, caches DNS queries for faster resolution, and includes an optional built-in DHCP server for automatic device configuration.
💡 Current Version: As of January 2026, the latest stable releases are Pi-hole Core v6.3, FTL v6.4, and Web Interface v6.4. Always check the official GitHub releases for the most current version before installation.
This comprehensive guide covers every aspect of Pi-hole deployment, from basic installation on a Raspberry Pi to advanced configurations including Docker deployment, recursive DNS with Unbound, VPN integration, NAS installation, high availability setups, and Home Assistant integration. We’ll explain every command, what it does, and provide platform-specific instructions for Windows, macOS, and Linux.
What is Pi-hole?
Pi-hole intercepts DNS requests from devices on your network and checks them against blocklists containing known advertising, tracking, and malicious domains. If a request matches a blocked domain, Pi-hole returns a null response, effectively “sinking” the request into a black hole—hence the name.
+-------------------------------------------------------------------+
| HOW PI-HOLE WORKS |
+-------------------------------------------------------------------+
| |
| +----------+ DNS Request +--------------+ |
| | Device | -------------------> | Pi-hole | |
| | (Phone, | "ads.com?" | (DNS | |
| | TV, PC) | | Server) | |
| +----------+ +------+-------+ |
| | |
| +----------------+----------------+ |
| | | |
| v v |
| +---------------+ +-------------+ |
| | On Blocklist | | Not Blocked | |
| | (Blocked) | | (Allowed) | |
| +-------+-------+ +------+------+ |
| | | |
| v v |
| +---------------+ +-------------+ |
| | Returns 0.0.0.0| | Forwards to | |
| | (Ad Blocked!) | | Upstream DNS| |
| +---------------+ +-------------+ |
| |
+-------------------------------------------------------------------+ Key Features
| Feature | Description |
|---|---|
| Network-Wide Blocking | Blocks ads and trackers for ALL devices (browsers, apps, smart TVs, IoT) without per-device setup |
| Web Dashboard | Responsive UI for stats, query logs, long-term data, audit logs, and privacy controls |
| DNS Caching | Caches DNS results locally for faster response times on frequently accessed domains |
| Custom Blocklists | Add or remove domains from blocklists with regex support for fine-tuned blocking |
| DHCP Server | Optional built-in DHCP server for automatic client configuration |
| Privacy Modes | Four privacy levels: show everything, hide domains, hide domains and clients, or anonymous mode |
| API & CLI | Full REST API and command-line interface for scripting and automation |
| IPv4 & IPv6 | Full support for both IPv4 and IPv6 networks |
| Low Resource Usage | Can run on a Raspberry Pi Zero W using ~50MB of RAM |
| Scalability | Handles millions of queries on server hardware |
📊 Performance: Users typically report 15-30% faster page loads and significant privacy gains from reduced tracker connections.
Pi-hole v6 New Features (February 2025)
Pi-hole v6 introduced major architectural changes:
| Feature | Description |
|---|---|
| Embedded Web Server | No longer requires lighttpd or PHP—integrated directly into pihole-FTL |
| Native HTTPS Support | Built-in SSL/TLS support for secure admin interface access |
| REST API | New comprehensive REST API replacing the legacy PHP-based API |
| TOML Configuration | Single, richly commented configuration file for easier management |
| Subscribed Allowlists | “Antigravity” feature for maintaining curated allowlists |
| Redesigned UI | Modern interface with Basic and Expert modes |
Who Is This Guide For?
- Home users wanting to block ads on all devices
- Privacy enthusiasts seeking to reduce online tracking
- Home lab enthusiasts building network infrastructure
- Parents implementing network-level content filtering
- IT professionals managing small business networks
Estimated Time
| Installation Method | Estimated Time |
|---|---|
| Bare Metal (Raspberry Pi) | 20-30 minutes |
| Docker (Linux) | 15-20 minutes |
| Docker (Windows/macOS) | 30-45 minutes |
| Proxmox LXC | 30-45 minutes |
| Synology NAS | 20-30 minutes |
| With Unbound Setup | Add 15-20 minutes |
Part 1: System Requirements
Hardware Requirements
Pi-hole is extremely lightweight and can run on minimal hardware:
| Component | Minimum | Recommended | Notes |
|---|---|---|---|
| RAM | 512 MB | 1-2 GB | More RAM helps with large blocklists |
| Storage | 2 GB | 4+ GB | SSD recommended for faster performance |
| CPU | 1 core | 2+ cores | Any modern CPU is sufficient |
| Network | Any | Wired Ethernet | Wi-Fi works but wired is more reliable |
Raspberry Pi Model Recommendations
| Model | Suitability | Notes |
|---|---|---|
| Raspberry Pi Zero 2 W | ✅ Excellent | Best budget option, low power, sufficient performance |
| Raspberry Pi 3 B/B+ | ✅ Excellent | Good balance with built-in Ethernet |
| Raspberry Pi 4 B | ✅ Overkill | Only needed if running additional services |
| Raspberry Pi 5 | ✅ Overkill | Best for multi-service setups |
| Raspberry Pi Zero W | ⚠️ Adequate | Works but Zero 2 W is preferred |
💡 Tip: For dedicated Pi-hole use, the Raspberry Pi Zero 2 W with a USB Ethernet adapter is the most cost-effective option.
Software Requirements
| Component | Required Version | Purpose |
|---|---|---|
| Operating System | See supported list | Host for Pi-hole |
| Docker | 20.10+ | For containerized installations |
| Docker Compose | v2.0+ | Multi-container orchestration |
Supported Operating Systems
Pi-hole officially supports actively maintained versions of:
- Alpine Linux
- Armbian OS
- Debian (10+)
- CentOS Stream
- Fedora
- Raspberry Pi OS (formerly Raspbian)
- Ubuntu (20.04+)
Supported Architectures
Pre-built binaries are available for:
- x86_64 (amd64 and i686)
- armv6 (Raspberry Pi Zero/1)
- armv7 (Raspberry Pi 2/3)
- armv8/aarch64 (Raspberry Pi 3/4/5 64-bit)
- riscv64
Network Requirements
| Requirement | Details |
|---|---|
| Static IP Address | Pi-hole must have a static IP (DHCP reservation acceptable) |
| Port 53 | DNS queries (TCP/UDP) |
| Port 80/443 | Web interface (or custom port) |
| Port 67 | DHCP server (optional) |
| Port 123 | NTP server (optional) |
Part 2: General Use Cases
Pi-hole’s primary role is ad and tracker blocking, but its DNS capabilities extend to broader applications for home and enterprise environments.
Primary Use Cases
| Use Case | Description |
|---|---|
| Ad Blocking in Apps | Blocks ads in mobile apps, games, smart TVs, and streaming devices where browser extensions can’t reach |
| Privacy Enhancement | Prevents tracking by sinkholing domains from telemetry services (Google Analytics, Facebook trackers) |
| Parental Controls | Block adult content, gambling, or social media sites via custom blocklists |
| Bandwidth Optimization | Reduces data usage by stopping ad downloads—useful for metered connections or mobile hotspots |
| Network Monitoring | Logs DNS queries to identify unusual activity, like malware phoning home |
| Enterprise Filtering | In small offices or schools, filter phishing and malware domains |
| IoT Security | Protects smart devices from connecting to malicious or telemetry servers |
| VPN Integration | Pair with VPN for ad-free mobile use outside your home network |
Home Lab Capabilities with Examples
In a home lab or personal setup, Pi-hole shines as a low-maintenance tool for network management:
| Capability | Description | Example |
|---|---|---|
| DNS Caching & Forwarding | Speeds up repeated queries; forwards legit requests to upstream DNS | Configure Cloudflare (1.1.1.1) as upstream for faster resolution |
| DHCP Server | Assigns IPs and auto-configures DNS for devices | Enable DHCP in Pi-hole to simplify device setup |
| Query Analysis | Dashboard shows top blocked domains, clients, and query types | Use query log to troubleshoot why a site isn’t working |
| Custom Blocking | Add regex for patterns | Block all *.ads.example.com with a single regex rule |
| High Availability | Run multiple instances with sync tools for redundancy | Two Pi-holes with Orbital Sync for fault tolerance |
| Resource Efficiency | Runs alongside other services on shared hardware | Combine with Unbound on the same Raspberry Pi |
Real-World Examples:
Basic Ad Blocking: A family runs Pi-hole and sees no ads on their Roku, smart TV apps, and mobile games—blocking 100,000+ domains out-of-the-box.
IoT Monitoring: Log queries from smart bulbs and cameras to detect anomalies. Block a compromised camera from contacting external servers.
Custom Filters: Whitelist a site if blocking breaks functionality (e.g., allow
cdn.example.comfor a game). Use the audit log to identify and tweak.Privacy Testing: Experiment with privacy modes; e.g., anonymous mode hides client IPs in logs for GDPR-like compliance testing.
Part 3: Pre-Installation Preparation
Before installing Pi-hole, complete these preparation steps on your target system.
Step 1: Update Your System
Always start with an updated system to avoid compatibility issues.
Linux (Debian/Ubuntu/Raspberry Pi OS)
# Update package lists and upgrade all packages
sudo apt update && sudo apt full-upgrade -y
# Explanation:
# - sudo: Run with administrator privileges
# - apt update: Refreshes the list of available packages
# - apt full-upgrade: Installs newer versions (handles dependencies better than upgrade)
# - -y: Automatically answer "yes" to prompts Linux (Fedora/RHEL/CentOS)
sudo dnf update -y Linux (Alpine)
sudo apk update && sudo apk upgrade macOS
# Update macOS
softwareupdate -i -a
# If using Homebrew, also run:
brew update && brew upgrade Windows
- Open Settings → Update & Security → Windows Update
- Click Check for updates
- Install all available updates
- Restart if prompted
Step 2: Set a Static IP Address
Pi-hole requires a static IP address for reliable DNS service.
Linux (NetworkManager - GUI)
- Open Settings → Network → Wired/Wi-Fi → Settings (gear icon)
- Select IPv4 tab
- Change Method to Manual
- Enter:
- Address:
192.168.1.100(example) - Netmask:
255.255.255.0 - Gateway:
192.168.1.1(your router)
- Address:
- Click Apply
Linux (Command Line - Debian/Ubuntu)
Edit /etc/network/interfaces or use netplan:
# For netplan (Ubuntu 18.04+)
sudo nano /etc/netplan/01-netcfg.yaml network:
version: 2
ethernets:
eth0:
dhcp4: no
addresses:
- 192.168.1.100/24
gateway4: 192.168.1.1
nameservers:
addresses:
- 8.8.8.8
- 8.8.4.4 # Apply configuration
sudo netplan apply Raspberry Pi OS
sudo nano /etc/dhcpcd.conf Add at the end:
interface eth0
static ip_address=192.168.1.100/24
static routers=192.168.1.1
static domain_name_servers=8.8.8.8 8.8.4.4 # Restart networking
sudo systemctl restart dhcpcd macOS
- Open System Preferences → Network
- Select your connection → Advanced → TCP/IP
- Change Configure IPv4 to Manually
- Enter your IP, Subnet Mask, and Router
- Click OK → Apply
Windows
- Open Control Panel → Network and Sharing Center
- Click your connection → Properties
- Select Internet Protocol Version 4 (TCP/IPv4) → Properties
- Select Use the following IP address
- Enter your IP, Subnet mask, and Default gateway
- Click OK
Step 3: Configure Firewall
Open required ports for Pi-hole.
Linux (UFW - Ubuntu/Debian)
# Allow DNS traffic
sudo ufw allow 53/tcp
sudo ufw allow 53/udp
# Allow web interface
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# If using Pi-hole's DHCP
sudo ufw allow 67/udp
# Check status
sudo ufw status Linux (firewalld - Fedora/RHEL)
sudo firewall-cmd --permanent --add-service=dns
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-service=dhcp
sudo firewall-cmd --reload Linux (iptables)
# Accept DNS
sudo iptables -A INPUT -p tcp --dport 53 -s 192.168.0.0/16 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 53 -s 192.168.0.0/16 -j ACCEPT
# Accept HTTP/HTTPS
sudo iptables -A INPUT -p tcp --dport 80 -s 192.168.0.0/16 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -s 192.168.0.0/16 -j ACCEPT
# Save rules
sudo iptables-save | sudo tee /etc/iptables/rules.v4 Windows Firewall
# Run PowerShell as Administrator
# Allow DNS
New-NetFirewallRule -DisplayName "Pi-hole DNS TCP" -Direction Inbound -Protocol TCP -LocalPort 53 -Action Allow
New-NetFirewallRule -DisplayName "Pi-hole DNS UDP" -Direction Inbound -Protocol UDP -LocalPort 53 -Action Allow
# Allow Web Interface
New-NetFirewallRule -DisplayName "Pi-hole HTTP" -Direction Inbound -Protocol TCP -LocalPort 80 -Action Allow
New-NetFirewallRule -DisplayName "Pi-hole HTTPS" -Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow Part 3: Bare Metal Installation (Linux)
This is the recommended installation method for Raspberry Pi and dedicated Linux servers.
Step 1: Run the Pi-hole Installer
The official one-step installer handles everything automatically:
curl -sSL https://install.pi-hole.net | sudo bash Command Breakdown:
curl: Command-line tool for downloading from URLs-sSL: Silent mode with error display, follow redirectshttps://install.pi-hole.net: Official installer script| sudo bash: Pipes the script to bash with admin privileges
⚠️ Security Note: While convenient, piping to bash can be risky. For maximum security, download and review the script first:
# Download first, review, then run
curl -sSL https://install.pi-hole.net -o pihole-install.sh
cat pihole-install.sh # Review the script
sudo bash pihole-install.sh Step 2: Follow the Installation Wizard
The interactive installer will guide you through:
Static IP Confirmation: Confirms your static IP configuration
Upstream DNS Provider: Choose your preferred DNS resolver:
- Google (8.8.8.8, 8.8.4.4)
- OpenDNS (208.67.222.222)
- Cloudflare (1.1.1.1) - Recommended for speed
- Quad9 (9.9.9.9) - Security-focused
- Custom - For Unbound or other local resolvers
Blocklists: Accept default blocklists (StevenBlack’s unified hosts)
Admin Web Interface: Install the web interface (highly recommended)
Web Server: Install lighttpd (for Pi-hole v5) or use built-in (v6+)
Query Logging: Enable logging for troubleshooting
Privacy Mode: Choose your FTL privacy level:
- 0: Show everything
- 1: Hide domains
- 2: Hide domains and clients
- 3: Anonymous mode
Step 3: Note Your Admin Password
At the end of installation, Pi-hole generates a random admin password:
[✓] Installation complete!
Configure your router's DHCP options to use Pi-hole as the DNS server
or set Pi-hole's IP address as the DNS on individual devices.
Pi-hole web interface: http://192.168.1.100/admin
Admin password: [randomly generated password]
Your password can be changed using 'pihole -a -p' Change the password immediately:
# Set a new admin password
pihole -a -p
# You'll be prompted to enter a new password twice Step 4: Verify Installation
# Check Pi-hole status
pihole status
# Expected output:
# [✓] FTL is running
# [✓] Pi-hole blocking is enabled
# Test DNS resolution
dig @127.0.0.1 example.com
# Check version
pihole -v Step 5: Access the Web Interface
- Open your web browser
- Navigate to:
http://YOUR_PI_IP/adminorhttp://pi.hole/admin - Log in with your admin password
- Explore the dashboard!
Part 4: Docker Installation
Docker provides isolated, portable, and easily updatable Pi-hole deployments.
Method 1: Docker on Linux
Step 1: Install Docker
# Remove old versions
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do
sudo apt-get remove -y $pkg 2>/dev/null
done
# Install prerequisites
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
# Add Docker's official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg |
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add Docker repository
echo
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" |
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker Engine
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
docker-buildx-plugin docker-compose-plugin
# Add your user to docker group (optional, avoids sudo)
sudo usermod -aG docker $USER
newgrp docker
# Verify installation
docker --version
docker compose version Step 2: Create Project Directory
mkdir -p ~/pihole
cd ~/pihole Step 3: Create docker-compose.yml
nano docker-compose.yml services:
pihole:
container_name: pihole
image: pihole/pihole:latest
ports:
# DNS ports
- "53:53/tcp"
- "53:53/udp"
# Web interface ports (change left side if port conflicts)
- "80:80/tcp"
- "443:443/tcp"
# Uncomment for DHCP (requires --cap-add=NET_ADMIN)
# - "67:67/udp"
environment:
# Set your timezone
TZ: 'America/New_York'
# Set a strong admin password
FTLCONF_webserver_api_password: 'your-secure-password-here'
# Upstream DNS (Cloudflare example)
FTLCONF_dns_upstreams: '1.1.1.1;1.0.0.1'
volumes:
# Persistent data storage
- './etc-pihole:/etc/pihole'
- './etc-dnsmasq.d:/etc/dnsmasq.d'
cap_add:
# Required for DHCP functionality
- NET_ADMIN
restart: unless-stopped Environment Variable Explanations:
| Variable | Purpose | Example |
|---|---|---|
TZ | Timezone for logs and UI | America/New_York, Europe/London |
FTLCONF_webserver_api_password | Admin interface password | Strong password |
FTLCONF_dns_upstreams | Upstream DNS servers | 1.1.1.1;1.0.0.1 |
Step 4: Create Data Directories
mkdir -p etc-pihole etc-dnsmasq.d Step 5: Start Pi-hole
# Pull the image and start
docker compose up -d
# Check container status
docker compose ps
# View logs
docker compose logs -f pihole Step 6: Access the Web Interface
Navigate to http://YOUR_SERVER_IP/admin and log in.
Method 2: Docker on Windows (WSL2)
Prerequisites
- Windows 10 (version 2004+) or Windows 11
- WSL2 enabled
- Docker Desktop installed
Step 1: Enable WSL2
Open PowerShell as Administrator:
# Enable WSL feature
wsl --install
# Restart your computer when prompted
# After restart, WSL will complete installation Step 2: Install Docker Desktop
- Download Docker Desktop from docker.com
- Run the installer
- Check “Use WSL 2 instead of Hyper-V”
- Complete installation and restart
Step 3: Configure Docker Desktop
- Open Docker Desktop
- Go to Settings → Resources → WSL Integration
- Enable integration with your default distro
- Click Apply & Restart
Step 4: Create Project Directory
Open PowerShell:
# Create directory
mkdir C:Users$env:USERNAMEDocumentsDockerpihole
cd C:Users$env:USERNAMEDocumentsDockerpihole
# Create subdirectories
New-Item -ItemType Directory -Path etc-pihole, etc-dnsmasq.d -Force Step 5: Create docker-compose.yml
notepad docker-compose.yml Paste the same YAML content from Method 1, but adjust volume paths:
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
ports:
- "53:53/tcp"
- "53:53/udp"
- "8080:80/tcp" # Changed to avoid conflicts
- "8443:443/tcp"
environment:
TZ: 'America/New_York'
FTLCONF_webserver_api_password: 'your-secure-password-here'
FTLCONF_dns_upstreams: '1.1.1.1;1.0.0.1'
volumes:
- './etc-pihole:/etc/pihole'
- './etc-dnsmasq.d:/etc/dnsmasq.d'
cap_add:
- NET_ADMIN
restart: unless-stopped ⚠️ Port 80 Conflict: Windows often uses port 80 for IIS or other services. We use 8080 instead.
Step 6: Start Pi-hole
docker compose up -d
docker compose ps Step 7: Configure Windows DNS
To use Pi-hole as your DNS:
- Open Control Panel → Network and Sharing Center
- Click your connection → Properties
- Select Internet Protocol Version 4 → Properties
- Select Use the following DNS server addresses
- Enter your Pi-hole IP (use
127.0.0.1if running locally)
Access the web interface at http://localhost:8080/admin
Method 3: Docker on macOS
Step 1: Install Docker Desktop
- Download Docker Desktop for Mac from docker.com
- Apple Silicon (M1/M2/M3/M4): Download “Apple Chip” version
- Intel Macs: Download “Intel Chip” version
- Drag Docker.app to Applications
- Launch Docker from Applications
Step 2: Configure Resources
- Docker Desktop → Settings → Resources
- Allocate at least 2GB RAM (4GB recommended)
- Click Apply & Restart
Step 3: Create Project Directory
mkdir -p ~/pihole
cd ~/pihole
mkdir -p etc-pihole etc-dnsmasq.d Step 4: Create docker-compose.yml
nano docker-compose.yml Use the same YAML as Linux, but change ports to avoid conflicts:
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
ports:
- "5353:53/tcp" # macOS uses port 53 for mDNSResponder
- "5353:53/udp"
- "8080:80/tcp"
- "8443:443/tcp"
environment:
TZ: 'America/Los_Angeles'
FTLCONF_webserver_api_password: 'your-secure-password-here'
FTLCONF_dns_upstreams: '1.1.1.1;1.0.0.1'
volumes:
- './etc-pihole:/etc/pihole'
- './etc-dnsmasq.d:/etc/dnsmasq.d'
cap_add:
- NET_ADMIN
restart: unless-stopped ⚠️ macOS Port 53: macOS uses port 53 for mDNSResponder (Bonjour). We use 5353 instead.
Step 5: Start Pi-hole
docker compose up -d
docker compose ps Step 6: Configure macOS DNS
To use Pi-hole (with custom port):
- Open System Preferences → Network
- Select your connection → Advanced → DNS
- Add
127.0.0.1as DNS server - Then configure your router to point to your Mac’s IP
Access the web interface at http://localhost:8080/admin
Part 5: NAS & Virtualization Installations
Synology NAS (Docker/Container Manager)
Prerequisites
- Synology DSM 7.0+ with Container Manager installed
- SSH access enabled (optional but helpful)
Step 1: Install Container Manager
- Open Package Center
- Search for “Container Manager” (or “Docker” on older DSM)
- Click Install
Step 2: Create Folders
- Open File Station
- Navigate to your docker share (create one if needed)
- Create folder structure:
docker/ └── pihole/ ├── etc-pihole/ └── etc-dnsmasq.d/
Step 3: Create Project
- Open Container Manager → Project
- Click Create
- Enter name:
pihole - Set path:
/volume1/docker/pihole - Select Create docker-compose.yml
Step 4: Enter Docker Compose Configuration
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
ports:
- "53:53/tcp"
- "53:53/udp"
- "8082:80/tcp" # Changed to avoid DSM conflicts
- "4443:443/tcp"
environment:
TZ: 'America/New_York'
FTLCONF_webserver_api_password: 'your-secure-password'
FTLCONF_dns_upstreams: '1.1.1.1;1.0.0.1'
PIHOLE_UID: '1026' # Match your Synology user ID
PIHOLE_GID: '100'
volumes:
- '/volume1/docker/pihole/etc-pihole:/etc/pihole'
- '/volume1/docker/pihole/etc-dnsmasq.d:/etc/dnsmasq.d'
cap_add:
- NET_ADMIN
restart: unless-stopped 💡 Finding UID/GID: SSH into Synology and run
idto find your user’s UID/GID
Step 5: Build and Start
- Click Next → Done
- Container Manager will pull images and start Pi-hole
- Access at
http://SYNOLOGY_IP:8082/admin
Proxmox LXC Container
LXC containers are lighter than VMs and perfect for Pi-hole.
Step 1: Download Template
# SSH into Proxmox host
pveam update
pveam available | grep debian
pveam download local debian-12-standard_12.2-1_amd64.tar.zst Step 2: Create LXC Container
Using Proxmox web UI:
- Click Create CT
- General Tab:
- CT ID:
100(or next available) - Hostname:
pihole - Password: Set root password
- Check Unprivileged container
- CT ID:
- Template: Select
debian-12-standard - Disk: 4-8 GB
- CPU: 1-2 cores
- Memory: 512-1024 MB
- Network:
- Bridge:
vmbr0 - IPv4: Static IP (e.g.,
192.168.1.100/24) - Gateway:
192.168.1.1
- Bridge:
- DNS: Use host settings or
8.8.8.8 - Check Start at boot
- Under Options: Enable Nesting (required for Pi-hole)
Step 3: Start Container and Install Pi-hole
# Start the container
pct start 100
# Enter the container console
pct console 100
# Update system
apt update && apt upgrade -y
# Install curl
apt install curl -y
# Install Pi-hole
curl -sSL https://install.pi-hole.net | bash Follow the installation wizard as described in Part 3.
Step 4: Set Admin Password
pihole -a -p Access at http://192.168.1.100/admin
Part 6: Unbound Recursive DNS Setup
Unbound is a validating, recursive, caching DNS resolver that allows Pi-hole to resolve DNS queries directly from root servers, enhancing privacy by not relying on third-party DNS providers.
Why Use Unbound with Pi-hole?
| Benefit | Description |
|---|---|
| Maximum Privacy | DNS queries never leave your network to third parties |
| DNSSEC Validation | Validates DNS responses for authenticity |
| Reduced Latency | Local caching improves repeat query speed |
| Independence | No reliance on Google, Cloudflare, or other providers |
Installation
Step 1: Install Unbound
Linux (Debian/Ubuntu)
sudo apt update
sudo apt install unbound -y Linux (Fedora/RHEL)
sudo dnf install unbound -y Linux (Alpine)
sudo apk add unbound Step 2: Download Root Hints
Root hints tell Unbound where to find the root DNS servers:
# Download root hints
sudo wget -O /var/lib/unbound/root.hints https://www.internic.net/domain/named.root
# Verify download
ls -la /var/lib/unbound/root.hints 💡 Tip: Update root hints every 6 months. Add to crontab:
echo "0 0 1 */6 * root wget -O /var/lib/unbound/root.hints https://www.internic.net/domain/named.root" | sudo tee -a /etc/crontab
Step 3: Configure Unbound for Pi-hole
Create Pi-hole specific configuration:
sudo nano /etc/unbound/unbound.conf.d/pi-hole.conf server:
# Listen on localhost, port 5335 (Pi-hole will use 53)
interface: 127.0.0.1
port: 5335
# Allow queries from localhost only
access-control: 127.0.0.0/8 allow
# Enable IPv4 and disable IPv6 (adjust if you use IPv6)
do-ip4: yes
do-ip6: no
do-udp: yes
do-tcp: yes
# Security hardening
harden-glue: yes
harden-dnssec-stripped: yes
harden-large-queries: yes
harden-algo-downgrade: yes
# Privacy settings
qname-minimisation: yes
use-caps-for-id: yes
# Root hints file location
root-hints: "/var/lib/unbound/root.hints"
# Cache settings
cache-min-ttl: 3600
cache-max-ttl: 86400
prefetch: yes
prefetch-key: yes
# Performance
num-threads: 2
msg-cache-size: 50m
rrset-cache-size: 100m
# Logging (minimal by default)
verbosity: 0
# Private addresses - don't forward
private-address: 192.168.0.0/16
private-address: 169.254.0.0/16
private-address: 172.16.0.0/12
private-address: 10.0.0.0/8 Step 4: Start Unbound
# Restart Unbound
sudo systemctl restart unbound
# Enable on boot
sudo systemctl enable unbound
# Check status
sudo systemctl status unbound Step 5: Test Unbound
# Test DNS resolution through Unbound
dig example.com @127.0.0.1 -p 5335
# Expected output should show NOERROR status
# ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: xxxxx Step 6: Configure Pi-hole to Use Unbound
- Open Pi-hole web interface (
http://pi.hole/admin) - Go to Settings → DNS
- Uncheck all default upstream DNS servers
- Under Custom 1 (IPv4), enter:
127.0.0.1#5335 - Check Use DNSSEC (Unbound handles validation)
- Click Save
Docker Unbound + Pi-hole Setup
For Docker environments, run both containers:
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
depends_on:
- unbound
ports:
- "53:53/tcp"
- "53:53/udp"
- "80:80/tcp"
environment:
TZ: 'America/New_York'
FTLCONF_webserver_api_password: 'your-password'
FTLCONF_dns_upstreams: 'unbound#5335'
volumes:
- './etc-pihole:/etc/pihole'
- './etc-dnsmasq.d:/etc/dnsmasq.d'
restart: unless-stopped
networks:
- pihole_net
unbound:
container_name: unbound
image: mvance/unbound:latest
volumes:
- './unbound:/opt/unbound/etc/unbound'
restart: unless-stopped
networks:
- pihole_net
networks:
pihole_net:
driver: bridge Part 7: Configuring Your Network
After installing Pi-hole, you need to configure your network to use it as the DNS server.
Option 1: Router DNS Configuration (Recommended)
This ensures ALL devices automatically use Pi-hole.
General Router Steps
- Log into your router’s admin interface
- Find DHCP Settings or LAN Settings
- Change Primary DNS to your Pi-hole’s IP address
- Leave Secondary DNS blank (or set to Pi-hole’s IP)
- Save and restart router
⚠️ Important: Leaving Secondary DNS as another provider (like 8.8.8.8) allows devices to bypass Pi-hole!
Option 2: Use Pi-hole’s DHCP Server
If your router doesn’t allow DNS changes, Pi-hole can serve DHCP:
- Disable your router’s DHCP server first
- In Pi-hole: Settings → DHCP
- Check DHCP server enabled
- Configure:
- Range of addresses to assign
- Router IP (gateway)
- Lease time
- Click Save
Option 3: Static DNS on Devices
Configure individual devices to use Pi-hole:
Windows
# View current DNS
ipconfig /all
# Set DNS (replace with your adapter name)
netsh interface ip set dns "Wi-Fi" static 192.168.1.100 primary Or via GUI: Network Settings → Advanced → DNS
macOS
# Set DNS
sudo networksetup -setdnsservers Wi-Fi 192.168.1.100
# Verify
scutil --dns Linux
Edit /etc/resolv.conf or NetworkManager settings:
nameserver 192.168.1.100 iOS
Settings → Wi-Fi → [Network] → Configure DNS → Manual → Add 192.168.1.100
Android
Settings → Network → Wi-Fi → [Network] → Advanced → IP Settings → Static → DNS 1: 192.168.1.100
Part 8: Blocklists Management
Pi-hole’s effectiveness depends on quality blocklists.
Recommended Blocklists (2026)
| Blocklist | Focus | URL |
|---|---|---|
| HaGeZi Multi Pro | Ads, tracking, malware | https://raw.githubusercontent.com/hagezi/dns-blocklists/main/adblock/pro.txt |
| OISD | Comprehensive | https://abp.oisd.nl/ |
| StevenBlack Unified | Ads + malware | https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts |
| Firebog Tick List | Curated safe lists | Multiple lists at firebog.net |
Adding Blocklists
- Go to Group Management → Adlists
- Enter the blocklist URL in the Address field
- Add a descriptive Comment
- Click Add
- Run Tools → Update Gravity to activate
Command Line Management
# Update blocklists (gravity)
pihole -g
# Add a blocklist
pihole -a adlist add https://example.com/blocklist.txt
# View current lists
pihole -a adlist list Whitelisting Domains
Sometimes Pi-hole blocks legitimate sites:
# Add to whitelist
pihole -w example.com
# Remove from whitelist
pihole -w -d example.com
# Add to blacklist
pihole -b example.com Via Web UI: Domains → Add domain → Select Whitelist
Part 9: VPN Integration
WireGuard + Pi-hole
Use Pi-hole for ad blocking when away from home.
Step 1: Install WireGuard
# Debian/Ubuntu
sudo apt install wireguard -y
# Generate keys
wg genkey | tee privatekey | wg pubkey > publickey Step 2: Configure WireGuard Server
sudo nano /etc/wireguard/wg0.conf [Interface]
PrivateKey = YOUR_PRIVATE_KEY
Address = 10.0.0.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# Use Pi-hole as DNS
DNS = 192.168.1.100
[Peer]
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32 Step 3: Start WireGuard
sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0 Step 4: Configure Pi-hole for VPN Clients
In Pi-hole: Settings → DNS → Interface settings:
- Select Permit all origins to allow VPN client queries
Tailscale + Pi-hole
Tailscale simplifies VPN setup with automatic NAT traversal.
Step 1: Install Tailscale
# Install Tailscale
curl -fsSL https://tailscale.com/install.sh | sh
# Authenticate
sudo tailscale up Step 2: Get Pi-hole’s Tailscale IP
tailscale ip -4
# Example output: 100.x.x.x Step 3: Configure Tailscale DNS
- Log into Tailscale Admin Console
- Under Global nameservers, add your Pi-hole’s Tailscale IP:
100.x.x.x - Enable Override local DNS
Step 4: Configure Pi-hole
In Pi-hole Settings → DNS → Interface settings:
- Select Permit all origins
Or specifically add the Tailscale interface (tailscale0)
Now all Tailscale-connected devices use Pi-hole!
Part 10: Home Assistant Integration
Pi-hole integrates with Home Assistant for automation and monitoring.
Setup Integration
- In Home Assistant: Settings → Devices & Services → Add Integration
- Search for Pi-hole
- Enter:
- Host: Pi-hole IP address
- Port: 80 (or your custom port)
- API Key/Password: Found in Pi-hole under Settings → API (expert mode)
- Click Submit
Available Entities
| Entity Type | Name | Function |
|---|---|---|
| Switch | switch.pi_hole | Enable/disable blocking |
| Sensor | sensor.pi_hole_ads_blocked_today | Daily blocked count |
| Sensor | sensor.pi_hole_ads_percentage_blocked_today | Block percentage |
| Sensor | sensor.pi_hole_dns_queries_today | Total queries |
| Sensor | sensor.pi_hole_domains_blocked | Blocklist size |
Example Automation
Disable Pi-hole for 5 minutes when a button is pressed:
automation:
- alias: "Temporarily Disable Pi-hole"
trigger:
- platform: state
entity_id: input_button.disable_pihole
action:
- service: switch.turn_off
entity_id: switch.pi_hole
- delay: "00:05:00"
- service: switch.turn_on
entity_id: switch.pi_hole Part 11: Backup, Restore & Migration
Teleporter Backup
Pi-hole’s built-in backup tool:
Web Interface
- Go to Settings → Teleporter
- Click Backup to download
.tar.gzfile - Store safely off-device
Command Line
# Create backup
pihole -a -t
# Creates file like:
# pi-hole-ubuntu-teleporter_2026-01-12_20-30-00.tar.gz Automated Backups
Add to crontab:
# Daily backup at 2am
0 2 * * * pihole -a -t && mv *.tar.gz /path/to/backup/folder/ Restoring Settings
Web Interface
- Go to Settings → Teleporter
- Click Browse under Restore
- Select your
.tar.gzbackup - Click Restore
Migration to New System
- Backup old Pi-hole using Teleporter
- Install Pi-hole on new system
- Restore backup via Teleporter
- If IP changed, run:
pihole -rto reconfigure
Part 12: High Availability Setup
For networks requiring redundancy.
Two Pi-hole Instances
Run two Pi-hole servers with synchronized configurations.
Configuration Sync with Nebula-Sync (Pi-hole v6+)
Since Gravity Sync is retired, use Nebula-sync for Pi-hole v6:
# Install on secondary Pi-hole
git clone https://github.com/vmstan/nebula-sync.git
cd nebula-sync
./nebula-sync.sh install
# Configure sync from primary
./nebula-sync.sh configure Alternative: Orbital Sync (Docker)
For Docker-based deployments, Orbital Sync automates config replication:
# Add to docker-compose.yml
services:
orbital-sync:
image: mattwebbio/orbital-sync:latest
environment:
PRIMARY_HOST_BASE_URL: 'http://192.168.1.100'
PRIMARY_HOST_PASSWORD: 'your-primary-password'
SECONDARY_HOST_1_BASE_URL: 'http://192.168.1.101'
SECONDARY_HOST_1_PASSWORD: 'your-secondary-password'
INTERVAL_MINUTES: 60
restart: unless-stopped Orbital Sync syncs blocklists, whitelists, blacklists, and settings between Pi-hole instances hourly.
High Availability with keepalived
Use a Virtual IP (VIP) for automatic failover:
Step 1: Install keepalived
sudo apt install keepalived -y Step 2: Configure Primary Pi-hole
sudo nano /etc/keepalived/keepalived.conf vrrp_instance PIHOLE {
state MASTER
interface eth0
virtual_router_id 51
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass YourSecurePassword
}
virtual_ipaddress {
192.168.1.200/24 # Virtual IP
}
} Step 3: Configure Secondary Pi-hole
Same configuration but:
state BACKUPpriority 100
Step 4: Start keepalived
sudo systemctl enable keepalived
sudo systemctl start keepalived Now configure your network to use 192.168.1.200 as DNS!
Part 13: Troubleshooting
Common Issues
Ads Not Being Blocked
- Verify DNS: Run
nslookup ads.google.com- should return0.0.0.0 - Check client DNS: Ensure device is using Pi-hole
- Browser bypass: Disable DNS-over-HTTPS in browser settings
- Update blocklists: Run
pihole -g
Web Interface Not Loading
# Check FTL status
pihole status
# Restart FTL
pihole restartdns
# Check which port
ss -tlnp | grep pihole High CPU/Memory Usage
# Check stats
pihole -c
# Reduce logging
pihole logging off DNS Resolution Unavailable
# Check resolv.conf
cat /etc/resolv.conf
# Should NOT point to itself during installation
# Temporarily use: nameserver 8.8.8.8 Debug Command
# Generate debug log
pihole -d
# This creates a token you can share for support Useful Commands Reference
| Command | Purpose |
|---|---|
pihole status | Check if Pi-hole is running |
pihole -up | Update Pi-hole to latest version |
pihole -g | Update blocklists (gravity) |
pihole restartdns | Restart DNS service |
pihole -c | Real-time console stats |
pihole -t | Tail the log in real-time |
pihole -d | Generate debug token for support |
pihole -a -p | Change admin password |
pihole -b example.com | Add domain to blacklist |
pihole -w example.com | Add domain to whitelist |
pihole -b -d example.com | Remove domain from blacklist |
pihole -w -d example.com | Remove domain from whitelist |
pihole disable 5m | Disable blocking for 5 minutes |
pihole enable | Re-enable blocking |
pihole logging on | Enable query logging |
pihole logging off | Disable query logging |
pihole checkout core release/v6.0 | Switch to specific branch |
Part 14: Pi-hole vs AdGuard Home
| Feature | Pi-hole | AdGuard Home |
|---|---|---|
| Ease of Setup | Easy | Slightly easier |
| Web Interface | Good (AdminLTE) | Modern, polished |
| DNS-over-HTTPS | Requires setup | Built-in |
| DNS-over-TLS | Requires setup | Built-in |
| Parental Controls | Basic | Advanced built-in |
| HTTPS Filtering | No | Yes |
| Resource Usage | Very low | Low |
| Community | Large, active | Growing |
| Open Source | Yes | Yes |
Recommendation: Pi-hole for pure ad-blocking simplicity; AdGuard Home for advanced features out-of-box.
Part 15: Resources & Links
Official Resources
| Resource | URL |
|---|---|
| Pi-hole Website | pi-hole.net |
| Documentation | docs.pi-hole.net |
| GitHub | github.com/pi-hole |
| Docker Hub | hub.docker.com/r/pihole/pihole |
| Discourse Forum | discourse.pi-hole.net |
| r/pihole |
Blocklist Resources
| Resource | URL |
|---|---|
| Firebog | firebog.net |
| HaGeZi | github.com/hagezi/dns-blocklists |
| OISD | oisd.nl |
Conclusion
Pi-hole is an essential tool for any home network, providing network-wide ad blocking, enhanced privacy, and improved browsing performance. Whether you’re running it on a $15 Raspberry Pi Zero 2 W or in a Docker container on your NAS, Pi-hole delivers powerful protection with minimal resource overhead.
Key Takeaways:
- Start simple: Basic Pi-hole installation takes under 30 minutes
- Use quality blocklists: HaGeZi, OISD, and Firebog are excellent choices
- Consider Unbound: For maximum privacy, add recursive DNS
- VPN integration: Extend protection outside your home with WireGuard or Tailscale
- Backup regularly: Use Teleporter for easy backup and migration
- Monitor your network: The dashboard provides valuable insights
Happy ad-free browsing! 🎉
Last Updated: January 2026 | Pi-hole v6.4+ | Guide Version 1.0
Comments
Sign in to join the discussion!
Your comments help others in the community.