DNS resolution is currently unavailable

System Information

Debian: 13.4

systemd-resolved: stable,now 257.9-1~deb13u1 amd64

pihole:

Core
    Version is v6.4.2 (Latest: N/A)
    Branch is master
    Hash is 3413768c (Latest: N/A)
Web
    Version is N/A (Latest: N/A)
    Branch is N/A
    Hash is N/A (Latest: N/A)
FTL
    Version is N/A (Latest: N/A)
    Branch is N/A
    Hash is N/A (Latest: N/A)

Yesterday when I installed pihole + unbound, everything was a-ok. But today after I messed with systemd-resolved, something went wrong. But I can't figure out why; any help would be greatly appreciated!

Expected Behaviour:

When docker compose up is ran, the DNS resolving should not error.

Actual Behaviour:

My /srv/services/docker-compose.yml file is

# More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/
secrets:
  pihole_password:
    file: "./pihole_password"
services:
  pihole:
    secrets:
      - pihole_password
    container_name: pihole
    image: pihole/pihole:latest
    ports:
      # DNS Ports
      - "53:53/tcp"
      - "53:53/udp"
      # Default HTTP Port
      - "80:80/tcp"
      # Default HTTPs Port. FTL will generate a self-signed certificate
      - "443:443/tcp"
      # Uncomment the below if using Pi-hole as your DHCP Server
      #- "67:67/udp"
      # Uncomment the line below if you are using Pi-hole as your NTP server
      #- "123:123/udp"
    environment:
      # Set the appropriate timezone for your location from
      # https://en.wikipedia.org/wiki/List_of_tz_database_time_zones, e.g:
      TZ: 'Asia/Singapore'
      # Set a password to access the web interface. Not setting one will result in a random password being assigned
      WEBPASSWORD_FILE: pihole_password
      # If using Docker's default `bridge` network setting the dns listening mode should be set to 'ALL'
      FTLCONF_dns_listeningMode: 'ALL'
      # FTLCONF_dns_upstreams: '127.17.0.1#5335'
    # Volumes store your data between container upgrades
    volumes:
      # For persisting Pi-hole's databases and common configuration file
      - './etc-pihole:/etc/pihole'
      # Uncomment the below if you have custom dnsmasq config files that you want to persist. Not needed for most starting fresh with Pi-hole v6. If you're upgrading from v5 you and have used this directory before, you should keep it enabled for the first v6 container start to allow for a complete migration. It can be removed afterwards. Needs environment variable FTLCONF_misc_etc_dnsmasq_d: 'true'
      #- './etc-dnsmasq.d:/etc/dnsmasq.d'
    cap_add:
      # See https://docs.pi-hole.net/docker/configuration/#note-on-capabilities
      # Required if you are using Pi-hole as your DHCP server, else not needed
      # - NET_ADMIN
      # Required if you are using Pi-hole as your NTP client to be able to set the host's system time
      # - SYS_TIME
      # Optional, if Pi-hole should get some more processing time
      - SYS_NICE
    restart: unless-stopped

I'm using systemd-resolved with the configuration file /etc/systemd/resolved.conf

#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it under the
#  terms of the GNU Lesser General Public License as published by the Free
#  Software Foundation; either version 2.1 of the License, or (at your option)
#  any later version.
#
# Entries in this file show the compile time defaults. Local configuration
# should be created by either modifying this file (or a copy of it placed in
# /etc/ if the original file is shipped in /usr/), or by creating "drop-ins" in
# the /etc/systemd/resolved.conf.d/ directory. The latter is generally
# recommended. Defaults can be restored by simply deleting the main
# configuration file and all drop-ins located in /etc/.
#
# Use 'systemd-analyze cat-config systemd/resolved.conf' to display the full config.
#
# See resolved.conf(5) for details.

[Resolve]
# Some examples of DNS servers which may be used for DNS= and FallbackDNS=:
# Cloudflare: 1.1.1.1#cloudflare-dns.com 1.0.0.1#cloudflare-dns.com 2606:4700:4700::1111#cloudflare-dns.com 2606:4700:4700::1001#cloudflare-dns.com
# Google:     8.8.8.8#dns.google 8.8.4.4#dns.google 2001:4860:4860::8888#dns.google 2001:4860:4860::8844#dns.google
# Quad9:      9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net
DNS=127.0.0.1
FallbackDNS=127.0.0.1:5335 1.1.1.1#cloudflare-dns.com 1.0.0.1#cloudflare-dns.com 2606:4700:4700::1111#cloudflare-dns.com 2606:4700:4700::1001#cloudflare-dns.com 9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net 8.8.8.8#dns.google 8.8.4.4#dns.google 2001:4860:4860::8888#dns.google 2001:4860:4860::8844#dns.google
#Domains=
#DNSSEC=no
#DNSOverTLS=no
#MulticastDNS=yes
#LLMNR=yes
#Cache=yes
#CacheFromLocalhost=no
DNSStubListener=no
#DNSStubListenerExtra=
#ReadEtcHosts=yes
#ResolveUnicastSingleLabel=no
#StaleRetentionSec=0

When I run

sudo docker compose down --volumes --remove-orphans && sudo rm -r "./etc-pihole/" && sudo docker compose up && sudo docker compose logs -f 

I get

[+] down 2/2
 ✔ Container pihole
 ✔ Network services_default Removed
[+] up 2/2
 ✔ Network services_default Created
 ✔ Container pihole
Attaching to pihole
pihole  |   [i] Setting up user & group for the pihole user
pihole  |   [i] PIHOLE_UID not set in environment, using default (1000)
pihole  |   [i] PIHOLE_GID not set in environment, using default (1000)
pihole  |
pihole  |   [i] Starting FTL configuration
pihole  |   [i] No DNS upstream set in environment or config file, defaulting to Google DNS
pihole  |   [i] Setting FTLCONF_webserver_api_password from file
pihole  |   [i] Assigning password defined by Environment Variable
pihole  |   [i] Starting crond for scheduled scripts. Randomizing times for gravity and update checker
pihole  |
pihole  |   [i] Ensuring logrotate script exists in /etc/pihole
pihole  |
pihole  |   [i] Gravity migration checks
pihole  |   [i] No adlist file found, creating one with a default blocklist
pihole  |   [i] /etc/pihole/gravity.db does not exist (Likely due to a fresh volume). This is a required file for Pi-hole to operate.
pihole  |   [i] Gravity will now be run to create the database
pihole  |   [✗] DNS resolution is currently unavailable

I tried this with the sample Docker compose file given at https://docs.pi-hole.net/docker/ and the same error appeared.

Attempts at debugging

I tried the solutions posted in [SOLVED] DNS resolution is currently unavailable - #3 by SinE80 but none seem to work, and return the same error as above.

I also try following Gravity Update: DNS resolution is currently unavailable - #10 by Bucking_Horn :

  • When I run sudo docker exec -it pihole pihole -g, I get
  [✓] DNS resolution is available

  [✗] Migrating the list's cache directory to new location
Error: in prepare, no such table: info
  [i] Neutrino emissions detected...

  [✓] Preparing new gravity database
  [i] Creating new gravity databases...
  [✗] Unable to copy data from /etc/pihole/gravity.db to /etc/pihole/gravity.db_temp
  Parse error near line 11: no such table: OLD.group
Parse error near line 13: no such table: OLD.domainlist
Parse error near line 14: no such table: OLD.domainlist_by_group
Parse error near line 15: no such table: OLD.domainlist_by_group
Parse error near line 17: no such table: OLD.adlist
Parse error near line 18: no such table: OLD.adlist_by_group
Parse error near line 19: no such table: OLD.adlist_by_group
Parse error near line 21: no such table: OLD.client
Parse error near line 22: no such table: OLD.client_by_group
Parse error near line 23: no such table: OLD.client_by_group
   [✗] Unable to create gravity database. Please try again later. If the problem persists, please contact support.

Similarly,

grassglass@sh-touchsmart:/srv/services$ dig raw.githubusercontent.com


; <<>> DiG 9.20.21-1~deb13u1-Debian <<>> raw.githubusercontent.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20445
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;raw.githubusercontent.com.     IN      A

;; ANSWER SECTION:
raw.githubusercontent.com. 2328 IN      A       185.199.108.133
raw.githubusercontent.com. 2328 IN      A       185.199.109.133
raw.githubusercontent.com. 2328 IN      A       185.199.111.133
raw.githubusercontent.com. 2328 IN      A       185.199.110.133

;; Query time: 4 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Sat May 02 13:52:18 +08 2026
;; MSG SIZE  rcvd: 118

grassglass@sh-touchsmart:/srv/services$ nslookup raw.githubusercontent.com 8.8.8.8

Server:         8.8.8.8
Address:        8.8.8.8#53
Non-authoritative answer:
Name:   raw.githubusercontent.com
Address: 185.199.111.133
Name:   raw.githubusercontent.com
Address: 185.199.108.133
Name:   raw.githubusercontent.com
Address: 185.199.109.133
Name:   raw.githubusercontent.com
Address: 185.199.110.133

grassglass@sh-touchsmart:/srv/services$ at /etc/resolv.conf

# This is /run/systemd/resolve/resolv.conf managed by man:systemd-resolved(8).
# Do not edit.
#
# This file might be symlinked as /etc/resolv.conf. If you're looking at
# /etc/resolv.conf and seeing this text, you have followed the symlink.
#
# This is a dynamic resolv.conf file for connecting local clients directly to
# all known uplink DNS servers. This file lists all configured search domains.
#
# Third party programs should typically not access this file directly, but only
# through the symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a
# different way, replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.

nameserver 127.0.0.1
search .

Weird observation: I went to have lunch and I could magically reach the pihole WebGUI again, though there was error (-2) on the top right. But when I did sudo docker compose down --volumes --remove-orphans && sudo rm -r "./etc-pihole/" && sudo docker compose up && sudo docker compose logs -f , it broke again.

Update

Ok so this is baffling [✗] DNS resolution is currently unavailable lasts for some time. But then it becomes resolved, albeit with the constant error message Cannot read gravity database at /etc/pihole/gravity.db - file does not exist or is not readable.

Debug Token:

https://tricorder.pi-hole.net/lBmBwlu3/

This "solution" is telling to use 127.0.0.1 as DNS server, but this won't work.

Change the DNS server to 8.8.8.8 or any other public DNS server and try again.


The other issue is: your gravity database is completely empty (zero bytes):

*** [ DIAGNOSING ]: Gravity Database
-rw-r--r-- 1 root root 0 May  2 13:45 /etc/pihole/gravity.db

Try to recreate the database running this command:

sudo pihole -g -r recreate

Why did you remove all files from your bind mount? If you do this you will loose all settings when the new container is started.

I did sudo rm -r "./etc-pihole/" in an attempt to make a clean slate for which debugging might be easier.

Ok I'm now using DNS=8.8.8.8 in my resolved.conf file and I just ran sudo systemctl restart systemd-resolved.

OH it works! Hm interesting. May I ask if it is possible to use set up systemd-resolved (via resolved.conf) such that my Pi-hole host (homeserver) uses Pi-hole? And if Pi-hole is down, it falls back to other DNS resolvers. I thought that DNS=127.0.0.1 would work with FTLCONF_dns_upstreams: '127.17.0.1#5335' because it would route systemd-resolved -> 127.17.0.1 (Pi-hole) -> 127.17.0.1#5335 (unbound) but that doesn't seem like the case.

But, I guess I don't actually need Pi-hole filtering for my homeserver since it isn't what I browse actual webcontent on. Still, I'm curious.

Hm it seems that uncommenting FTLCONF_dns_upstreams: '127.17.0.1#5335' leads to errors:

pihole  | 2026-05-02 16:47:57.460 +08 [54/T59] ERROR: Cannot receive UDP DNS reply: Timeout - no response from upstream DNS server
pihole  | 2026-05-02 16:47:59.476 +08 [54/T59] ERROR: Cannot receive UDP DNS reply: Timeout - no response from upstream DNS server

What is the correct way do make pihole use unbound through the CLI? For clarity's sake, we note that unbound is working, since

$ dig dnssec.works @127.0.0.1 -p 5335

; <<>> DiG 9.20.21-1~deb13u1-Debian <<>> dnssec.works @127.0.0.1 -p 5335
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51463
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;dnssec.works.                  IN      A

;; ANSWER SECTION:
dnssec.works.           3525    IN      A       46.23.92.212

;; Query time: 0 msec
;; SERVER: 127.0.0.1#5335(127.0.0.1) (UDP)
;; WHEN: Sat May 02 16:48:41 +08 2026
;; MSG SIZE  rcvd: 57

Hm even if I do it the GUI way, as in the docs, it doesn't work.

That 127.17.0.1 is a loopback address, pointing back to the machine it runs on.
In case of a dockered Pi-hole, that's the Pi-hole container itself, where nothing is listening on port 5335.

Are you running your unbound bare metal or in Docker as well?

My unbound is ran bare-metal

Then you'd need to use the host machine's private range IPv4 as Pi-hole's upstream, and you'd also need to configure unbound to accept traffic from your Pi-hole's IP, see also Pi-Hole running in Docker doesn't seem to cooperate with Unbound - #9 by Bucking_Horn.

use the host machine's private range IPv4 as Pi-hole's upstream

Ok I now have FTLCONF_dns_upstreams: '192.168.x.y#5335' in my docker-compose.yml. (I also tried 127.0.0.1#5335)

configure unbound to accept traffic from your Pi-hole's IP

As per your link, I inserted

    interface: 192.168.x.y
    access-control: 172.18.0.0/16 allow

into /etc/unbound/unbound.conf.d/pi-hole.conf, because

$ ip -br -4 address

lo UNKNOWN 127.0.0.1/8
enp7s0 UP 192.168.x.y/24
docker0 DOWN 172.17.0.1/16
br-f95585440021 UP 172.18.0.1/16

But unbound still refuses to work with Pi-hole:

pihole  | 2026-05-02 22:43:27.060 +08 [53/T58] ERROR: Cannot receive UDP DNS reply: Timeout - no response from upstream DNS server
pihole  | 2026-05-02 22:43:27.060 +08 [53/T58] INFO: Tried to resolve PTR "4.4.8.8.in-addr.arpa" on 127.0.0.1#53 (UDP)
pihole  | 2026-05-02 22:43:29.076 +08 [53/T58] ERROR: Cannot receive UDP DNS reply: Timeout - no response from upstream DNS server
pihole  | 2026-05-02 22:43:29.076 +08 [53/T58] INFO: Tried to resolve PTR "8.8.8.8.in-addr.arpa" on 127.0.0.1#53 (UDP)

Do you have any advice?

How are you restarting the container? What files do you have in ./etc-pihole that could be kept between container restarts?

The log shows it's still trying localhost so your configuration changes are not being seen.

Can you show the output from
docker container exec pihole "/bin/bash/env" to show what the running environment is populated with.

Let's break the answer in smaller parts:

No.
With your current settings, if you use 127.0.0.1 as host DNS server, your machine won't have a DNS server when Pi-hole is offline. Also, there is no way to set a "fallback" like you want. If you add another server, both will be used even when Pi-hole is online.

Exactly. You don't need that.

They are completely different IPs.
The first one is used on the host, used by systemd-resolved. In this case you are using the loopback address.
The second one will be used by Pi-hole (inside the container) and it shouldn't be a loopback address.

I'm sure you are using the wrong IP in FTLCONF_dns_upstreams.
Are you sure the IP doesn't start with 172, instead of 127?

Where did you find this IP?


Note:
If you are running Unbound as a container, its IP will be something like 172.17.0.2 or 172.18.0.2. This IP is created by docker.

You should try to use this IP (or the host IP) as Pi-hole upstream server, but at the moment I suggest you to use FTLCONF_dns_upstreams=8.8.8.8 and make sure Pi-hole is working as expected, without Unbound.

If everything is working, then you can use Unbound IP.


If you made changes to your settings, please post the current compose file and a new debug log.

Please, also answer the questions asked by the other team members.

I'm restarting the container with

sudo docker compose down && sudo docker compose up -d

The output of docker container exec pihole "/bin/bash/env" is

OCI runtime exec failed: exec failed: unable to start container process: exec: "/bin/bash/env": stat /bin/bash/env: not a directory: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type

But docker container exec pihole tree "/bin/" returns

/bin/
├── arch -> /bin/busybox
├── ash -> /bin/busybox
├── base64 -> coreutils
├── bash
├── bbconfig -> /bin/busybox
├── busybox
├── cat -> coreutils
├── chattr -> /bin/busybox
├── chgrp -> coreutils
├── chmod -> coreutils
├── chown -> coreutils
├── coreutils
├── cp -> coreutils
├── date -> coreutils
├── dd -> coreutils
├── df -> coreutils
├── dmesg -> /bin/busybox
├── dnsdomainname -> /bin/busybox
├── dumpkmap -> /bin/busybox
├── echo -> coreutils
├── egrep
├── false -> coreutils
├── fatattr -> /bin/busybox
├── fdflush -> /bin/busybox
├── fgrep
├── fsync -> /bin/busybox
├── getopt -> /bin/busybox
├── grep
├── gunzip -> /bin/busybox
├── gzip -> /bin/busybox
├── hostname -> /bin/busybox
├── hugetop
├── ionice -> /bin/busybox
├── iostat -> /bin/busybox
├── ipcalc -> /bin/busybox
├── kbd_mode -> /bin/busybox
├── kill -> /bin/busybox
├── link -> coreutils
├── linux32 -> /bin/busybox
├── linux64 -> /bin/busybox
├── ln -> coreutils
├── login -> /bin/busybox
├── ls -> coreutils
├── lsattr -> /bin/busybox
├── lzop -> /bin/busybox
├── makemime -> /bin/busybox
├── mkdir -> coreutils
├── mknod -> coreutils
├── mktemp -> coreutils
├── more -> /bin/busybox
├── mount -> /bin/busybox
├── mountpoint -> /bin/busybox
├── mpstat -> /bin/busybox
├── mv -> coreutils
├── netstat -> /bin/busybox
├── nice -> coreutils
├── pidof
├── pidwait
├── ping -> /bin/busybox
├── ping6 -> /bin/busybox
├── pipe_progress -> /bin/busybox
├── printenv -> coreutils
├── ps
├── pwd -> coreutils
├── reformime -> /bin/busybox
├── rev -> /bin/busybox
├── rm -> coreutils
├── rmdir -> coreutils
├── run-parts -> /bin/busybox
├── sed -> /bin/busybox
├── setpriv -> /bin/busybox
├── setserial -> /bin/busybox
├── sh -> /bin/busybox
├── slabtop
├── sleep -> coreutils
├── stat -> coreutils
├── stty -> coreutils
├── su -> /bin/busybox
├── sync -> coreutils
├── tar -> /bin/busybox
├── tload
├── touch -> coreutils
├── true -> coreutils
├── umount -> /bin/busybox
├── uname -> coreutils
├── usleep -> /bin/busybox
├── vmstat
├── w
├── watch
└── zcat -> /bin/busybox

0 directories, 90 files

Ok let me add something. I don't think this is impactful but now I use dnsdist, instead of systemd-resolved (which has been apt removed'd from my system), with the /etc/dnsdist/dnsdist.yml config file being

# /etc/dnsdist/dnsdist.yml
general:
  # server_id: "sh-touchsmart-dnsdist"

console:
  listen_address: "127.0.0.1"
  key: "iRctSXUrETh/hjG+zb52NZB77GkGLjm3u0L0Zj6TPs0="

binds:
  - listen_address: "127.0.0.1:53"
    protocol: Do53

backends:
  - address: "127.0.0.1:5353"
    name: "pihole"
    protocol: Do53
    order: 1
    health_checks:
      mode: auto
      interval: 2
      timeout: 1000
      max_failures: 5
      rise: 2

  - address: "127.0.0.1:5335"
    name: "unbound"
    protocol: Do53
    order: 2
    health_checks:
      mode: auto
      interval: 2
      timeout: 1000
      max_failures: 5
      rise: 2

  - address: "1.1.1.2"
    name: "cloudflare-primary"
    protocol: Do53
    order: 3
    health_checks:
      mode: auto
      interval: 5
      timeout: 1000
      max_failures: 5
      rise: 2
  - address: "1.0.0.2"
    name: "cloudflare-secondary"
    protocol: Do53
    order: 4
    health_checks:
      mode: auto
      interval: 5
      timeout: 1000
      max_failures: 5
      rise: 2

  - address: "9.9.9.9"
    name: "quad9-primary"
    protocol: Do53
    order: 5
    health_checks:
      mode: auto
      interval: 5
      timeout: 1000
      max_failures: 5
      rise: 2
  - address: "149.112.112.11"
    name: "quad9-secondary"
    protocol: Do53
    order: 6
    health_checks:
      mode: auto
      interval: 5
      timeout: 1000
      max_failures: 5
      rise: 2

  - address: "8.8.8.8"
    name: "google-primary"
    protocol: Do53
    order: 7
    health_checks:
      mode: auto
      interval: 5
      timeout: 1000
      max_failures: 5
      rise: 2
  - address: "8.8.4.4"
    name: "google-secondary"
    protocol: Do53
    order: 8
    health_checks:
      mode: auto
      interval: 5
      timeout: 1000
      max_failures: 5
      rise: 2

load_balancing_policies:
  default_policy: firstAvailable
  servfail_on_no_server: false

Since dnsdist uses port 53, I simply changed docker-compose.yml to use

    ports:
      # DNS Ports
      - "5353:53/tcp"
      - "5353:53/udp"

I don't notice any change from before: Pi-hole still runs a-ok without FTLCONF_dns_upstreams being set to unbound.

Try just the env command bare:

docker container exec pihole env

The command sudo docker container exec pihole env returns

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=b1ef33baad7c
TZ=Asia/Singapore
WEBPASSWORD_FILE=pihole_password
FTLCONF_dns_listeningMode=ALL
FTLCONF_dns_upstreams=192.168.1.74#5335
DNSMASQ_USER=pihole
FTL_CMD=no-daemon
HOME=/root

You should try to use this IP (or the host IP) as Pi-hole upstream server, but at the moment I suggest you to use FTLCONF_dns_upstreams=8.8.8.8 and make sure Pi-hole is working as expected, without Unbound.

Yes Pi-hole works without issues when I comment FTLCONF_dns_upstreams: '127.17.0.1#5335'.

Ok I thought it works but, upon further experimentation, it appears it doesn't. Hm the problem seems to be with the ports --- dig dns.works @192.168.1.74 -p 5353 works but dig dns.works @192.168.1.74 doesn't. Is it not possible to put Pi-hole on a port that isn't 53? I thought dnsdist would forward the query to Pi-hole, making it go something like Pi-hole client -> dnsdist -> pihole.

Ok It works now after changing dnsdist.yml and ufw.

As aforementioned, I'm running Unbound bare-metal instead of on Docker. I got its IP by following the docs (which also runs Unbound bare-metal), which says

Finally, configure Pi-hole to use your recursive DNS server by specifying 127.0.0.1#5335 in the Settings > DNS > Custom DNS servers section and ensuring that all the other upstream servers are unticked, as shown below:

New compose file and debug log

When using FTLCONF_dns_upstreams: '192.168.1.74#5335':
Debug log: https://tricorder.pi-hole.net/rCxF8ipO/
Compose file:

# More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/
secrets:
  pihole_password:
    file: "./pihole_password"
services:
  pihole:
    secrets:
      - pihole_password
    container_name: pihole
    image: pihole/pihole:latest
    ports:
      # DNS Ports
      - "5353:53/tcp"
      - "5353:53/udp"
      # Default HTTP Port
      - "80:80/tcp"
      # Default HTTPs Port. FTL will generate a self-signed certificate
      - "443:443/tcp"
      # Uncomment the below if using Pi-hole as your DHCP Server
      #- "67:67/udp"
      # Uncomment the line below if you are using Pi-hole as your NTP server
      #- "123:123/udp"
    environment:
      # Set the appropriate timezone for your location from
      # https://en.wikipedia.org/wiki/List_of_tz_database_time_zones, e.g:
      TZ: 'Asia/Singapore'
      # Set a password to access the web interface. Not setting one will result in a random password being assigned
      WEBPASSWORD_FILE: pihole_password
      # If using Docker's default `bridge` network setting the dns listening mode should be set to 'ALL'
      FTLCONF_dns_listeningMode: 'ALL'
      FTLCONF_dns_upstreams: '127.0.0.1#5335'
    # Volumes store your data between container upgrades
    volumes:
      # For persisting Pi-hole's databases and common configuration file
      - './etc-pihole:/etc/pihole'
      # Uncomment the below if you have custom dnsmasq config files that you want to persist. Not needed for most starting fresh with Pi-hole v6. If you're upgrading from v5 you and have used this directory before, you should keep it enabled for the first v6 container start to allow for a complete migration. It can be removed afterwards. Needs environment variable FTLCONF_misc_etc_dnsmasq_d: 'true'
      #- './etc-dnsmasq.d:/etc/dnsmasq.d'
    cap_add:
      # See https://docs.pi-hole.net/docker/configuration/#note-on-capabilities
      # Required if you are using Pi-hole as your DHCP server, else not needed
      # - NET_ADMIN
      # Required if you are using Pi-hole as your NTP client to be able to set the host's system time
      # - SYS_TIME
      # Optional, if Pi-hole should get some more processing time
      - SYS_NICE
    restart: unless-stopped

As already said by Bucking_Horn, this won't work.

This is setting the container itself (not the host) as Pi-hole upstream server, but you want to use Unbound.

Since you are running Unbound bare-metal, you need to use the host IP (FTLCONF_dns_upstreams: '192.168.1.74#5335').

Note:
The documentation was written to use both Pi-hole and Unbound bare-metal. You need to adapt some things when using docker containers.

Yes, as per my reply to Bucking_Horn, I tried using FTLCONF_dns_upstreams: '192.168.1.74#5335', but it still doesn't run. Here is the debug token for it: https://tricorder.pi-hole.net/XRhthGnC/.

Updates

Now I'm using the docker-compose.yml file

# More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/
secrets:
  pihole_password:
    file: "./pihole_password"

services:
  pihole:
    secrets:
      - pihole_password
    container_name: pihole
    image: pihole/pihole:latest
    networks:
      - pihole_macvlan
    ports:
      # DNS Ports
      - "53:53/tcp"
      - "53:53/udp"
      # Default HTTP Port
      - "80:80/tcp"
      # Default HTTPs Port. FTL will generate a self-signed certificate
      - "443:443/tcp"
      # Uncomment the below if using Pi-hole as your DHCP Server
      #- "67:67/udp"
      # Uncomment the line below if you are using Pi-hole as your NTP server
      #- "123:123/udp"
    environment:
      # Set the appropriate timezone for your location from
      # https://en.wikipedia.org/wiki/List_of_tz_database_time_zones, e.g:
      TZ: 'Asia/Singapore'
      # Set a password to access the web interface. Not setting one will result in a random password being assigned
      WEBPASSWORD_FILE: pihole_password
      # If using Docker's default `bridge` network setting the dns listening mode should be set to 'ALL'
      FTLCONF_dns_listeningMode: 'ALL'
      #FTLCONF_dns_upstreams: '192.168.1.74#5335'
      # # Overwrite the query source when client information is provided through EDNS0 client subnet (ECS)
      # FTLCONF_dns_EDNS0ECS: true
    # Volumes store your data between container upgrades
    volumes:
      # For persisting Pi-hole's databases and common configuration file
      - './etc-pihole:/etc/pihole'
      # Uncomment the below if you have custom dnsmasq config files that you want to persist. Not needed for most starting fresh with Pi-hole v6. If you're upgrading from v5 you and have used this directory before, you should keep it enabled for the first v6 container start to allow for a complete migration. It can be removed afterwards. Needs environment variable FTLCONF_misc_etc_dnsmasq_d: 'true'
      #- './etc-dnsmasq.d:/etc/dnsmasq.d'
    cap_add:
      # See https://docs.pi-hole.net/docker/configuration/#note-on-capabilities
      # Required if you are using Pi-hole as your DHCP server, else not needed
      # - NET_ADMIN
      # Required if you are using Pi-hole as your NTP client to be able to set the host's system time
      # - SYS_TIME
      # Optional, if Pi-hole should get some more processing time
      - SYS_NICE
    restart: unless-stopped

networks:
  # Source: https://tonylawrence.com/posts/unix/synology/free-your-synology-ports/
  pihole_macvlan:                         # Reference to the network used in docker compose files
    name: pihole_macvlan                  # A user visible name of the network
    driver: macvlan                       # Use the macvlan network driver
    driver_opts:
      parent: enp7s0                      # If open vSwitch is enabled use ovs_eth0 (or ovs_eth1 etc.)
    ipam:
      config:
        - gateway: 192.168.1.1          # Gateway address
          ip_range: 192.168.1.75/32     # ip for pihole container
          subnet: 192.168.1.0/24        # Specify subnet

/etc/dnsdist/dnsdist.yml file

# /etc/dnsdist/dnsdist.yml
general:
  # server_id: "sh-touchsmart-dnsdist"

console:
  listen_address: "127.0.0.1"
  key: "iRctSXUrETh/hjG+zb52NZB77GkGLjm3u0L0Zj6TPs0="

binds:
  - listen_address: "127.0.0.1:53"
    protocol: Do53

backends:
  - address: "192.168.1.75"
    name: "pihole"
    # use_client_subnet: true
    protocol: Do53
    order: 1
    health_checks:
      mode: auto
      interval: 2
      timeout: 1000
      max_failures: 5
      rise: 2

  - address: "127.0.0.1:5335"
    name: "unbound"
    protocol: Do53
    order: 2
    health_checks:
      mode: auto
      interval: 2
      timeout: 1000
      max_failures: 5
      rise: 2

  - address: "1.1.1.2"
    name: "cloudflare-primary"
    protocol: Do53
    order: 3
    health_checks:
      mode: auto
      interval: 5
      timeout: 1000
      max_failures: 5
      rise: 2
  - address: "1.0.0.2"
    name: "cloudflare-secondary"
    protocol: Do53
    order: 4
    health_checks:
      mode: auto
      interval: 5
      timeout: 1000
      max_failures: 5
      rise: 2

  - address: "9.9.9.9"
    name: "quad9-primary"
    protocol: Do53
    order: 5
    health_checks:
      mode: auto
      interval: 5
      timeout: 1000
      max_failures: 5
      rise: 2
  - address: "149.112.112.11"
    name: "quad9-secondary"
    protocol: Do53
    order: 6
    health_checks:
      mode: auto
      interval: 5
      timeout: 1000
      max_failures: 5
      rise: 2

  - address: "8.8.8.8"
    name: "google-primary"
    protocol: Do53
    order: 7
    health_checks:
      mode: auto
      interval: 5
      timeout: 1000
      max_failures: 5
      rise: 2
  - address: "8.8.4.4"
    name: "google-secondary"
    protocol: Do53
    order: 8
    health_checks:
      mode: auto
      interval: 5
      timeout: 1000
      max_failures: 5
      rise: 2

load_balancing_policies:
  default_policy: firstAvailable
  servfail_on_no_server: false

and /etc/network/interfaces

# /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto enp7s0
iface enp7s0 inet static
    address 192.168.1.74/24
    gateway 192.168.1.1

# macvlan network interface for Pi-hole
auto macvlan0
iface macvlan0 inet manual
    pre-up ip link add macvlan0 link enp7s0 type macvlan mode bridge
    pre-up ip addr add 192.168.1.76/32 dev macvlan0
    up ip link set macvlan0 up
    post-up ip route add 192.168.1.75/32 dev macvlan0

But this wasn't to solve my Pi-hole Unbound issue; it still persists: https://tricorder.pi-hole.net/2ytfMOE7/.

Hmm sudo docker compose logs shows

INFO: Tried to resolve PTR "8.8.8.8.in-addr.arpa" on 127.0.0.1#53 (UDP)

Could this mean that FTLCONF_dns_upstreams: '192.168.1.74#5335' is not applying?

Note

I will be away from home and ununable to access my homeserver for the next 5 days (I wanted to setup a VPN but ran out of time in this weekend). So, apologies if I can't respond to you immediately.

Idea

Could it be that I need to open my firewall on port 5335 (where unbound listens) for Pi-hole to be able to access it? I'll test this conjecture out when I get back :+1:

Are you using DNSDist as well? Where is the dnsdist.yml file?

You've commented that line out in your provided docker compose file:
#FTLCONF_dns_upstreams: '192.168.1.74#5335'

You've created a massively complex system that is going to be nearly impossible to troubleshoot. My suggestion is to start by removing everything in the /etc-pihole/ directory and start with just the Pi-hole container. No unbound, no dnsdist. Once that is working with a remote upstream like 8.8.8.8 then add back unbound. Once that is working then play with dnsdist on the front end.

Ok yeah I figured it out:

  1. Use FTLCONF_dns_upstreams: '192.168.1.76#5335' in the docker-compose.yml file.
  2. Add interface: 192.168.1.76 (and access-control: 192.168.1.75/32 allow) in Unbound's pi-hole.conf.
  3. sudo ufw allow from 192.168.1.75 to any port 5335
    This is given that
# macvlan network interface for Pi-hole
auto macvlan0
iface macvlan0 inet manual

    pre-up ip link add macvlan0 link <physical interface> type macvlan mode bridge
    pre-up ip addr add 192.168.1.76/32 dev macvlan0
    up ip link set macvlan0 up
    ost-up ip route add 192.168.1.75/32 dev macvlan0

But I'll probably be scraping this setup :moai: