1

I'm currently working on a little home project where i host various services on a raspberry pi 4 via docker. While working on this project i now encountered a dns problem which i can't really get my head around. I'm hosting pihole inside a container and configured it to use my router as an upstream dns server. On my router i have configured my raspberry pi as the local dns server and added a fiew other upstream dns servers. From my understanding this would lead to all dns requests getting routed trough my pihole container on my raspberry pi and then back to my router to get it resolved. So far this setup works for all my devices on my local network including the raspberry pi itself.

The only problem i now encounter is with other containers on the same raspberry pi that are inside the same and/or different networks than pihole. All of them seem to have problems with resolving dns queries. For example: I have a phpmyadmin countainer connected to the same docker network as the pihole container. If i now ssh into the phpmyadmin container and want to execute 'ping google.com' or 'apt-get update' it won't be able to execute these commands because of failing dns.

What i already checked:

  • I looked at /etc/resolv.conf of the phpmyadmin container => It includes 127.0.0.11 - which is correct by my knowlegde
  • I looked at /etc/resolv.conf of the host => It includes the actual ip of my raspberry pi (NOT 127.0.0.1). I do not understand why it uses the actual ip instead of localhost here but it does work anyway
  • I restarted docker daemon
  • I recreated the networks included in my docker-compose.yml
  • I recreated the phpmyadmin container

So far none of the above steps solved the problem.

Out of curiosity i then set the ip of my router in /etc/dhcpcd.conf on my host as a static nameserver and reloaded both the dhcpcd and docker daemon. If i now ssh into my phpmyadmin container dns suddenly works. I excluded my routers ip again to verify my problem and dns stops working immediately. This leads me to the conclusion that all my docker containers (excluding pihole - because i specified dns 127.0.0.1 for this container) seem to have a problem with using my hosts ip address for dns.

My current docker-compose.yml:

version: '3'

services:
  portainer:
    image: portainer/portainer-ce:linux-arm
    container_name: portainer
    restart: unless-stopped
    environment:
      TZ: Europe/Berlin
    networks:
      - frontend
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data
    labels:
      - traefik.enable=true
      - traefik.docker.network=compose_frontend
      - traefik.http.routers.portainer.entrypoints=web_tcp
      - traefik.http.routers.portainer.rule=Host(`portainer.mydomain`)
      - traefik.http.services.portainer.loadbalancer.server.port=9000


  traefik:
    image: traefik:latest
    container_name: traefik
    restart: unless-stopped
    environment:
      TZ: Europe/Berlin
    networks:
      - frontend
    ports:
      - 80:80
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /home/farmadmin/config/traefik:/etc/traefik
    labels:
      - traefik.enable=true
      - traefik.docker.network=compose_frontend
      - traefik.http.routers.traefik.entrypoints=web_tcp
      - traefik.http.routers.traefik.rule=Host(`traefik.mydomain`)
      - traefik.http.services.traefik.loadbalancer.server.port=8080

  pihole:
    image: pihole/pihole:latest
    container_name: pihole
    restart: unless-stopped
    environment:
      TZ: Europe/Berlin
    networks:
      - frontend
    dns:
      - 127.0.0.1
    ports:
      - 53:53/tcp
      - 53:53/udp
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - etc-pihole:/etc/pihole/
      - etc-dnsmasq.d:/etc/dnsmasq.d/
    labels:
      - traefik.enable=true
      - traefik.docker.network=compose_frontend
      - traefik.http.routers.pihole.entrypoints=web_tcp
      - traefik.http.routers.pihole.rule=Host(`pihole.mydomain`)
      - traefik.http.routers.pihole.middlewares=dashboard_prefix
      - traefik.http.middlewares.dashboard_prefix.addprefix.prefix=/admin
      - traefik.http.services.pihole.loadbalancer.server.port=80

  mariadb:
    image: linuxserver/mariadb:latest
    container_name: mariadb
    restart: unless-stopped
    environment:
      - TZ=Europe/Berlin
      - PUID=1000
      - PGID=1000
    networks:
      - backend
    volumes:
      - mariadb_data:/config

  phpmyadmin:
    image: phpmyadmin:latest
    container_name: phpmyadmin
    restart: unless-stopped
    environment:
      - TZ=Europe/Berlin
      - PMA_HOST=mariadb
      - PMA_PORT=3306
    networks:
      - frontend
      - backend
    labels:
      - traefik.enable=true
      - traefik.docker.network=compose_frontend
      - traefik.http.routers.phpmyadmin.entrypoints=web_tcp
      - traefik.http.routers.phpmyadmin.rule=Host(`phpmyadmin.mydomain`)
      - traefik.http.services.phpmyadmin.loadbalancer.server.port=80

networks:
  frontend:
  backend:
    internal: true

volumes:
  # Persistent Portainer Data
  portainer_data:
  
  # Persistent Pihole Data
  etc-pihole:
  etc-dnsmasq.d:

  # Persistent MariaDB Data
  mariadb_data:

So my questions would be: Why does the hosts resolv.conf include its full own ip instead of localhost? Why is my host able to resolve dns queries with its own ip but my docker containers aren't? How can i solve this problem without setting the hosts nameserver to my router?

1
1

So, digging into this issue further (I had the same issue on one of my Pis), I found that if you're running a local DNS resolver on that server, and you want Docker's DNS to work with it properly, you need to make sure the Pi's /etc/resolv.conf file has the nameserver 127.0.0.1 (as you mentioned).

And to make that change stick, you should edit the /etc/resolvconf.conf file and uncomment the line:

# If you run a local name server, you should uncomment the below line and
# configure your subscribers configuration files below.
name_servers=127.0.0.1

After that you can reboot or regenerate the file immediately with sudo resolvconf -u.

As to why resolvconf drops the IP address of the Pi into /etc/resolv.conf by default—I believe unless you override the name_servers or have things customized in /etc/network/interfaces, it typically drops in the IP(s) of the DNS server(s) your router provides—which would be the IP address of your Pi! (Catch 22... but it's tricky to debug since many things besides Docker work fine with that setup!).

2
  • 1
    Honestly this is the best/cleanest solution to this problem i have found so far. After i posted the question a while ago i kept searching on the net for similar problems/solutions. It seems like the most widespread soluations are either 1. hardcoding dns servers ip in the docker daemon (which i dont like) or 2. messing around with ip tables so that docker containers are able to communicate with the host over network (seems messy too). – SleepyNeko May 21 at 10:55
  • I had however temporarily solved this problem by configuring a static ip for my pihole container and then overriding the dns server of every other container that needed network access with it. I have adjusted to the solution provided above tho because it seems a lot nicer and makes a lot more sense than mine. – SleepyNeko May 21 at 11:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.