A Minimal Solution for Running Pi-hole Docker Under Traefik

Ad blocking and privacy protection on the local network

Summary statistics from my running Pi-Hole

Posted: December 31, 2021

Pi-hole is a free and open source program that provides ad blocking and tracker blocking to everything on your local network. It even works with smart devices, like my Roku streaming box.

I run several of my local network services (such as git and wiki) as Docker containers on one host. A Traefik proxy multiplexes the services on this host. I wanted to add Pi-hole here.

There is a readily available, supported Pi-hole Docker image. That worked great for me.

I use Docker Compose to manage my Docker containers. I went looking for a docker-compose.yml file example on the net, but all the ones I found seemed unnecessarily complicated.

So, I thought I’d share my simple solution. Here it is:

services:
  traefik:
    .
    .
    .

  pihole:
    image: pihole/pihole:latest
    ports:
      # port 80 will go through Traefik
      - "53:53/tcp"
      - "53:53/udp"
    environment:
      - "TZ=America/Chicago"
      - "WEBPASSWORD=xxxxxxxx"
      - "VIRTUAL_HOST=pihole.chez-rufus.lan"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.pihole.rule=Host(`pihole.chez-rufus.lan`, `pihole`)"
      - "traefik.http.services.pihole.loadbalancer.server.port=80"
    volumes:
      - pihole_etc:/etc/pihole
    restart: unless-stopped

volumes:
  pihole_etc:
    name: pihole_etc

Network services

Pi-hole provdes three network services: a DNS resolver, a DHCP server, and a web server.

I’m exposing the DNS resolver (network ports 53/tcp and 53/udp) directly on the Docker host. I’ve seen a lot of solutions that run those through the Traefik proxy. That’s unnecessary.

I am leaving the DHCP server (network port 67/udp) disabled, which is why you don’t see any configuration for it above. A lot of the solutions I saw run this service but that too usually is unnecessary. Your gateway/router already has a DHCP server. If it allows you to configure the DNS assignments then there isn’t any reason not to use that.

That leaves the web service (network port 80/tcp), which provides the administration screen. I do run that through the Traefik proxy.

Pi-hole Host

The DNS setup in my gateway router has a static entry for “pihole.chez-rufus. lan”:

$ host pihole.chez-rufus.lan
pihole.chez-rufus.lan has address 192.168.20.6

It’s an alias for the host that has all my Docker containers.

The VIRTUAL_HOST environment setting is defined as this host. So, when
a local user visits http://pihole.chez-rufus.lan/ they’ll get the Pi-hole administrative screen.

Pi-hole DNS Configuration

I made a few adjustments to the default Pi-hole DNS configuration, as shown to the right (click to enlarge).

  • The default Pi-hole configuration uses Google Public DNS as the upstream DNS server. I don’t want that, so I unchecked the boxes normally set.

  • I added the gateway router (192.168.20.1) as the upstream DNS server. That way queries that aren’t blocked by the Pi-hole are passed upstream for resolution.

  • Finally, I removed the check on two options: “Never forward non-FQDN queries” and “Never forward reverse lookups for private IP ranges”. I want to forward those queries on to the gateway router for resolution.

With this setup, DNS requests are processed as follows:

  • First, by the Pi-hole, to filter out blocked sites
  • Next, by the gateway router, to resolve local resources on the network
  • Finally, my router passes the query to its upstream DNS resolver (I use Google Public DNS) to resolve public Internet addresses.

Router DHCP

The final change was to modify the DHCP configuration in my gateway router so network hosts were told to use the Pi-hole for DNS resolution, rather than the router itself.

Conclusion

With the setup complete, DNS request processing happens as shown in this sequence diagram:

My solution does require that DNS queries make one additional stop at the gateway router, for local resource resolution. That could be avoided by running DHCP on the Pi-hole. I didn’t want to do that. My gateway router has significantly higher uptime expectations than my Docker server, so I’d rather run DHCP there. The added overhead of this decision is small and worth the increased reliability.

The presented docker-compose.yml is a minimal solution for running Pi-Hole as a Docker container behind a Traefik proxy.

It's Just This Little Chromium Switch Here

Latest blog posts

Buying a New Computer Monitor

Jan 22, 2022

Welcome to 2022 and another year of remote work. Around the new year I decided it was time for me...

Android Private DNS Considered Helpful and Harmful

Jan 20, 2022

Starting with Android 9 Pie, a new feature called “Private DNS” was introduced.

My Favorite Sandwich Joints in Austin

Jan 3, 2022

Hey, who wants a sandwich? If you do – and if you live in the Austin area – here are...

A Minimal Solution for Running Pi-hole Docker Under Traefik

Dec 31, 2021

Pi-hole is a free and open source program that provides ad blocking and tracker blocking to everything on your...