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. 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.

Goal

Create a Docker Compose file

Run Pi Hole as a Docker Container on a Raspberry Pi

Install Docker and Docker Compose

Your Raspberry Pi should have a static IP and be up to date. You can follow this guide to install Docker and Docker Compose.

Install Docker on Raspbian

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.

sudo mkdir /home/pi-hole
sudo mkdir /home/pi-hole/etc-pihole
sudo mkdir /home/pi-hole/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.

cd /home/pi-hole
sudo vi 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.

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.

  1. Identify the conflicting service: Run the following command to see which service is using port 53:

    sudo netstat -tulpn | grep :53
    
  2. Stop the conflicting service: If dnsmasq is the culprit, you can stop and disable it with these commands:

    sudo systemctl stop dnsmasq
    sudo systemctl disable dnsmasq
    

    If it’s systemd-resolved, use these commands instead:

    sudo systemctl stop systemd-resolved
    sudo systemctl disable systemd-resolved
    
  3. Restart Docker Compose: After stopping the conflicting service, try starting your Pi-hole container again:

    sudo docker-compose up -d
    

Connect to Pi Hole

When the Pi Hole container is running, open the webpage using the address below and use the admin password you configured in the Docker compose file.

http://<raspbian-server-ip>:8081/admin/login.php

References

Docker Pi-hole


Last modified February 19, 2025: Update azure-point-to-site-vpn.md (a9c807a)