Create an unbound docker-compose example
Started based off conversation in #311
In the same style of the existing docker-compose example files, let's create a multi-service docker-compose yaml file with unbound + pihole using https://docs.pi-hole.net/guides/unbound/ as the basis.
First iteration may only support x86 as I don't see much for ARM unbound images.. See: unbound containers available on docker hub.
I was curious about this as well.
So one thing I was unsure on... what listens on port 53? You have Pi-Hole on 53, right? And then it doesn't matter with Unbound is on, you just set that same Port in the config, correct?
Exactly, you start a unbound container e.g.: -p 5553:53 then set UnboundContainerIP#5553 in pihole settings. https://docs.pi-hole.net/guides/unbound/
When you say UnboundContainerIP, you mean the DockerHostIP, right?
Depends if you use docker host networking or default docker bridge networking.
I'm not a huge fan of containers ran using host networking mode because it decreases the isolation docker provides so all of my examples are bridged unless otherwise stated.
Having bridged docker containers connect to each other on docker's internal network is the common approach. Typically that'd be done by using the hostname alias provided by Docker since it abstracts Docker's DHCP providing a random IP address.
Since Pi-hole needs IPs for DNS and Docker DHCP adds randomness I'm thinking the example will need to have a static Docker IP address applied to the unbound container's config.
Well, the key is the -p 5553:53. If you use that, then the host's port 5553 will be listening to your Unbound container's 53. i.e. you'd use DockerHostIP#5553 or UnboundContainerIP#53 to connect directly, where the UnboundContainerIP is not consistent and you'd have to be linked. This is all without host networking. The -p flag is invalid is you do host networking and either IP would work at 53.
Is that correct?
OK, I get what you're saying now, that could be a valid alternative to using the static IP on unbound and having Pi-hole use said static ip.
I was just thinking that going out of the docker LAN and back in through the port forward is an unnecessary hop and exposes a service that doesn't have to be exposed. Staying within the Docker internal network with a static IP on unbound is a little cleaner IMO. Either approach should work and the extra -p 5553:53 to unbound may actually be useful for Pi-hole debugging purposes.
I'm not 100% sure how docker network routing works with their current implementation, the bottom of this page discusses it but I find it confusing.
The --userland-proxy parameter, true by default, provides a userland implementation for inter-container and outside-to-container communication. When disabled, Docker uses both an additional MASQUERADE iptable rule and the net.ipv4.route_localnet kernel parameter which allow the host machine to connect to a local container exposed port through the commonly used loopback address: this alternative is preferred for performance reasons.
That bit does makes me think the new userland-proxy (on by default) is not as efficient for container connections that go out to a docker host port forward and then back into another container.
@CWSpear correct. I got it to work without the -p flag and use a static container IP. Pi-hole and unbound need to be on the same bridge.
So this should work in theory (NOT TESTED):
(Note, in these examples, replace <DOCKER_HOST_IP> with the host of your Docker host... i.e. the regular local IP address of the machine that's hosting Docker, for example 192.168.1.12 (i.e. this is assigned by my router. Also change <LOCAL_PIHOLE_VOLUME_PATH> to the path you want to persist the container's /etc/pihole/ directory.)
version: '3.7'
services:
pihole:
image: pihole/pihole
restart: unless-stopped
links:
- ubound
ports:
- 53:53/tcp
- 53:53/udp
- 67:67/udp
volumes:
- <LOCAL_PIHOLE_VOLUME_PATH>:/etc/pihole/
- /etc/dnsmasq.d/:/etc/dnsmasq.d/
# this isn't strictly necessary, but Ubuntu 18.04 has a symlink to here and I didn't want to mess
- /etc/dnsmasq.d-available/:/etc/dnsmasq.d-available/
cap_add:
- NET_ADMIN
dns: 127.0.0.1
environment:
TZ: America/Los_Angeles
ServerIP: <DOCKER_HOST_IP>
PROXY_LOCATION: pihole
DNS1: unbound#53
DNS2: no
unbound:
image: mvance/unbound
restart: unless-stopped
The links entry will add an entry to the pihole container so that unbound will resolve to the internal IP for the unbound container. This IP is not static, and can change between creating the container, so you don't want to hard code that IP. This is what links is for.
If someone wants to use that as a starting point...
If pihole won't accept a hostname as the DNS1, you can expose unbound's IP on a different port (9753 in this example), and then it will be listening on that host's port:
version: '3.7'
services:
pihole:
image: pihole/pihole
restart: unless-stopped
links:
- ubound
ports:
- 53:53/tcp
- 53:53/udp
- 67:67/udp
volumes:
- <LOCAL_PIHOLE_VOLUME_PATH>:/etc/pihole/
- /etc/dnsmasq.d/:/etc/dnsmasq.d/
# this isn't strictly necessary, but Ubuntu 18.04 has a symlink to here and I didn't want to mess
- /etc/dnsmasq.d-available/:/etc/dnsmasq.d-available/
cap_add:
- NET_ADMIN
dns: 127.0.0.1
environment:
TZ: America/Los_Angeles
ServerIP: <DOCKER_HOST_IP>
PROXY_LOCATION: pihole
DNS1: <DOCKER_HOST_IP>#9753
DNS2: no
unbound:
image: mvance/unbound
restart: unless-stopped
ports:
- 9753:53/tcp
- 9753:53/udp
Anyway... something like that...
Hello, Could you also add open vpn ? ☺️ Thanks !
With DNS2: no getting:
ERROR: The Compose file './docker-compose.yml' is invalid because:
services.pihole.environment.DNS2 contains false, which is an invalid type, it should be a string, number, or a null
Without it or with - DNS2='' pihole just fills it up with the second default server which is Google's 8.8.4.4 Can anyone suggest how to solve this please?
@CWSpear did you by any chance test this? Whatever I do pihole keeps saying "dns resolution unavilable" though I can resolve via exposed port 5353 in my case from the local lan but not from the overlay with:
services:
unbound:
container_name: unbound
image: mvance/unbound:latest
networks:
unimatrix01:
hostname: unbound
ports:
- "6353:53/tcp"
- "6353:53/udp"
DNS1: 192.168.254.246#6353
I made small adjustmend from the example CWSpear Link to the Post and it works for me.
Service pihole:
- links: - unbound fix typo
- ports: - 85:80/tcp (open Port for Pi-Hole Admin Console)
- volumes: link to the local timesone as a host volume share
- DNS1: 127.0.0.1#5353 (use the localhost ip) & DNS2: 213.73.91.35 (Chaos Computer Club)
service unbound:
- ports: -5353:53 (use default unbound host port)
services:
pihole:
image: pihole/pihole
restart: unless-stopped
links:
- unbound
ports:
- 53:53/tcp
- 53:53/udp
- 67:67/udp
- 85:80/tcp
volumes:
- ./pihole_unbound/pihole:/etc/pihole
- ./pihole_unbound/dnsmasq.d:/etc/dnsmasq.d
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
# this isn't strictly necessary, but Ubuntu 18.04 has a symlink to here and I didn't want to mess
cap_add:
- NET_ADMIN
dns: 127.0.0.1
environment:
# TZ: America/Los_Angeles # use Host-Timezone with volumes
# ServerIP: <DOCKER_HOST_IP>
# WEBPASSWORD: IfYOuNeedSetA_StaticPassword
PROXY_LOCATION: pihole
DNS1: 127.0.0.1#5353
DNS2: 213.73.91.35
# DNS2 == Chaos Computer Club
unbound:
image: mvance/unbound
restart: unless-stopped
ports:
- 5353:53/tcp
- 5353:53/udp
I made small adjustmend from the example CWSpear Link to the Post and it works for me.
I've used what you've done, however, I'm not sure it's actually working. If I remove the second DNS server and solely rely on Unbound (i.e. 127.0.0.01:5353) and then do dig commands to random URLs, it won't resolve which tells me that pi-hole is not linking to unbound.
@eflemingtra 127.0.0.01:5353 please check the IP, it could be DNS1 127.0.0.1:5353
I check my pihole dns request, and get follow response. The IP 127.0.0.11 is right (as far as I know) this is the docker proxy local IP)
$dig startpage.com
;; Query time: 37 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
I check my pihole dns request, and get follow response. The IP 127.0.0.11 is right (as far as I know) this is the docker proxy local IP)
Okay, so it seems to be an issue with Ubuntu. Unbound appears to be working, but unless I specify Ubuntu to use 127.0.0.1@5354, it won't work.
So, for example, dig pi-hole.net @127.0.0.1 -p 5354 gives me a positive response. If I just do dig pi-hole.net, nothing is resolved. Similarly, if I input any command that requires an internet connection (say apt-get update), it won't work. Interestingly, all my other containers that require net access are working fine. I'm guessing I need to tell Ubuntu to use 127.0.0.1#5354?
With
DNS2: nogetting:ERROR: The Compose file './docker-compose.yml' is invalid because: services.pihole.environment.DNS2 contains false, which is an invalid type, it should be a string, number, or a nullWithout it or with
- DNS2=''pihole just fills it up with the second default server which is Google's8.8.4.4Can anyone suggest how to solve this please?
I put DNS2="no" and it seems to work and leave it empty. (Note the double quotes)
I created a single docker image containing both pihole and unbound. Unbound is exposed as port 5053 and pihole uses port 53, plus 80 and 443. (These aren't in the docker-compose file since I'm linking to an external network but they can be added.) It's my first shot at docker so I'm sure it can be improved but it does seem to work for me.
Code: https://github.com/mcarson75/unbound-pihole Docker image: mcarson75/unbound-pihole:amd64
https://github.com/chriscrowe/docker-pihole-unbound
This issue is stale because it has been open 30 days with no activity. Please comment or update this issue or it will be closed in 5 days.
I'm trying to run both Pihole and Unbound using a Docker compose, but I'm facing an issue I cannot fix. Once the containers are up, DNS queries are forwarded from Pihole to Unbound on the Pihole log. Still, the host where I'm running the containers lost its ability to make queries, e.g., If I do dig pi-hole.net on the host console I can't resolve the IP address.
; <<>> DiG 9.16.44-Debian <<>> pi-hole.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 58616
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;pi-hole.net. IN A
;; Query time: 3999 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Fri Feb 09 19:02:24 -03 2024
;; MSG SIZE rcvd: 29
I used the same configuration some people here have used without success. Since I can't resolve DNS on the Pihole container, I keep getting DNS resolution errors on the Pihole log, and the Gravity tables are not updated.
pihole | fatal: unable to access 'https://github.com/pi-hole/pi-hole/': Could not resolve host: github.com
pihole | fatal: unable to access 'https://github.com/pi-hole/web/': Could not resolve host: github.com
pihole | fatal: unable to access 'https://github.com/pi-hole/FTL/': Could not resolve host: github.com
pihole | Pi-hole version is v5.17.3 (Latest: N/A)
pihole | web version is v5.21 (Latest: N/A)
pihole | FTL version is v5.24 (Latest: N/A)
pihole | Container tag is: 2024.01.0
My docker-compose.yaml looks like the following:
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
hostname: PIhole-2
links:
- unbound
ports:
- "53:53/tcp"
- "53:53/udp"
- "80:80/tcp"
- "443:443/tcp"
environment:
TZ: 'America/Recife'
WEBPASSWORD: '@Pihole65'
DNSSEC: true
PROXY_LOCATION: pihole
DNS1: 127.0.0.1#5335
DNS2: "no"
dns:
- 127.0.0.1#5335
volumes:
- './etc-pihole:/etc/pihole'
- './etc-dnsmasq.d:/etc/dnsmasq.d'
restart: unless-stopped
unbound:
container_name: unbound
image: "mvance/unbound:latest"
hostname: unbound
restart: unless-stopped
ports:
- "5335:53/tcp"
- "5335:53/udp"
I noticed that the DNS resolution in the container host is being sent to 127.0.0.11, instead of the DNS server in /etc/resolv.conf. I'm using docker on a Ubuntu 23.04.
https://github.com/Blu-Eagle/pihole-ubound-tls-portainer.git easier than this is impossible, just 1 image and few env var.