Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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/configs with your actual config path. The dns network is shared with Unbound — create it first if Unbound is already running, or create it manually with docker 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 blocking
  • IoT-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