Australia/Melbourne
Posts

How to Set up PiHole with Docker on your Home Network

April 24, 2025
If you’ve seen the price of Raspberry Pis recently — with the state of the world and ongoing chip shortages — you might be thinking, “I can’t afford a Raspberry Pi.” Well, good news: you can run PiHole in a Docker container right on your home network. This is a great way to get started without spending a lot on hardware. But what if you don’t want to buy a Raspberry Pi, or don’t have one lying around? No problem — Docker makes it easy. I picked up a thin client off eBay — 4GB RAM, 16GB storage — for around $50. Prices have gone up recently, but it’s still way cheaper than a Pi (currently around $250–400 😬). It came with embedded Windows, but after some BIOS tinkering I got it to boot from a USB drive. I installed Ubuntu Server 20.04, and it’s been running great since. I’ve got a few other services running on it too — that’s a story for another day. I’ll let Copilot give you a quick rundown of Docker and PiHole, but if you just want the installation steps, skip ahead.
PiHole is a DNS sinkhole that protects your devices from unwanted content — no client software required. It blocks ads and trackers across your entire network and provides a clean web interface showing:
  • Connected devices
  • DNS queries made
  • Blocked domains and IPs

Docker is a containerization platform that runs applications in isolated environments called containers. It’s great for running software with complex dependencies or tricky installs, and works across different operating systems — e.g. running Linux apps on Windows or vice versa.
Docker lets you run apps on your home network without cluttering your host system. Instead of manually installing and configuring something like a Minecraft server, you can:
  • Pull the app image from Docker Hub
  • Configure it via a simple docker-compose.yml
  • Run it in seconds
No messy installs, no port conflicts, no dependency nightmares.
  1. Install Docker → Get Docker
  2. Install Docker Compose → Get Docker Compose

I’ve been using Traefik as a reverse proxy for everything lately. This setup assumes you already have a Traefik instance and a Docker network ready. If not, here’s a minimal but functional docker-compose.yml to get started. Create a traefik directory:
Bash
mkdir traefik
cd traefik
vim docker-compose.yml
Paste this:
Yaml
version: "3.3"

services:
  traefik:
    image: "traefik:v2.4"
    container_name: "traefik"
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "443:443"
      - "52:52" # only needed if you want to use DNS over HTTPS
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    networks:
      - lan
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`traefik.local`)"
      - "traefik.http.routers.api.service=api@internal"
      - "traefik.http.routers.api.entrypoints=web"

networks:
  lan:
    external: true

We’ll use the official PiHole Docker image from Docker Hub, alongside the Traefik Docker image. Create a new directory:
Bash
mkdir pihole
cd pihole
vim docker-compose.yml
Paste this:
Yaml
version: "3.3"

services:
  pihole:
    image: "pihole/pihole:latest"
    container_name: "pihole"
    environment:
      - TZ="Australia/Melbourne"
      - WEBPASSWORD="yourpassword"
      - DNS1=8.8.8.8

Lifted from this example:
Bash
mkdir traefik-pihole
cd traefik-pihole
vim docker-compose.yml
Then paste:
Yaml
version: '3'

services:
  traefik:
    container_name: traefik
    domainname: homedomain.lan
    image: traefik
    restart: unless-stopped
    command: "--web --docker --docker.domain=homedomain.lan --docker.exposedbydefault=false --logLevel=DEBUG"
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /dev/null:/traefik.toml
    networks:
      - default
      - discovery
    dns:
      - 192.168.1.50
      - 192.168.1.1

  pihole:
    container_name: pihole
    domainname: homedomain.lan
    image: diginc/pi-hole:debian
    ports:
      - '0.0.0.0:53:53/tcp'
      - '0.0.0.0:53:53/udp'
      - '0.0.0.0:67:67/udp'
      - '0.0.0.0:8053:80/tcp'
    volumes:
      - ./etc-pihole/:/etc/pihole/
      - ./etc-dnsmasqd/:/etc/dnsmasq.d/
    environment:
      ServerIP: 192.168.1.50
      PROXY_LOCATION: pihole
      VIRTUAL_HOST: pihole.homedomain.lan
      VIRTUAL_PORT: 80
      TZ: 'America/Chicago'
    restart: unless-stopped
    labels:
      - "traefik.enable=true"
      - "traefik.frontend.rule=HostRegexp:pihole.homedomain.lan,{catchall:.*}"
      - "traefik.frontend.priority=1"
      - "traefik.backend=pihole"
      - "traefik.port=80"

networks:
  discovery:
    external: true

✅ Done! You now have PiHole running behind Traefik in Docker — no Raspberry Pi required. Enjoy network-wide ad blocking and analytics right from your browser.
On this page