Table of Contents

Pi-hole® is a DNS sinkhole that protects your devices from unwanted content, without installing any client-side software.

We will use Pi-hole as our DNS server in our local network in order to block ads on all devices. It is important for Pi-hole to be run on a device or server that is constantly running, as we will configure our router to point to this device for any DNS query. So without it running we will not be able to access any webpage.

Specifically, in this guide we will configure Pi-hole to run as a Docker container in our Ubuntu server which is located in our local network. This is a very convenient way of installing it, as we do not need an extra device only yo run Pi-hole.

The same steps could be done to configure Pi-hole in the cloud or on a remote server, but some additional steps are needed to make the remote server and connection to it secure.

This guide assumes, that Docker and Docker Compose is already installed in your system.

Stop DNS resolver

For Ubuntu based systems, we first need to stop and disable the existing DNS resolver, as we will use Pi-hole as our DNS resolver:

sudo systemctl stop systemd-resolved.service
sudo systemctl disable systemd-resolved.service

Now we do not have any internet access, because we need to change the DNS server in the system setting:

sudo vim /etc/resolv.conf

Change the default DNS address to some other, like Cloudflare DNS 1.1.1.1:

# nameserver 127.0.0.53
nameserver 1.1.1.1

Run Pi-hole Using Docker

Download Pi-hole Docker’s repository

Clone the Pi-hole repository in your system and navigate into it:

git clone https://github.com/pi-hole/docker-pi-hole.git
cd docker-pi-hole

Copy the example docker-compose.yml.example file:

cp docker-compose.yml.example docker-compose.yml

Open the docker-compose.yml file:

version: "3"

# https://github.com/pi-hole/docker-pi-hole/blob/master/README.md

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"
      - "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"
      # run `touch ./var-log/pihole.log` first unless you like errors
      # - './var-log/pihole.log:/var/log/pihole.log'
    # Recommended but not required (DHCP needs NET_ADMIN)
    #   https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
    cap_add:
      - NET_ADMIN
    restart: unless-stopped

Modify Docker Compose file

We need to modify it to work with our personal setting.

Delete DHCP Port

If we will not use Pi-hole as our DHCP server we do not need to expose port 67. We will not use this feature on this guide, so we can delete this line.

Change Web UI port

If the default http port 80 is already taken, we can change it to another available port. For me it is 8081:

ports:
  - "8081:80/tcp"

Change Timezone

Change the TZ variable according to your location. For me it is Europe/Athens:

environment:
  TZ: "Europe/Athens"

Add Server’s IP Address

We will add the FTLCONF_REPLY_ADDR4 and set it to our server’s LAN IP. For me it is 192.168.1.99:

environment:
  FTLCONF_REPLY_ADDR4: "192.168.1.99"

This environment variable replaces the deprecated ServerIP and solves the problem where we can not access pi.hole/admin.

Final Docker Compose file

The final version of the docker-compose.yml file is now:

version: "3"

# https://github.com/pi-hole/docker-pi-hole/blob/master/README.md

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"
      - "8081:80/tcp"
    environment:
      TZ: "Europe/Athens"
      # WEBPASSWORD: 'set a secure password here or it will be random'
      FTLCONF_REPLY_ADDR4: "192.168.1.99"
    # Volumes store your data between container upgrades
    volumes:
      - "./etc-pihole:/etc/pihole"
      - "./etc-dnsmasq.d:/etc/dnsmasq.d"
      # run `touch ./var-log/pihole.log` first unless you like errors
      # - './var-log/pihole.log:/var/log/pihole.log'
    # Recommended but not required (DHCP needs NET_ADMIN)
    #   https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
    cap_add:
      - NET_ADMIN
    restart: unless-stopped

Start Pi-hole Container

To download the images and start the container run:

docker-compose up -d

Stop Pi-hole Container

To stop the container run:

docker-compose down

View Logs

View the generated logs with docker-compose:

docker-compose logs

and find the randomly generated password:

pihole    |  ::: Starting docker specific checks & setup for docker pihole/pihole
pihole    | Assigning random password: tFTQWe5q

Access Web UI

Once Pi-hole is deployed you can navigate to http://ip-server:8081, to see the home page.

Go to the admin panel http://ip-server:8081/admin and login with the password copied earlier.

Change Password

In order to change the Web UI password we need to run a command inside the the Docker container.

Navigate inside the pihole container:

docker exec -it pihole bash

And run this command to change the password:

pihole -a -p

Type exit to exit the container:

exit

Change DNS server

To specify the default DNS resolver the Pi-hole will use, from the Web UI:

  • Navigate to the Settings section:
    • Under the DNS tab, select the desired DNS servers.
  • Scroll down and click the Save button.

View Pi-hole Blocked Domains list

To view the default blocked domains by Pi-hole, from the Web UI:

  • Navigate to the Group Management section:
    • Under the Adlists tab, you can see all the adlists.

To add a new adlist:

  • Add the URL of the adlist (adlist format: 0.0.0.0 domain.com)
  • Add a comment
  • Click the Add button.

View DNS queries

In order to see if Pi-hole is getting the DNS requests, from the Web UI:

  • Navigate to the Query Log section:
    • Here you can view the most recent DNS queries from each client

Add Local DNS Records

We can add our custom DNS records for our Local Network, in order to use domain names instead of IPs for our devices in the house. To do that, from the Web UI:

  • Navigate to the Local DNS section:
    • Under the DNS Records tab, you can add or list all local DNS domains.
    • To add a new record:
      • Select a domain name: e.g. server.home
      • Add the IP address of the device you want to use this domain for: e.g. 192.168.1.99
      • Click the Add button.

Now we can access our home server at the server.home URL.

Add Pi-hole as a DNS server on the Router

In order for Pi-hole to be able to block ads on all the devices in our network, we either need to:

  • Configure each device to use Pi-hole as its DNS server
  • Configure on our router to use Pi-hole as each DNS server for all the DHCP clients

The most efficient way is to add it the IP of server that runs Pi-hole as the DNS server and an alternative for backup like Cloudflare DNS 1.1.1.1.

This depends highly on your router’s model, but the steps are somewhat similar:

  • Go to your router’s admin panel, e.g. http://192.168.1.1
  • Navigate to the tab that has the Local Network settings.
  • Find the DHCP setting.
  • Change the DNS IP address to Pi-hole server’s IP, e.g. 192.168.1.2.
  • Add an alternative DNS IP, e.g. 1.1.1.1..

It is best to restart the router in order to force all clients to update the DNS server.

Clear DNS cache

If you do not see any queries being made to Pi-hole maybe the client have cached the DNS results and they are not making new requests. To force them to make the DNS queries we need to clear the cache.

Clear DNS cache on Windows

To clear the cache system wide on Windows, open a CMD and type:

ipconfig /flushdns

Clear DNS cache on Linux

Some Linux distributions do not use DNS caching at system level, instead the application maintain their own caches.

For Ubuntu based systems to clear the cache system wide on, open a terminal and type:

sudo systemd-resolve --flush-caches

Clear DNS cache on Chrome

To clear the cache system wide on Chromium based browsers, open a new tab and type on the browser field:

chrome://net-internals/#dns

and press the Clear host cache button.

Clear DNS cache on Firefox

To clear the cache system wide on Firefox:

  • From the application menu select Settings:
    • Select the Privacy & Security tab.
    • Find the Cookies and Site Data field.
      • Press the Clear Data button.
      • Select only the Cached Web Contain field.
      • Press Clear

Upgrade Pi-hole

If a new image is available, the steps to update our Pi-hole container are the following:

  • Download the latest version of the image:
docker pull pihole/pihole
  • Stop and delete the current container (no logs/customizations will be deleted because we have them volume-mapped):
docker-compose down
docker rm -f pihole
  • Start the container with the newer base image:
docker-compose up -d