Run Pi-Hole as a Docker Container on a Raspberry Pi

This lab uses a Raspberry Pi to run a Pi-Hole server as a Docker Container

Goal

This sets up Pi-Hole as a Docker container

It uses Docker Compose

The host OS is Raspbian running on Raspberry Pi hardware

Pi-Hole is a server used to filter network traffic. If you send your client through it for Internet access by configuring it as the DNS endpoint on the client it will scan traffic and block access to malicious websites.

Persistent storage for configuration files

As is the “Docker Way” the Pi Hole container should be ephemeral and be able to be easily re-created for upgrades and such. As there is configuration data to manage it is good practice to store the configuration data in persistent storage that the container is configured to refer to when it comes online. The simplest way of doing this for a single node system is to create a working directory from which to run the container from and store the data.

These commands will first create the working directory then the configuration sub-directories.

mkdir /home/pi-hole-docker
mkdir /home/pi-hole-docker/etc-pihole
mkdir /home/pi-hole-docker/etc-dnsmasq.d

Docker Compose file

Now you create the Docker compose file that configures the docker container. Create this in the root of your working directory and edit it with your favorite text editor.

vim docker-compose.yml

In the file you need to add the Docker configuration. This example is a functional file that works with some basic settings configured. It for example sets the upstream DNS servers manually to 8.8.8.8 and 8.8.4.4 and defines the admin password.

OBS! that the Raspberry Pi IP address is used and port-forwarding is configured on 8081 to 80 to access the Pi-Hole web interface. You could put in a reverse proxy instead but this works and is simple enough.

OBS! that to function as a DNS server you need to ensure that the Raspberry Pi itself is not hosting a service on port 53 otherwise Pi-Hole won’t work. See the DNS section below.

version: "3"

# More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/
services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    # For DHCP it is recommended to remove these ports and instead add: network_mode: "host"
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "67:67/udp" # Only required if you are using Pi-hole as your DHCP server
      - "8081:80/tcp" # Port fowards on 8081 to 80 using the Raspberry Pi IP address
    environment:
      TZ: 'Europe/Copenhagen'
      WEBPASSWORD: 'jU3cZrEBmzbe' # Enter a random password
      PIHOLE_DNS_: '8.8.8.8;8.8.4.4'
    # Volumes store your data between container upgrades
    volumes:
      - './etc-pihole:/etc/pihole'
      - './etc-dnsmasq.d:/etc/dnsmasq.d'
    #   https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
    cap_add:
      - NET_ADMIN # Required if you are using Pi-hole as your DHCP server, else not needed
    restart: unless-stopped

DNS service clash

If your Raspberry Pi is running a DNS service on port 53 it needs to be disabled in order for Pi-Hole to function. A common issue because the default DNS server that comes with Raspbian (often dnsmasq or systemd-resolved) is already using port 53.

To resolve this issue, you’ll need to stop the service that’s currently using port 53.

Identify the Service Using Port 53: Use the following command to find out which service is using port 53:

sudo netstat -tulpn | grep :53

Stop the Service: Depending on which service is using port 53, you’ll need to stop it. If it’s dnsmasq, you can stop it with:

sudo systemctl stop dnsmasq

If it’s systemd-resolved, you can stop it with:

sudo systemctl stop systemd-resolved

Disable the Service: To prevent the service from starting automatically on boot, you can disable it:

sudo systemctl disable dnsmasq

or

sudo systemctl disable systemd-resolved

Replace dnsmasq or systemd-resolved with the service you identified earlier.

Restart Docker Compose: After stopping and disabling the conflicting service, try starting your Pi-hole container again:

sudo docker-compose up -d

Run the container

Now you are ready to start Pi-Hole which simply means running the Docker compose up command against your docker-compose.yaml file.

sudo docker-compose up -d
Last modified July 21, 2024: update (e2ae86c)