DHCP with docker-compose and bridge networking

docker

#1

I had been running Pi-hole with docker-compose on a RaspberryPi 3 for quite some time and it worked flawlessly. Since I use built-in DHCP functionality the Pi-hole container had been running with network_mode: "host":

version: "3"
services:
  pihole:
    image: pihole/pihole:latest
    restart: unless-stopped
    network_mode: "host"
    cap_add:
        - NET_ADMIN
    environment:
...

Some time ago I tried to use bridge networking but could not get it to work. Have a look here.

Two weeks ago I decided to move away from my two RaspberryPi to one Intel® NUC as home server. Since I wanted to run multiple services that would need HTTP on port 80 (like Pi-hole) I chose to use a docker reverse proxy.

So I gave bridge networking another try. As @diginc already pointed out on GitHub you need a DHCP relay to make this work. My router does not support this so I played around with different tools and software until I settled with dhcp-helper by Simon Kelley who is also the author of dnsmasq!

I created this Dockerfile:

FROM alpine:latest
RUN apk --no-cache add dhcp-helper
EXPOSE 67 67/udp
ENTRYPOINT ["dhcp-helper", "-n"]

And copied it to the subfolder dhcp-helper.

The new docker-compose file now looks like this:

version: "3"
services:
  pihole:
    image: pihole/pihole:latest
    ports:
      - "53:53/tcp"
      - "53:53/udp"
    restart: unless-stopped
    cap_add:
        - NET_ADMIN
    dns:
      - 127.0.0.1
      - 1.1.1.1
    environment:
      ServerIP: x.x.x.x
      DNS1: 1.1.1.1
      DNS2: 1.0.0.1
      VIRTUAL_HOST: pi.hole
      DNSMASQ_LISTENING: all
    volumes:
      - '/home/xxx/docker/pihole/pihole/:/etc/pihole/'
      - '/home/xxx/docker/pihole/dnsmasq.d/:/etc/dnsmasq.d/'
    depends_on:
      - dhcphelper
    networks:
      backend:
        ipv4_address: '172.31.0.100'
      frontproxy_proxy-tier: {}

  dhcphelper:
    build: ./dhcp-helper
    restart: unless-stopped
    network_mode: "host"
    command: -s 172.31.0.100
    cap_add:
      - NET_ADMIN

networks:
  backend:
    ipam:
      config:
        - subnet: 172.31.0.0/16
  frontproxy_proxy-tier:
    external: true

As you can see I configured dhcphelper with host networking but this is no problem because it only needs port 67.
DNSMASQ_LISTENING: all is needed because Pi-hole now needs to listen to docker bridge network for forwarded DHCP requests and to the host network adapter for incoming DNS requests.

After this DHCP requests were answered but I had the problem that DNS server in DHCP responses was set to 172.31.0.100 which is on the internal docker network and is not reachable from my home network.
In order to fix this I added another configuration file 07-dhcp-options to the dnsmasq.d folder:

dhcp-option=option:dns-server,x.x.x.x

Where x.x.x.x stands for the external IP address of my NUC (see Dockerfile above).

With this configuration now everything is working as expected even without a dhcp-relay on another device!

I hope this post will help someone who has the same problem as I had.

Yours,
DerFetzer


#2

Thanks, I think I’ll write up some docs on DHCP detailing the many ways to handle setting it up. Do you mind if I link your post to help others set this up the same way?

Done : https://docs.pi-hole.net/docker/DHCP/


#3

Of course, you can link that post anywhere you like. I hope someone finds it useful.


#4