Pihole from docker can not connect to unbound on host machine

I am using PiHole with Docker Compose, and on a host machine I have also installed unbound.

This is my docker-compose.yml for PiHole:

version: "3"

services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    # hostname: ${HOSTNAME}
    # domainname: ${DOMAIN_NAME}
    ports:
      - "10.10.6.1:53:53/tcp"
      - "10.10.7.1:53:53/tcp"
      - "10.10.8.1:53:53/tcp"
      - "10.10.6.1:53:53/udp"
      - "10.10.7.1:53:53/udp"
      - "10.10.8.1:53:53/udp"
      - "10.10.6.1:67:67/udp"
      - "10.10.7.1:67:67/udp"
      - "10.10.8.1:67:67/udp"
      - "10.10.6.1:8080:80/tcp"
      - "10.10.8.1:8080:80/tcp"
    environment:
      - FTLCONF_LOCAL_IPV4=${FTLCONF_LOCAL_IPV4}
      - TZ=${TZ:-UTC}
      - WEBTHEME=${WEBTHEME:-default-light}
      - REV_SERVER=false
      - PIHOLE_DNS_=127.0.0.1#5335
      - DNSSEC=true
      - DNSMASQ_LISTENING=single
    volumes:
      - './custom_configs/etc/pihole:/etc/pihole'
      - './custom_configs/etc/dnsmasq.d:/etc/dnsmasq.d'
      - './custom_configs/etc/unbound/unbound.conf.d:/etc/unbound/unbound.conf.d/'
    restart: unless-stopped

And this is /etc/unbound/unbound.conf.d/pihole.conf:

server:
    verbosity: 2

    interface: 127.0.0.1
    port: 5335
    access-control: 127.0.0.0/8 allow
    access-control: 172.17.0.0/24 allow
    access-control: 172.21.0.0/24 allow
    cache-max-ttl: 14400
    cache-min-ttl: 600
    do-ip4: yes
    do-udp: yes
    do-tcp: yes
    hide-identity: yes
    hide-version: yes
    minimal-responses: yes
    qname-minimisation: yes
    rrset-roundrobin: yes
    #tls-upstream: yes
    #tls-system-cert: yes
    use-caps-for-id: yes
 
    do-ip6: no
    prefer-ip6: no
    harden-glue: yes
    harden-dnssec-stripped: yes
    use-caps-for-id: no
    edns-buffer-size: 1232
    prefetch: yes
    num-threads: 1
    so-rcvbuf: 1m

    private-address: 192.168.0.0/16
    private-address: 169.254.0.0/16
    private-address: 172.16.0.0/12
    private-address: 10.0.0.0/8

Now, on I host machine I say dig google.com @127.0.0.1 -p 5335 and I receive DNS answer.

Then I go to PiHole docker: sudo docker exec -it pihole bash and say:
dig google.com @172.21.0.1 -p 5335 or dig google.com @host.docker.internal -p 5335, an the connection timeouts. No result.

On a host machine I have ufw, but I said sudo ufw allow from any to any port 5335, and the result is the same. Connection from docker to the host machine timeouts...

127.0.0.1 refers to the local machine, which in case of Docker would refer to the container, so this would only work if you'd run a third-party image that combines Pi-hole and unbound in the same container - which apparently you don't do.

Depending on how you installed unbound (bare metal or as another container), you'd need to configure your Pi-hole to use your host's or container's IP address instead.

EDIT:
As for unbound: You'd also have to adopt unbound's configuration to be less restrictive.

I failed to spot that your attempt at lifting that restriction is faulty:
You still bind to 127.0.0.1 - your access-control runs empty in that case.

You want to change that interface: 127.0.0.1 to eth0 or whatever your host machine's interface name is, or be less lenient and limit that to unbound's IP.
Depending on Docker's network mode, you may not need to add allow-lists for Docker internal IPs.

Apologies for not spotting that earlier.
My only excuse it that this is the Pi-hole forum, not the unbound one - we are more versed in finding Pi-hole issues here. :wink:

1 Like

Well, you are correct, but this is not a problem.

The first problem is, that there is no connection from docker to unbound on a host machine. When I will solve this, I can change PIHOLE_DNS setting.

I mean, I can set PIHOLE_DNS_=host.docker.internal#5335, but it will still not be working, right? Because I cannot connect to unbound from inside docker.

Do you run unbound as bare metal or as another container?

Baremetal.

Then replacing 127.0.0.1 with your host machine's IP would suffice.
EDIT: In your case, that could be:

  - PIHOLE_DNS_=${FTLCONF_LOCAL_IPV4}#5335

Unfortunately this is not working. I say dig google.com @my.ip.xx.xx -p 5335 and connection times out.

I also said sudo ufw allow from any to any port 5335 on a host machine. And dig google.com @my.ip.xx.xx -p 5335 also returns communications error - connection refused.

I guess it is some stupid mistake, but I can not find what...

What machine did you run that dig command from?

On na host machine (Debian 12) and inside the PiHole docker.

What kind of network is the Docker container running on? macvlan will be isolated from the host.

Hmm, how can I check that? Can you see that from docker-compose.yml (above)?

By default, unbound would listen on localhost only, and the unbound configuration of Pi-hole's unbound guide goes a step further to enforce that behaviour.

I failed to spot that your attempt at lifting that restriction is faulty.

I've updated my previous reply accordingly.

OK, now I see that IP is 192.168.1.10, but it still times out.

What is the host server that you are running Docker on?

Debian 12.

Can you show the output from

docker network ls

docker network ls

NETWORK ID     NAME              DRIVER    SCOPE
3f624e5f0627   bridge            bridge    local
82255210532e   host              host      local
9afc8eb879c8   joplin_default    bridge    local
307ef100f137   none              null      local
277554ce113e   pi-hole_default   bridge    local

If that's the complete configuration, it would imply Docker's default bridge mode.

I don't quite get you here - could you elaborate?
Where do you see that IP?
And could you post your current docker-compose.yml and unbound.conf.d/pihole.conf?

What does the following output?

docker container inspect \
  --format '{{range $net,$v := .NetworkSettings.Networks}}{{printf "%s\n" $net}}{{end}}' \
  pihole

This should list the network(s) that the container is attached to.

docker container inspect pihole -f "{{json .NetworkSettings.Networks }}"

This will output a string with more information on the IP address scheme for the docker network that the container is attached to.

First command gives that output:

pi-hole_default

The second one:


{"pi-hole_default":{"IPAMConfig":null,"Links":null,"Aliases":["pihole","f755c506ccab"],"NetworkID":"277554ce113e49473be6194de9acc1bc38910172ad683ff6cca9e98eb71f2238","EndpointID":"fc7b0fc76ee55165c525de9b81188328910fe8a80b4a7f7d98f30a8549035d3d","Gateway":"172.21.0.1","IPAddress":"172.21.0.2","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:15:00:02","DriverOpts":null}}