[Solved] Failed to allocate and map port 53-53 after system restart

Hello,

My Pi-hole container does not start automatically after a system (debian) restart :

$ sudo docker ps -a | grep pihole
ffb0952aee2a   pihole/pihole:latest                          "/s6-init"               4 minutes ago   Exited (128) About a minute ago                                                                                                                                                                                                                                                                                                                     pihole
$ sudo journalctl -u docker
...
time="2023-09-08T08:25:58.882268255+02:00" level=warning msg="Failed to allocate and map port 53-53: Error starting userland proxy: listen udp4 192.168.9.105:53: bind: cannot assign requested address"
time="2023-09-08T08:25:59.011007483+02:00" level=error msg="failed to start container" container=ffb0952aee2a6eaf77f99c0191b901da814acf1abf195b48c16cffdeeee33b71 error="driver failed programming external connectivity on endpoint pihole (9f1434b34c23047850468343890140a89012d63e38e1fbec0d1eac48752a1b3d): Error starting userland proxy: listen udp4 192.168.9.105:53: bind: cannot assign requested address"
...

If I manually restart using docker compose up -d, Pi-hole starts

$ sudo docker ps -a | grep pihole
ffb0952aee2a   pihole/pihole:latest                          "/s6-init"               8 minutes ago   Up 16 seconds (health: starting)   0.0.0.0:53->53/tcp, 192.168.9.105:53->53/udp, :::53->53/tcp, 67/udp, 0.0.0.0:50080->80/tcp, :::50080->80/tcp                                                                                                                                                                                                     pihole

Here is my docker-compose file :

version: "3"
services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    networks:
      - home
    ports:
      - "53:53/tcp"
      - "192.168.9.105:53:53/udp"
      - "50080:80/tcp"
    environment:
      TZ: ${TZ}
      WEBPASSWORD: ${PIHOLE_WEBPASSWORD}
    volumes:
      - ${DATA_PATH}/pihole/etc-pihole/:/etc/pihole/
      - ${DATA_PATH}/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/
      - ${DATA_PATH}/pihole/var-log/pihole.log:/var/log/pihole.log
    dns:
      - 127.0.0.1
      - 1.1.1.1
    restart: always

networks:
  home:
    ipam:
      config:
        - subnet: 172.9.0.0/24

I did some tests/checks using a startup script (crontab reboot) :

  • port 53 is not used (nc -z -v -w 1 localhost 53)
  • delaying pihole container start does not fix the problem (sleep 120)

If I remove my host IP from the docker-compose ("192.168.9.105:53:53/udp" --> "53:53/udp"), the Pi-hole container starts well after a system restart but I have DNS resolution issues with my other containers.

Thanks a lot for your help!

PS : My problem is similar to that one but using the official Pi-hole image : Issues when restarting image jacklul/pihole


Debian version: 11.5
Docker version: 24.0.6
Docker Compose version: v2.21.0
Pi-hole version: Docker Tag 2023.05.2 / Pi-hole v5.17.1 / FTL v5.23 / Web Interface v5.20.1

Hi there.

I've had this problem before. It was very frustrating.

It is caused because you have this in your compose file.

I believe that it happens when the container starts after a bootup because the network interface (192.168.9.105) isn't quite ready.

what I did was to introduce a short delay into the containers starting up, and it solved it for me. I'll have to go through my notes to see how I did this.

cd /etc/systemd/system/

sudo mkdir docker.service.d

sudo touch override.conf

sudo nano override.conf


add these lines:

[Service]
# wait for the network to be up
ExecStartPre=/bin/sleep 10
3 Likes

Thank you very much for your help @Rhubarb, this service override did the trick !

I've made some improvements to the approach. Instead of sleeping for 10 seconds, I wrote a script to check for the connection to the router (IP server) every second, until it finds it. This way the start is quicker.

#!/bin/bash

ipServerAddress="192.168.0.1"
cycleLength=1 # The length of a wait cycle in seconds
timeout=15    # Maximum number of seconds to wait before giving up

elapsedTime=0
ping -c 1 $ipServerAddress > /dev/null 2>&1
while [ $? -ne 0 ]; do
    if [ "$elapsedTime" -ge "$timeout" ]; then
        # Timeout
        exit 1
    fi

    elapsedTime=$((elapsedTime + cycleLength))
    sleep $cycleLength
    ping -c 1 $ipServerAddress > /dev/null 2>&1
done

And then I call this script in the override.conf:

[Service]
# wait for the network to be up
ExecStartPre=/etc/systemd/system/docker.service.d/wait_for_network.sh

I've saved the script next to override.conf into /etc/systemd/system/docker.service.d/. If you save it somewhere else, make sure to call it with the appropriate path. And make sure that the script is executable (chmod +x wait_for_network.sh).

1 Like

Hi,

Thanks, that’s a good suggestion. I think I may adopt that myself. I seem to remember that when I first encountered this issue I was in the middle of fixing a few other issues. Once I’d finished I never revisited this issue after the quick fix of waiting 10s. This is a much better idea.

Does
https://docs.pi-hole.net/ftldns/configfile/?#delay_startup
not work?

I did try that at the time, but it didn’t seem to work for me.. I don’t know why.. and as mentioned above I had a whole host of technical issues to work through at the time, so after a few hours of trying it, I just moved on to trying to delay the whole of docker.. a sledge hammer to crack a nut, I know, but it was a quick solution.

Now I have more time (fingers crossed) I should really go back and revisit the problem.

Just thinking about it after my reply above, I believe that it was docker that was trying to set up the network connection (because of the settings in the docker-compose file), and that attempt failed early on during start up. Hence delaying the start of pihole didn’t change that. The network error was raised by docker, not pihole.