Get Started with Docker - Part 3: Pi-Hole
Tags: docker, tutorial, pihole
Published: 2024-03-03 10:30:00

You've set up Docker on your operating system and device of choice. You're ready to start spinning up containers and seeing what Docker is all about.

In this guide, we'll spin up one of the most useful services in a container and a great introduction to the Docker ecosystem.

We'll be

-   Looking at what Pi-Hole is
-   Going to the project page for Pi-Hole for our build and install instructions
-   Using Notepad++ on a Windows Laptop to create a custom Docker Compose with Environmental Variables
-   Setting up a folder on our machine for Docker to locally store our config files and other persistent data
-   Using the Nano Text Editor on our Docker machine to create our docker-compose.yml file
-   Spin up and deploy our Pi-Hole Docker Container
-   Login to our Pi-Hole with a custom password
-   Connect our Windows Machine and Android Phone so they use the Pi-Hole for their DNS to provide the ad-blocking function

___

## What's a PiHole?

In short, the PiHole intercepts requests to the internet and blocks domains based on the sites listed in it's block list.

By default, there are about 100,000 entries which is enough for most people to get decent protection from malicious websites and ads.

<img width="100%" style="width:100%" src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExaHJzMTZtaHQwczR5ZGk0bXJ5dGJ3Yjh2bW13Ymowb3IxZG5odXBjZyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/njYrp176NQsHS/giphy-downsized-large.gif">

This will speed up your network and make it safer overall by stopping unwanted traffic at the source with some extra added benefits.

We'll look at how to increase this with number with third party block lists later on in this guide.

___

## PiHole Project Page

You can find a Docker version of most software and applications usually on their main website.

![Pihole Website 01](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/loxjifvj436o4a0sxugu.png)

[https://pi-hole.net](https://pi-hole.net)

This will usually link you to a project page on Docker Hub, GitHub or their own website to get further information and build instructions.


![Pihole Website 02](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/olh4ism7wu37cizxyhrq.png)

___

## Customise a Docker Compose file

One of the best things about Docker is that a lot of the images are set up with customisation in mind.

Using Environmental Variables you can start the Docker container with certain settings such as a different port number or paths to Docker config folders.

As we found on the website here is the default docker-compose.yml for PiHole

```
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
      - "80:80/tcp"
    environment:
      TZ: 'America/Chicago'
      # WEBPASSWORD: 'set a secure password here or it will be random'
    # 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
```

We're going to make a few changes to this so that it works for our setup.

___

## Notepad++ Text Editor

We can use a text editor to make changes to the Docker Compose file as a quick and easy way to experiment.

Personally I use Notepad++ as my text editor in Windows to help me to edit the Docker Compose file ready to be pasted into the terminal later.

![NotePad++ Docker Compose File](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dgdlgyd3rspdy9ayl7i7.png)

You can download it from here but if you don't want to install anything than you can use the trusty Notepad app built into Windows.

___

## Set the container name

In this section we're going to set the container name to be pihole

We're also going to set the image we're going to download as the pi-hole image from the pihole repository.

We'll use the latest tag to get the latest version of this image when we deploy the container.

As an extra bonus we're also going to define the hostname as **reprodevpihole** which will be used by this pi-hole instance. This will make management easier if you're running a few pi-holes.

You can change this to one which makes sense for you.

```
services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    hostname: reprodevpihole
```

## Set the Ports and DNS

In this section we're going to set the networking for this Docker container.

I've found that you may have issues with your device resolving DNS or other Docker containers if you install Pihole on something like a Raspberry Pi.

We can add the environmental variables for DNS and define these as 127.0.0.1, to use the local device to resolve and 8.8.8.8 to use Google servers to resolve as a backup.

```
    dns:
      - 127.0.0.1
      - 8.8.8.8
```

To help devices connect to use this as a DNS then it's also best that we define the IP of the device we are installing this on for Port 53.

In this example it's 192.168.0.90 so that has been added to the lines for port 53.

Go ahead and replace this with your own IP address as needed.

```
    ports:
      - "192.168.0.90:53:53/tcp"
      - "192.168.0.90:53:53/udp"
```

Finally the port to connect to the Pihole Admin has been defined as 1010 on the host to map onto port 80 in the docker container.

You can change this to one of your choosing by changing the number on the left to an unused port.

```
      - "67:67/udp"
      - "1010:80/tcp"
```

The ports section should now look like this

```
    ports:
      - "192.168.0.90:53:53/tcp"
      - "192.168.0.90:53:53/udp"
      - "67:67/udp"
      - "1010:80/tcp"
```

The whole networking section should now look like this

```
    dns:
      - 127.0.0.1
      - 8.8.8.8
    ports:
      - "192.168.0.90:53:53/tcp"
      - "192.168.0.90:53:53/udp"
      - "67:67/udp"
      - "1010:80/tcp"
```

Docker Networking can get quite complicated and we'll look at this in more detail at a later date.

For now this should work for you to get started

___

## Set the Environment Variables

Setting the Environment Variables for a Docker container can help to speed up and create containers customised to your use case.

### Set the Time Zone

You can define the time zone using the **TZ** variable in most docker compose files to make sure they work correctly.

You can find a list of them here but for this example we've changed it to '**Europe/London'** to match my settings

```
environment:
  TZ: 'Europe/London'
```

Replace your own time zone here to make sure it matches the city closest to your time zone.

### Set the Web Admin Password

You can also define the password that will be used to access the PiHole Admin later on.

Make sure that you change the WEBPASSWORD environment variable in the docker compose file to a random secure password.

e.g. from this one

```
      WEBPASSWORD: 'a5up3r53cr3tpa33'
```

to this one

```
      WEBPASSWORD: 'yourownpassword'
```

This will be the password you use to access the PiHole Admin later on so make a note of it or comment it out.

```
    # WEBPASSWORD: 'a5up3r53cr3tpa33'
```

If you comment it out then one will be set randomly on first boot and you'll be able to find it in the terminal output from the logs.

___

## Set the Docker Data Volume Paths

The default for most Docker Compose files is to save the config files needed by the container in the running container for testing.

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

We need to replace the paths on the left with the location of the Pihole folder we created earlier to store this Docker Compose YAML file.

The new volumes file for this example will now look like this.

```
  volumes:
  - '/home/reprodev/Files/AppData/Config/pihole/etc-pihole:/etc/pihole'
  - '/home/reprodev/Files/AppData/Config/pihole/etc-dnsmasq.d:/etc/dnsmasq.d'
```

That's all of our changes to this file as the rest can stay the same.

___

## Pihole Docker Compose File

We've finally got our own customised YAML file for Pihole that we can use on any machine that has Docker installed.

The one below is based on the one in our guide so yours may look a little different to this one in a few places.

```
version: "3"

services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    hostname: piholevm
    dns:
      - 127.0.0.1
      - 8.8.8.8
    ports:
      - "192.168.0.90:53:53/tcp"
      - "192.168.0.90:53:53/udp"
      - "67:67/udp"
      - "1010:80/tcp"
    environment:
      TZ: 'Europe/London'
      WEBPASSWORD: 'a5up3r53cr3tpa33'
    volumes:
      - '/home/reprodev/Files/AppData/Config/pihole/etc-pihole:/etc/pihole'
      - '/home/reprodev/Files/AppData/Config/pihole/etc-dnsmasq.d:/etc/dnsmasq.d'
    cap_add:
      - NET_ADMIN
    restart:
      unless-stopped
```

Other than changing a few variables as needed, we have our own custom Docker Compose file for Pihole.

We can now use this any time we want to spin up a docker container for Pihole with the settings we have added.

Now that we have our customised Docker Compose file we need to get this saved into our Pihole Config folder.

___

## Login to a Linux Shell

To install Pihole and deploy the Docker container we'll need to login to a Linux Shell.

Follow the instructions below to open the Linux Shell

### If you're using Windows (WSL with Docker Desktop)

-   Open a Terminal and **"Run as administrator"**

![Login to Linux Shell 01](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v6ik7jl3e6l5vfab5l0u.png)

-   Type the **wsl** command to open a WSL shell

```
wsl
```

![Login to Linux Shell 02](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9xuajdf4gi33jzkmw6mw.png)

This will open up a command prompt to the Linux distro you are installed alongside the Windows Subsystem for Linux.


![Login to Linux Shell 03](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dwejddy4iwmyh30xov9j.png)

### If you're using Linux (Raspberry Pi OS and more)

Then just

-   Open a terminal

![Login to Linux Shell 04](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s8e3wrvgxka8e57koa56.png)

>💡 This is where the Linux and Raspberry Pi users can rejoin as these commands will now be the same.

Type **cd** and **Press Enter** to change directory back to your Linux user home directory

```
cd
```

![Login to Linux Shell 05](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1kca62twnx0rqhwyjtrd.png)

Run the **pwd** command to check which folder you are currently in

```
pwd
```

![Login to Linux Shell 06](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kejbfvub471skjo04kgo.png)

![Login to Linux Shell 07](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w2h41z3aqdawfu73nl2y.png)

You should be in /home/(yourusername)

___

## Set up your Docker Config folders

As this may be your first Docker container you'll need to settle on a folder structure for Docker to store the config files and folders outside of Docker.

In this guide and for most of our guides we'll be using the following folder to store all of our config files.

```
/home/$yourusername/docker/Files/AppData/Config
```

It’s best that we start with a folder structure to make it easier to organise and back up the data volumes. This is the folder structure I’m currently using between my different machines running docker.

Once you've started, you can then use this structure for all your Docker config folders. You just need to replace the name of the application or service.

We'll use this folder later on but for now let's go and get our instructions for the PiHole Docker container

___

### Make Docker Persistent Config Directories

We can now start to make up the folders for Docker, to store it's config files to persist and save.

These folders will be stored outside of the docker container and won't be deleted when the container is destroyed or recreated.

Type **cd** and **Press Enter** to change directory back to your Linux user home directory

```
cd
```

![Docker Persistent 01](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rmr1nycx45fgmuxa3cqn.png)

Run the **pwd** command to check which folder you are currently in

```
pwd
```

![Docker Persistent 02](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hzv99bro4xneae99kg71.png)

You should be in /home/(yourusername)

```
/home/reprodev/
```

Run the below commands one at a time, to create the folder structure

```
mkdir docker
cd docker
mkdir Files
cd Files
mkdir AppData
cd AppData
mkdir Config
cd Config
```

![Docker Persistent 03](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xi24z3lmi5mhsnd702mz.png)

Run the below commands to create the Pihole config folder

```
mkdir pihole
cd pihole
```

![Docker Persistent 04](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/on0dnrjwru9ycdib2m46.png)

![Docker Persistent 05](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sj5i1x4d0xzyfg5mjzwl.png)

![Docker Persistent 06](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bnsq4kon9itewhwo8pt7.png)

We should now be in the pihole directory we just created.

```
/home/reprodev/docker/Files/AppData/Config/pihole
```

Run the **pwd** command to check which folder you're currently in

```
pwd
```

We can now create our Docker Compose YAML file.

You can use the newly created Config folder to store all of your docker config files in future and easily find them all in one place.

___

## Use Nano Text Editor to create the Docker Compose YAML File

Before we can run our Docker container we need to get the Docker Compose YAML file text we customised, into a place where Docker can find it.

We can use Nano to do this.

### Open Nano Text Editor

Linux has a few text editors to choose from and just like my preference for Notepad++ in Windows. I have the same preference for Nano editor over the other popular editors like Vim.

This is just my personal preference as I find it the easiest to use but feel free to use your Linux Text Editor of choice.

We're going to use the Nano Text Editor as it's built into Ubuntu, which is in turn the default Linux distribution installed as part of Windows Subsystem for Linux (WSL) install.

This means it will also be part of the Raspberry Pi OS and Ubuntu if you're running Linux on bare metal or as a virtual machine.

We should still be in the **pihole** folder we created in the last step. We can open Nano and create a blank file to write in at the same time.

Run the below command to make the Docker Compose YAML file

```
nano docker-compose.yml
```

![Nano Editor 01](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7x13y3xbwzv6eugco6xh.png)

This will open Nano and create a blank file called docker-compose.yml

![Nano Editor 02](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c3fe5qlppv8016whppqg.png)

You can now paste the Docker Compose file contents we customised earlier in Notepad++

Open up Notepad++ and select all the text and copy it to the clipboard. You can either use the normal keyboard shortcuts or right click to copy like normal.

Go back to the Nano and Right Click to paste all of the text into the blank file.

![Nano Editor 03](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/alpqxp1fenuf38r176ap.png)

The formatting should be correct and you can scroll up and down to make any corrections if you need to.

![Nano Editor 04](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s432yz1dpqy4jjhw18aq.png)

When you're happy with the text then use the keyboard shortcut below to save the file

```
Ctrl+S
```

![Nano Editor 05](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yo0zpm2hvtxvrul1k1v5.png)

Use the below keyboard shortcut to exit Nano and return to the Linux command line

```
Ctrl+X
```

![Nano Editor 06](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jd6z26l8riqez1b6d6gu.png)

![Nano Editor 07](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wl0kjyzsiyhgwk6ippdo.png)

![Nano Editor 08](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9mzurqu73p6lw46jzal7.png)

The docker-compose.yml is also linked below in the ReproDev Recipes Github :

{% embed https://github.com/reprodev/reprodev-recipes/ %}

___

## Spin Up and Deploy Your Container

Well we've done all the hard work so we're finally ready to spin up and deploy the container.

Make sure you are in the same folder as your docker-compose.yml file and run the below command

```
docker-compose up -d
```

![Deploy Pihole 01](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x8uwhaho4zudxyd9rgps.png)

![Deploy Pihole 02](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6a4rchabkf7enx1nv618.png)

![Deploy Pihole 03](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ud1rll1nceu91sv97rq1.png)

This will start up the Docker container in detached mode so it's time to grab a coffee as this may take 5 to 10 minutes depending on your system.

![Deploy Pihole 04](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zvb55vnu17jxtp9b0v2g.png)

When you're back to the command line then your Docker container has been deployed and should be running.

![Deploy Pihole 05](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b59am2i68915wku01bp7.png)

We can check this by running the below command

```
docker ps
```

![Deploy Pihole 06](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t59s7ogx0wkkbb48yumy.png)

This will check all running docker containers and we should be able to see **pihole** as one of the running containers

![Deploy Pihole 07](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wlh0a36e8mp2eg85bzdd.png)

If you're on Windows using Docker Desktop you'll see this running in the Containers section as well.

You can stop, delete or even use command line to directly interact with a running Docker container from here.

It's also a good place to get the same stats you'd get from the command line such as uptime and docker hostnames at a quick glance.

We can now go to the IP of our Docker machine using the 1010/admin and we should see the PiHole login page.

![Deploy Pihole 08](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7z59ogs8in4e1bjgfvw7.png)

There's no username but there is a password.

The password will be the same one that you set in the Docker Compose file earlier.

![Deploy Pihole 09](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tuslscp9hebuoyw4bzca.png)


![Deploy Pihole 10](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hhxzfb78h2d2xwy49duh.png)

If you can login and see this page then you've successfully installed Pihole.

![Deploy Pihole 11](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w1zd1bz22fsm96pstilx.png)

Let's go ahead and start adding some clients so we can start using it.

___

## Adding Clients to the Pihole

We should now have Pihole deployed with the default adlist but we haven’t got any machines using this yet.

You can use Pihole to replace the DNS for your whole network by changing the DNS settings in your router.

That does depend on you being able to change those settings and usually it's easier to do this on each device you're using while you're getting to grips with it.

Especially if you have other people on the network who may not appreciate you adding their favourite site to your blocklist or it's down for maintenance.

### Joining a client using DNS replacement

To join one of your devices to the running Pihole we have to change the DNS setting on the device in the Network settings.

To get a device to use the Pi-Hole as it’s DNS for ad blocking then we need to set the DNS for a device on the network to use the IP Address of the device running Pihole e.g. 192.168.0.177

On Windows 11, you can do this by going to Network and Internet settings

![Add Client Win11 01](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tcjv66ffchaf8gijpc8c.png)

Find the network connection in this case it's HomeWifi and click Wi-Fi in the list

![Add Client Win11 02](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k4omxwa27sdjvkty903i.png)

Click properties on your Wifi

![Add Client Win11 03](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ops0r2aqrl9ule469x1o.png)

Click Edit Next to your DNS or IP assignment if you want to set a Static IP which we'll be doing

![Add Client Win11 04](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/atvtor2u92c7txi6qlqa.png)

This is currently set to the Google DNS servers of 8.8.8.8 and 8.8.4.4. We're going to change this.

<u>Change the IP Settings</u>

Click the dropdown to Manual and make sure the Preferred DNS is set to the same IP address as your Pi-Hole e.g. 192.168.0.177. Make sure you click Save.

![Add Client Win11 05](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3y25kfco6owiupo8q7rh.png)

<u>Change just the DNS settings</u>

Click the dropdown to change from Auto to Manual and change the preferred DNS to your Pi-Hole IP address.

![Add Client Win11 06](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wf68k1wqvqrasxnzu521.png)

![Add Client Win11 07](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3d0nnj64maaz7cvn5rto.png)

Go to google.com and run a search for whatever you want on that machine. It may take a second longer than normal but go to a website from the search results.

![Check Working 01](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h8hfgfk2tnyvpwit5vsf.png)

Now, go back to the PiHole and you should see some Hits and Blocked traffic.

![Check Working 02](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6e7g4s27su3shs1y8208.png)

If there's nothing showing then check your DNS on the device, disconnect the wifi or restart and try again.

![Check Working 03](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wynse3cwxj5ju9v1noc5.png)

You can add each of your devices now to this DNS in the same way like your mobile phones, Smart TV and other internet devices to stop tracking, ads and much more.

![Check Working 04](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7z2721mgmr9ej8d3dtg0.png)

Congratulations, you've deployed Pihole in a Docker container with your own custom Docker Compose file and connected up a device to use it for it's DNS.

<img width="100%" style="width:100%" src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExeW5oOWRqeWpoMDU4cG00dGNzbGx6Njg2NGd3Yndwb3ZneDZ1NzBjeiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/xT1Ra2Ik3FEyvw526c/giphy.gif">

In a future guide, we'll be looking at how we can use the Local DNS feature in Pihole with NGINX Proxy Manager to access your local services with a name and not an IP address.

Next up, we'll be looking at another way to deploy and manage Docker Containers using a GUI interface.

We're going to install a local service using Docker that will let us choose from a list of different Docker containers. This service will then deploy it for us without having to use the command line.

___

In Part 4, we 're going to be looking into Portainer and how we can use it to simplify the Docker experience.

___

For more Docker Compose files check out **ReproDev Recipes** on GitHub with Docker Compose files for you to try out yourself

{% embed https://github.com/reprodev/reprodev-recipes/ %}

___

Check out the guide below if you want more information on What Docker is and how to get started

{% embed https://dev.to/reprodev/get-started-with-docker-part-1-an-intro-to-docker-3b81 %}

___

Don't forget to explore the rest of our website as we build out more content. Stay tuned for more tutorials, tips, and tricks to help you make tech work for you.

If you want to stay up-to-date with regular updates, make sure to subscribe to our free mailing list.

___