Solution

It was found (here, and here) that Podman uses its own DNS server, aardvark-dns which is bound to port 53 (this explains why I was able to bind to 53 with nc on the host while the container would still fail). So the solution is to bridge the network for that port. So, in the compose file, the ports section would become:

ports:
  - "<host-ip>:53:53/tcp"
  - "<host-ip>:53:53/udp"
  - "80:80/tcp"

where <host-ip> is the ip of the machine running the container — e.g. 192.168.1.141.


Original Post

I so desperately want to bash my head into a hard surface. I cannot figure out what is causing this issue. The full error is as follows:

Error: cannot listen on the UDP port: listen udp4 :53: bind: address already in use

This is my compose file:

version: "3"
services:
  pihole:
    container_name: pihole
    image: docker.io/pihole/pihole:latest
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "80:80/tcp"
    environment:
      TZ: '<redacted>'
    volumes:
      - './etc-pihole:/etc/pihole'
      - './etc-dnsmasq.d:/etc/dnsmasq.d'
    restart: unless-stopped

and the result of # ss -tulpn:

Netid       State        Recv-Q       Send-Q                             Local Address:Port               Peer Address:Port       Process                                         
udp         UNCONN       0            0                    [fe80::e877:8420:5869:dbd9]:546                           *:*           users:(("NetworkManager",pid=377,fd=28))       
tcp         LISTEN       0            128                                      0.0.0.0:22                      0.0.0.0:*           users:(("sshd",pid=429,fd=3))                  
tcp         LISTEN       0            128                                         [::]:22                         [::]:*           users:(("sshd",pid=429,fd=4))        

I have looked for possible culprit services like systemd-resolved. I have tried disabling Avahi. I have looked for other potential DNS services. I have rebooted the device. I am running the container as sudo (so it has access to all ports). I am quite at a loss.

  • Raspberry Pi Model 1 B Rev 2
  • Raspbian (bookworm)
  • Kernel v6.6.20+rpt-rpi-v6
  • Podman v4.3.1
  • Podman Compose v1.0.3

EDIT (2024-03-14T22:13Z)

For the sake of clarity, # netstat -pna | grep 53 shows nothing on 53, and # lsof -i -P -n | grep LISTEN shows nothing listening to port 53 — the only listening service is SSH on 22, as expected.

Also, as suggested here, I tried manually binding to port 53, and I was able to without issue.

    • Kalcifer@sh.itjust.worksOP
      link
      fedilink
      English
      arrow-up
      1
      arrow-down
      1
      ·
      9 months ago

      Yup. I ran # nc -u -l 0.0.0.0 53 to listen on port 53. Then I ran # drill @127.0.0.1 53 archlinux.org in another shell. I saw the request in the listening shell.

      • catloaf@lemm.ee
        link
        fedilink
        English
        arrow-up
        1
        ·
        edit-2
        9 months ago

        Hmm. Can you run another service like https://github.com/vhiribarren/docker-echo-server on udp 53? If it fails, can you bind another port, both under and over 1024, with success? That would tell us if it’s something with that image or a system problem.

        Edit: I remember when I was running pihole under docker, maybe this? Not sure if anyone has mentioned it: https://github.com/pi-hole/docker-pi-hole/issues/968 (the NET_ADMIN capability is different from running as root).

        Maybe also try starting the container without the port maps in the compose file to see if that works?

        Also what network are you using? I think I had to put mine in host networking.