Pi-hole Setup Tutorial
A step-by-step guide to setting up Pi-hole as a network-wide ad blocker and DNS server using Docker and Dockge, based on a real homelab deployment.
Prerequisites
- Docker and Dockge installed on your server
- A static IP for your server (e.g.
192.168.50.203) - Basic familiarity with Docker Compose
1. Create the Compose Stack
In Dockge, create a new stack called pihole with the following compose.yaml:
# /opt/docker/stacks/pihole/compose.yaml
services:
pihole:
image: pihole/pihole:latest
container_name: pihole
restart: unless-stopped
labels:
- homepage.group=Homelab
- homepage.name=Pi-hole
- homepage.icon=pi-hole.png
- homepage.href=http://192.168.50.203:20720/admin/
- homepage.description=Network ad blocker & DNS
ports:
- 53:53/tcp
- 53:53/udp
- 20720:20720/tcp
volumes:
- /path/to/configs/pihole/config:/etc/pihole
- /path/to/configs/pihole/dns:/etc/dnsmasq.d
environment:
TZ: Europe/Brussels
FTLCONF_dns_listeningMode: all
FTLCONF_webserver_api_password: ${WEBPASSWORD}
FTLCONF_webserver_port: "20720"
DNSMASQ_USER: pihole
FTL_CMD: no-daemon
networks:
- dns
networks:
dns:
name: dns
Note: Replace
/path/to/configswith your actual config path. Thednsnetwork is shared with Unbound — create it first if Unbound is already running, or create it manually withdocker network create dns.
Create a .env file in the same directory with your admin password:
WEBPASSWORD=your_secure_password_here
2. Configure Your Router
Pi-hole needs to be the DNS server for all devices on your network. There are two places to configure this on most routers:
- LAN / DHCP DNS Server 1:
192.168.50.203(your server’s IP) - LAN / DHCP DNS Server 2: leave empty, or set to your secondary Pi-hole when ready
Remove any fallback DNS like 8.8.8.8 — this would allow devices to bypass Pi-hole.
3. Configure Upstream DNS
In the Pi-hole web UI, go to Settings > DNS.
- Uncheck all preset upstream DNS providers
- Under Custom DNS servers, enter:
unbound#5335 - Click Save
This assumes Unbound is running as a container on the same Docker network. If you haven’t set up Unbound yet, temporarily use
1.1.1.1(Cloudflare) as upstream.
4. Set Up Group Management
Pi-hole’s group management lets you apply different blocking rules to different devices.
Create Groups
Go to Groups and create:
Default— full blocking (already exists)Unblocked— for family members who don’t want blockingIoT-blocked— for smart devices you want to block from the internet
Assign Adlists to Groups
Go to Adlists and for each blocklist, uncheck the Unblocked group. This means devices in that group have no blocklists applied.
Block IoT Devices Completely
Go to Domains > RegEx filter tab and add:
- Regex:
.* - Type: Deny
- Group:
IoT-blocked
This blocks all DNS resolution for devices in that group.
Assign Clients to Groups
Go to Clients, add each device by IP address, and assign it to the appropriate group.
Important: Make sure IoT devices have static IPs (either set on the device or via DHCP reservation in your router) so group assignments don’t break when IPs change.
5. Verify Everything Works
Check that DNS queries are flowing through Pi-hole by visiting a few websites and checking the Query Log in the Pi-hole web UI.
You should see:
- Your devices’ IPs appearing as clients
- Queries being forwarded to
unbound#5335 - Blocked queries showing in red
Tips
- Use the Query Log to identify false positives — you can whitelist domains with one click
- Start with a conservative blocklist (e.g. Steven Black unified or HaGeZi Multi Normal) to minimize false positives
- The Dashboard shows real-time stats on blocked queries, top domains, and top clients