Binding port 53 to Pi-hole in docker

When deploying pi-hole via docker on your Linux or Mac machine, there's a high probability that port 53 is already being used to resolve DNS requests via your local machine to an upstream server, and as such you can not bind your docker container to port 53 on the host.

You'll likely see the error:
listen tcp4 0.0.0.0:53: bind: address already in use

To find what is using port 53 you can execute:
sudo lsof -i -P -n | grep LISTEN
on Linux, or on Mac:
sudo lsof -i :53

You can be 99.9% sure that systemd-resolved on Linux (or mDNSResponseder on Mac) is what is listening to port 53.

Before diving in and disabling your local DNS resolver, you probably want to consider moving Pi-Hole to it's own VLAN instead. This will ensure it gets its own interface on your network and will make discover of clients better in the pi-hole itself.

To do that, you'll want to add a Macvlan.

Macvlan network driver
All about using Macvlan to make your containers appear like physical machines on the network

To do this, you can add a new "network" section to your docker-compose.yml:

networks:
  vlan:
    enable_ipv6: true
    driver: macvlan
    driver_opts:
      parent: eno1
    ipam:
      config:
        - subnet: 192.168.1.0/24
          gateway: 192.168.1.1
          ip_range: 192.168.1.1/24 # this must not overlap with your DHCP range
        - subnet: 2001:db8:3333::/64
          gateway: 2001:db8:3333::1

You can now use this new VLAN in your main pi-hole service configuration:

services:
  pihole:
  ...
    networks:
      vlan:
        ipv4_address: 192.168.1.10

Here, you just need to specify the actual IP address you want to assign your Pi-Hole. This will now be the IP address of your new Pi-Hole DNS Server.
You can access the Pi-Hole admin cosole here too. e.g:
`http://192.168.1.10/admin`

Option 2

If you really want to disable your local DNS resolver, or you're not quite comfortable with Docker VLANs yet, you can go ahead and do that.

Be aware however, this may have other side-effects if you even remove or shut down your pi-hole container. (i.e. you'll loose the ability to resolve domains by name.)

So, to go ahead and disable it, you can use these 2 commands:

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

Now you have port 53 open, but no DNS configured for your host.

To fix that, you need to edit /etc/resolv.conf and add your upstream DNS nameserver IP address. e.g.:

nameserver 1.1.1.1

If you have another name-server in that file, just comment it out in case you need to remember the original value.
Once your pi-hole docker container is up and running, you can change the DNS server of your host to localhost, as you are binding port 53 to the host machine. Again, change /etc/resolv.conf like this:

nameserver 127.0.0.1

Have a look at the official Docker Pi-Hole documentation for more information on configuration options, running pi-hole as a DHCP server etc.

GitHub - pi-hole/docker-pi-hole: Pi-hole in a docker container
Pi-hole in a docker container. Contribute to pi-hole/docker-pi-hole development by creating an account on GitHub.