Get Rewarded! We will reward you with up to €50 credit on your account for every tutorial that you write and we publish!

How to Install Pi-hole with Docker on Debian and Ubuntu

profile picture
Author
Miroslav Minárik
Published
2026-06-17
Time to read
6 minutes reading time

About the author- Web Developer who enjoys working with Linux

Introduction

Pi-hole is a network-wide DNS filtering solution that blocks advertisements, trackers, and malicious domains before they reach your devices.

In this tutorial, you will install Docker, Docker Compose, and deploy Pi-hole inside a Docker container on a Debian or Ubuntu server. At the end of this guide, you will have a fully functional Pi-hole instance accessible through a web interface and ready to serve DNS requests for your network.

Prerequisites

  • A server
    • Debian 12/13 or Ubuntu 24.04/26.04
    • Root or sudo access
    • A static IP address
    • Open ports 53/tcp, 53/udp, and 80/tcp
    • Docker already installed

Example terminology

Throughout this tutorial, the following placeholders are used:

  • Hostname: <your_host>
  • Server IP: <10.0.0.1>
  • Password: <your_password>

Step 1 - Install Docker

If you haven't already, install Docker now as explained in the official Docker documentation:

Remember to add your user to the docker group:

sudo usermod -aG docker your-user-name

Step 2 - Create the Pi-hole Directory Structure

Create a directory for Pi-hole:

mkdir -p ~/pihole
cd ~/pihole

Create persistent storage directories:

mkdir -p ~/pihole/etc-pihole
mkdir -p ~/pihole/etc-dnsmasq.d
touch ~/pihole/docker-compose.yml

Your structure should look like:

~/pihole
├── docker-compose.yml
├── etc-pihole
└── etc-dnsmasq.d

Step 3 - Create the Docker Compose Configuration

Create the compose file:

nano docker-compose.yml

Insert the following configuration which uses the Docker image pihole/pihole:

services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest

    environment:
      TZ: Europe/Bratislava
      FTLCONF_webserver_api_password: "ChangeMe123!"

    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "80:80/tcp"

    volumes:
      - ./etc-pihole:/etc/pihole
      - ./etc-dnsmasq.d:/etc/dnsmasq.d

    restart: unless-stopped

Save and close the file.

Step 4 - Start Pi-hole

Start the container:

docker compose up -d

If you get an error message like Error response from daemon: failed to set up container networking, go to Step 9 - Troubleshooting: Port 53 Already in Use.

Verify that the container is running:

docker ps

Expected output:

CONTAINER ID   IMAGE                  STATUS         PORTS                     NAMES
xxxxxxxxxxxx   pihole/pihole:latest   Up (healthy)   0.0.0.0:53->53/tcp, ...   pihole
Click here if the ports section is empty

The ports section should look like this:

0.0.0.0:53->53/tcp, [::]:53->53/tcp, 67/udp, 0.0.0.0:80->80/tcp, 0.0.0.0:53->53/udp, [::]:80->80/tcp, [::]:53->53/udp, 123/udp, 443/tcp

If this section is empty for you, stop and remove the container are restart it:

docker stop pihole && docker rm pihole
docker compose up -d
docker ps

View the logs:

docker compose logs -f

Press CTRL+C to exit.

Step 5 - Access the Web Interface

Open your browser and navigate to:

http://<10.0.0.1>/admin

Replace <10.0.0.1> with the IP address of your server.

Log in using the password configured in docker-compose.yml:

FTLCONF_webserver_api_password: "ChangeMe123!"

After logging in, you should see the Pi-hole dashboard.

Step 6 - Configure DNS Clients

To use Pi-hole, configure your devices or router to use the Pi-hole server as their DNS server.

Example:

Primary DNS: <10.0.0.1>
Secondary DNS: (leave empty)

For best results, configure DNS directly on your router so all devices automatically use Pi-hole. Learn more, in the official Pi-hole documentation:

Step 7 - Update Pi-hole

Pull the latest image
cd ~/pihole
docker compose pull
Restart the container
docker compose up -d
Verify the running version
docker exec pihole pihole -v
docker ps

Step 8 - Useful Commands

View logs
docker compose logs -f
Restart Pi-hole
docker compose restart
Stop Pi-hole
docker compose down
Start Pi-hole
docker compose up -d
Check container status
docker ps

Step 9 - Troubleshooting: Port 53 Already in Use

When starting the Pi-hole container, you may encounter an error similar to:

failed to bind host port 0.0.0.0:53/tcp: address already in use

This means another service is already listening on DNS port 53.

Check which service is using the port:

sudo ss -tulpn | grep ':53'

  • Ubuntu - systemd-resolved

    Some Ubuntu installations use systemd-resolved which occupies port 53.

    Stop and disable the service:

    sudo systemctl stop systemd-resolved
    sudo systemctl disable systemd-resolved

    Create a new DNS configuration:

    cat <<EOF | sudo tee /etc/resolv.conf
    nameserver 1.1.1.1
    nameserver 8.8.8.8
    EOF

    Verify DNS resolution:

    ping -c 4 google.com

  • Debian - dnsmasq

    Some Debian installations may have dnsmasq installed.

    Check its status:

    sudo systemctl status dnsmasq

    If it is running and you do not need it, stop and disable it:

    sudo systemctl stop dnsmasq
    sudo systemctl disable dnsmasq

  • Verify Port Availability

    Ensure that nothing is listening on port 53:

    sudo ss -tulpn | grep ':53'

    If no output is returned, start Pi-hole again:

    cd ~/pihole
    docker compose up -d

    Verify the container status:

    docker ps

Conclusion

You have successfully installed Docker and deployed Pi-hole using Docker Compose on Debian or Ubuntu. Your server is now capable of providing network-wide DNS filtering and blocking advertisements, trackers, and malicious domains for all devices that use it as their DNS server.

License: MIT
Want to contribute?

Get Rewarded: Get up to €50 in credit! Be a part of the community and contribute. Do it for the money. Do it for the bragging rights. And do it to teach others!

Report Issue
Try Hetzner Cloud

Get €20/$20 free credit!

Valid until: 31 December 2026 Valid for: 3 months and only for new customers
Get started
Want to contribute?

Get Rewarded: Get up to €50 credit on your account for every tutorial you write and we publish!

Find out more