Get Started with Docker - Part 3: Pi-Hole

Repro Dev - Mar 3 - - Dev Community

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.

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://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


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
Enter fullscreen mode Exit fullscreen mode

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

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

to this one

      WEBPASSWORD: 'yourownpassword'
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

  • Type the wsl command to open a WSL shell
wsl
Enter fullscreen mode Exit fullscreen mode

Login to Linux Shell 02

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

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

Then just

  • Open a terminal

Login to Linux Shell 04

šŸ’” 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
Enter fullscreen mode Exit fullscreen mode

Login to Linux Shell 05

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

pwd
Enter fullscreen mode Exit fullscreen mode

Login to Linux Shell 06

Login to Linux Shell 07

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Docker Persistent 01

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

pwd
Enter fullscreen mode Exit fullscreen mode

Docker Persistent 02

You should be in /home/(yourusername)

/home/reprodev/
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Docker Persistent 03

Run the below commands to create the Pihole config folder

mkdir pihole
cd pihole
Enter fullscreen mode Exit fullscreen mode

Docker Persistent 04

Docker Persistent 05

Docker Persistent 06

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

/home/reprodev/docker/Files/AppData/Config/pihole
Enter fullscreen mode Exit fullscreen mode

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

pwd
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Nano Editor 01

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

Nano Editor 02

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

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

Nano Editor 04

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

Ctrl+S
Enter fullscreen mode Exit fullscreen mode

Nano Editor 05

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

Ctrl+X
Enter fullscreen mode Exit fullscreen mode

Nano Editor 06

Nano Editor 07

Nano Editor 08

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

GitHub logo reprodev / reprodev-recipes

ReproDev Recipes is a repository of code snippets and docker compose files from reprodev.com

Welcome to ReproDev Recipes!

This repository contains a collection of code snippets and examples that provide step-by-step instructions for solving common programming problems.


This is a companion piece to guides and articles on ReproDev.com


License

This repository is licensed under the MIT License. See the LICENSE file for details.


Usage

To use ReproDev Recipes, simply browse the repository and select the recipe that best matches your needs. Each recipe is located in its own folder, and includes a detailed README file with instructions and code snippets.

You are free to use, modify, and distribute the code in this repository, as long as you include a copy of the MIT License in your project.


Contributing

If you would like to contribute to ReproDev Recipes, we welcome your pull requests! To get started, simply fork the repository, create a new branch for your changes, and submit a pull request with a clearā€¦





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
Enter fullscreen mode Exit fullscreen mode

Deploy Pihole 01

Deploy Pihole 02

Deploy Pihole 03

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

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

Deploy Pihole 05

We can check this by running the below command

docker ps
Enter fullscreen mode Exit fullscreen mode

Deploy Pihole 06

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

Deploy Pihole 07

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

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

Deploy Pihole 10

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

Deploy Pihole 11

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

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

Add Client Win11 02

Click properties on your Wifi

Add Client Win11 03

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

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.

Change the IP Settings

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

Change just the DNS settings

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

Add Client Win11 06

Add Client Win11 07

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

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

Check Working 02

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

Check Working 03

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

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.

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

GitHub logo reprodev / reprodev-recipes

ReproDev Recipes is a repository of code snippets and docker compose files from reprodev.com

Welcome to ReproDev Recipes!

This repository contains a collection of code snippets and examples that provide step-by-step instructions for solving common programming problems.


This is a companion piece to guides and articles on ReproDev.com


License

This repository is licensed under the MIT License. See the LICENSE file for details.


Usage

To use ReproDev Recipes, simply browse the repository and select the recipe that best matches your needs. Each recipe is located in its own folder, and includes a detailed README file with instructions and code snippets.

You are free to use, modify, and distribute the code in this repository, as long as you include a copy of the MIT License in your project.


Contributing

If you would like to contribute to ReproDev Recipes, we welcome your pull requests! To get started, simply fork the repository, create a new branch for your changes, and submit a pull request with a clearā€¦





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


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.


. . . . . . . . . . . . .