Hello,
Please be gentle, I’m new to Linux, Docker, Compose, YAMLs, macvlans (should be obvious since I’m new to Linux). About the only thing I have going for me is that I’m a seasoned sysadmin and network engineer. I am attempting a multi-pihole deployment on an RPi at my home to provide software redundancy. 2x Pihole + unbound and 2x pihole for a kid’s network that will be forced to OpenDNS. Because I’m going to have so many resolvers listening on Port 53, the only way I know to make this work is to use macvlan so they all get their own L2 virtual adapters.
I have my YAML composed and functioning (it validates, runs, etc). It appears to do what I need it to do, it created the macvlans with the appropriate network addresses/subnets and gateways. What I am having issues with is that pihole is saying it can’t resolve DNS and it is bootlooping. Ironically, the Plex server that I have running will remain running and is pingable from the other networks with access to that VLAN. I am unable to get a ping from the piholes, but I suspect that’s because it’s either disabled by default or it’s not booting far enough to allow an ICMP response. Below are the YAML as well as the startup info from docker logs and the docker inspect info on one of the piholes.
YAML (Note, most of the commented items were either in the examples from hub.docker or are items I’m hoping to get working once I can get the baseline stable):
version: "3"
services:
pihole_UF1:
container_name: pihole_UF1
image: cbcrowe/pihole-unbound:latest
hostname: piholeUF1
domainname: piholeUF1.local
# Expose:
# - "443"
# - "53"
# - "80"
# - "22" # Uncomment to enable SSH
environment:
#ServerIP: ${ServerIP}
TZ: 'America/Los_Angeles'
WEBPASSWORD: 'PASSWORD_REDACTED'
#REV_SERVER: ${REV_SERVER}
#REV_SERVER_TARGET: ${REV_SERVER_TARGET}
#REV_SERVER_DOMAIN: ${REV_SERVER_DOMAIN}
#REV_SERVER_CIDR: ${REV_SERVER_CIDR}
DNS1: 127.0.0.1#5335
DNS2: 127.0.0.1#5335
DNSSEC: "true" # Enable DNSSEC
# network_mode: "Bridge"
mac_address: 22:85:20:22:d3:da
networks:
pi_vlan:
ipv4_address: 10.10.90.2
DSN:
- 1.1.1.1
- 1.0.0.1
volumes:
- ./etc_pihole-unbound:/etc/pihole_UF1:rw
- ./etc_pihole_dnsmasq-unbound:/etc/dnsmasq.d_UF1:rw
restart: unless-stopped
pihole_UF2:
container_name: pihole_UF2
image: cbcrowe/pihole-unbound:latest
hostname: piholeUF2
domainname: piholeUF2.local
# Expose:
# - "443"
# - "53"
# - "80"
# - "22" # Uncomment to enable SSH
environment:
#ServerIP: ${ServerIP}
TZ: 'America/Los_Angeles'
WEBPASSWORD: 'PASSWORD_REDACTED'
#REV_SERVER: ${REV_SERVER}
#REV_SERVER_TARGET: ${REV_SERVER_TARGET}
#REV_SERVER_DOMAIN: ${REV_SERVER_DOMAIN}
#REV_SERVER_CIDR: ${REV_SERVER_CIDR}
DNS1: 127.0.0.1#5335 # Hardcoded to Local Unbound server
DNS2: 127.0.0.1#5335
DNSSEC: "true" # Enable DNSSEC
# network_mode: "Bridge"
mac_address: 5e:8d:8c:08:60:20
networks:
pi_vlan:
ipv4_address: 10.10.90.3
DSN:
- 1.1.1.1
- 1.0.0.1
volumes:
- ./etc_pihole-unbound:/etc/pihole_UF2:rw
- ./etc_pihole_dnsmasq-unbound:/etc/dnsmasq.d_UF2:rw
restart: unless-stopped
pihole_F1:
container_name: pihole_f1
image: pihole/pihole:latest
restart: unless-stopped
environment:
TZ: 'America/Los_Angeles'
WEBPASSWORD: 'PASSWORD_REDACTED'
# DNS1: 10.10.90.5
DNS1: 208.67.222.222
DNS2: 208.67.220.220
# Volumes store your data between container upgrades
DSN:
- 208.67.222.222
- 208.67.220.220
volumes:
- './etc-pihole-F1/:/etc/pihole_F1/'
- './etc-dnsmasqF1.d/:/etc/dnsmasq.d_F1/'
# Recommended but not required (DHCP needs NET_ADMIN)
# https ://github. com/pi-hole/docker-pi-hole#note-on-capabilities
#cap_add:
# - NET_ADMIN
mac_address: 6a:01:91:a1:96:33
networks:
pi_vlan:
# Define a static ip for the container. The containter can be accessible by others devices on the LAN network with this IP.
ipv4_address: 10.10.90.4
pihole_F2:
container_name: pihole_f2
image: pihole/pihole:latest
restart: unless-stopped
environment:
TZ: 'America/Los_Angeles'
WEBPASSWORD: 'PASSWORD_REDACTED'
# DNS1: 10.10.90.4
DNS1: 208.67.222.222
DNS2: 208.67.220.220
# Volumes store your data between container upgrades
DSN:
- 208.67.222.222
- 208.67.220.220
volumes:
- './etc-pihole-F1/:/etc/pihole_F2/'
- './etc-dnsmasqF2.d/:/etc/dnsmasq.d_F2/'
# Recommended but not required (DHCP needs NET_ADMIN)
# https ://github. com/pi-hole/docker-pi-hole#note-on-capabilities
#cap_add:
# - NET_ADMIN
mac_address: b6:fe:ec:49:ce:e6
networks:
pi_vlan:
# Define a static ip for the container. The containter can be accessible by others devices on the LAN network with this IP.
ipv4_address: 10.10.90.5
plex:
image: ghcr.io/linuxserver/plex
container_name: plex
# network_mode: "bridge"
environment:
- PUID=1000
- PGID=1000
- VERSION=docker
# - PLEX_CLAIM-
# DNS:
# - 10.10.90.2
# - 10.10.90.3
# - 1.1.1.1
# - 1.0.0.1
# Expose:
# - "32400"
# - "1900"
# - "5353"
# - "8324"
# - "32410"
# - "32412"
# - "32413"
# - "32414"
# - "32469"
volumes:
- /home/$USER/docker/plex:/home/pi/plex
- /mnt/media:/home/pi/plex/media
# volumes:
# NFSShare:
# driver: local
# driver_opts:
# type: nfs
# o: addr=10.10.50.2
# device: ":/PlexServer"
# Network: plex_vlan
mac_address: ca:e3:26:60:d2:06
networks:
plex_vlan:
# Define a static ip for the container. The containter can be accessible by others devices on the LAN network with this IP.
ipv4_address: 10.10.40.2
restart: always
networks:
pi_vlan:
driver: macvlan
driver_opts:
parent: eth0.90
ipam:
driver: default
config:
- subnet: 10.10.90.0/24
gateway: 10.10.90.1
plex_vlan:
driver: macvlan
driver_opts:
parent: eth0.40
ipam:
driver: default
config:
- subnet: 10.10.40.0/24
gateway: 10.10.40.1
Pihole Startup info:
root@raspberrypi:/home/pi# docker logs pihole_f1
[s6-init] making user provided files available at /var/run/s6/etc…exited 0.
[s6-init] ensuring user provided files have correct perms…exited 0.
[fix-attrs.d] applying ownership & permissions fixes…
[fix-attrs.d] 01-resolver-resolv: applying…
[fix-attrs.d] 01-resolver-resolv: exited 0.
[fix-attrs.d] done.
[cont-init.d] executing container initialization scripts…
[cont-init.d] 20-start.sh: executing…
::: Starting docker specific checks & setup for docker pihole/pihole
[i] Installing configs from /etc/.pihole…
[i] Existing dnsmasq.conf found… it is not a Pi-hole file, leaving alone!
[✓] Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf
Converting DNS1 to PIHOLE_DNS_
Converting DNS2 to PIHOLE_DNS_
Setting DNS servers based on PIHOLE_DNS_ variable
Setting password: ‘PASSWORD_REDACTED’
- pihole -a -p ‘PASSWORD_REDACTED’ ‘PASSWORD_REDACTED’
[✓] New password set
DNSMasq binding to default interface: eth0
Added ENV to php:
“PHP_ERROR_LOG” => “/var/log/lighttpd/error.log”,
“ServerIP” => “0.0.0.0”,
“VIRTUAL_HOST” => “0.0.0.0”,
Using IPv4 and IPv6
::: setup_blocklists now setting default blocklists up:
::: TIP: Use a docker volume for /etc/pihole/adlists.list if you want to customize for first boot
::: Blocklists (/etc/pihole/adlists.list) now set to:
https ://raw.githubusercontent. com/StevenBlack/hosts/master/hosts
::: Testing pihole-FTL DNS: FTL started!
::: Testing lighttpd config: Syntax OK
::: All config checks passed, cleared for startup …
::: Enabling Query Logging
[i] Enabling logging…
[✓] Logging has been enabled!
::: Docker start setup complete
[✗] DNS resolution is currently unavailable
Docker Inspect info on one of the Pihole instances:
root@raspberrypi:/home/pi# docker inspect pihole_f1
[
{
“Id”: “52289454bc468135092fec6573d316e2504a37f9b3ea81c00c34705effad8d93”,
“Created”: “2021-02-25T23:04:12.863818653Z”,
“Path”: “/s6-init”,
“Args”: ,
“State”: {
“Status”: “running”,
“Running”: true,
“Paused”: false,
“Restarting”: false,
“OOMKilled”: false,
“Dead”: false,
“Pid”: 7098,
“ExitCode”: 0,
“Error”: “”,
“StartedAt”: “2021-02-25T23:04:17.628603203Z”,
“FinishedAt”: “0001-01-01T00:00:00Z”,
“Health”: {
“Status”: “healthy”,
“FailingStreak”: 1,
“Log”: [
{
“Start”: “2021-02-25T15:04:47.628891081-08:00”,
“End”: “2021-02-25T15:04:47.92390568-08:00”,
“ExitCode”: 0,
“Output”: “\n; <<>> DiG 9.11.5-P4-5.1+deb10u2-Debian <<>> +norecurse +retry=0 @127.0.0.1 pi.hole\n; (1 server found)\n;; global options: +cmd\n;; Got answer:\n;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59415\n;; flags: qr aa ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1\n\n;; OPT PSEUDOSECTION:\n; EDNS: version: 0, flags:; udp: 4096\n;; QUESTION SECTION:\n;pi.hole.\t\t\tIN\tA\n\n;; ANSWER SECTION:\npi.hole.\t\t2\tIN\tA\t0.0.0.0\n\n;; Query time: 1 msec\n;; SERVER: 127.0.0.1#53(127.0.0.1)\n;; WHEN: Thu Feb 25 15:04:47 PST 2021\n;; MSG SIZE rcvd: 52\n\n”
},
{
“Start”: “2021-02-25T15:05:17.96837919-08:00”,
“End”: “2021-02-25T15:05:23.240918151-08:00”,
“ExitCode”: 1,
“Output”: “\n; <<>> DiG 9.11.5-P4-5.1+deb10u2-Debian <<>> +norecurse +retry=0 @127.0.0.1 pi.hole\n; (1 server found)\n;; global options: +cmd\n;; connection timed out; no servers could be reached\n”
}
]
}
},
“Image”: “sha256:1b529812cd4bbba0276755b589d4ddc8b1c0ff27e7ed6c502f9442ba8a4d1e7f”,
“ResolvConfPath”: “/var/lib/docker/containers/52289454bc468135092fec6573d316e2504a37f9b3ea81c00c34705effad8d93/resolv.conf”,
“HostnamePath”: “/var/lib/docker/containers/52289454bc468135092fec6573d316e2504a37f9b3ea81c00c34705effad8d93/hostname”,
“HostsPath”: “/var/lib/docker/containers/52289454bc468135092fec6573d316e2504a37f9b3ea81c00c34705effad8d93/hosts”,
“LogPath”: “/var/lib/docker/containers/52289454bc468135092fec6573d316e2504a37f9b3ea81c00c34705effad8d93/52289454bc468135092fec6573d316e2504a37f9b3ea81c00c34705effad8d93-json.log”,
“Name”: “/pihole_f1”,
“RestartCount”: 0,
“Driver”: “overlay2”,
“Platform”: “linux”,
“MountLabel”: “”,
“ProcessLabel”: “”,
“AppArmorProfile”: “”,
“ExecIDs”: null,
“HostConfig”: {
“Binds”: [
“/home/pi/etc-dnsmasqF1.d:/etc/dnsmasq.d_F1:rw”,
“/home/pi/etc-pihole-F1:/etc/pihole_F1:rw”
],
“ContainerIDFile”: “”,
“LogConfig”: {
“Type”: “json-file”,
“Config”: {}
},
“NetworkMode”: “pi_pi_vlan”,
“PortBindings”: {},
“RestartPolicy”: {
“Name”: “unless-stopped”,
“MaximumRetryCount”: 0
},
“AutoRemove”: false,
“VolumeDriver”: “”,
“VolumesFrom”: ,
“CapAdd”: null,
“CapDrop”: null,
“CgroupnsMode”: “host”,
“Dns”: null,
“DnsOptions”: null,
“DnsSearch”: null,
“ExtraHosts”: null,
“GroupAdd”: null,
“IpcMode”: “private”,
“Cgroup”: “”,
“Links”: null,
“OomScoreAdj”: 0,
“PidMode”: “”,
“Privileged”: false,
“PublishAllPorts”: false,
“ReadonlyRootfs”: false,
“SecurityOpt”: null,
“UTSMode”: “”,
“UsernsMode”: “”,
“ShmSize”: 67108864,
“Runtime”: “runc”,
“ConsoleSize”: [
0,
0
],
“Isolation”: “”,
“CpuShares”: 0,
“Memory”: 0,
“NanoCpus”: 0,
“CgroupParent”: “”,
“BlkioWeight”: 0,
“BlkioWeightDevice”: null,
“BlkioDeviceReadBps”: null,
“BlkioDeviceWriteBps”: null,
“BlkioDeviceReadIOps”: null,
“BlkioDeviceWriteIOps”: null,
“CpuPeriod”: 0,
“CpuQuota”: 0,
“CpuRealtimePeriod”: 0,
“CpuRealtimeRuntime”: 0,
“CpusetCpus”: “”,
“CpusetMems”: “”,
“Devices”: null,
“DeviceCgroupRules”: null,
“DeviceRequests”: null,
“KernelMemory”: 0,
“KernelMemoryTCP”: 0,
“MemoryReservation”: 0,
“MemorySwap”: 0,
“MemorySwappiness”: null,
“OomKillDisable”: null,
“PidsLimit”: null,
“Ulimits”: null,
“CpuCount”: 0,
“CpuPercent”: 0,
“IOMaximumIOps”: 0,
“IOMaximumBandwidth”: 0,
“MaskedPaths”: [
“/proc/asound”,
“/proc/acpi”,
“/proc/kcore”,
“/proc/keys”,
“/proc/latency_stats”,
“/proc/timer_list”,
“/proc/timer_stats”,
“/proc/sched_debug”,
“/proc/scsi”,
“/sys/firmware”
],
“ReadonlyPaths”: [
“/proc/bus”,
“/proc/fs”,
“/proc/irq”,
“/proc/sys”,
“/proc/sysrq-trigger”
]
},
“GraphDriver”: {
“Data”: {
“LowerDir”: “/var/lib/docker/overlay2/686bb2c9c8ebc9d3fdc384345d044613c453e43dd317dedd39a0043e2aa06d9a-init/diff:/var/lib/docker/overlay2/07b4d6fdbb12fbd19b30af544db06d36e546fc0b7326355cbaedbbc231ad46de/diff:/var/lib/docker/overlay2/38e1095bff5fb706967a95a13d31ed07febaf54c67d735dce1f9bcca4021b883/diff:/var/lib/docker/overlay2/a0dea51594e8720b2cedf024e58055a73998dd02cc3422b735b6a7667b72d4e7/diff:/var/lib/docker/overlay2/2d3fa216b981c3c5916976e88ca83c19a8854172e4f6f68691be398ce8d7f757/diff:/var/lib/docker/overlay2/b91207f2610ada3d098ee6acb45f919ba25d70d1e0ce4d1025bc123adb2c25c9/diff:/var/lib/docker/overlay2/0f9d30ba101f08ce1d903fdaf553e04652399d96e1ddb9fffe532723a3707b62/diff:/var/lib/docker/overlay2/ead6f5e915e2a96e79cdd14ffa9f23fffbabdedb79291e85f71232941504582e/diff:/var/lib/docker/overlay2/73ae8d34f168325f784350e21e2c450917b9bcf4e416d27d5ea3516986606027/diff”,
“MergedDir”: “/var/lib/docker/overlay2/686bb2c9c8ebc9d3fdc384345d044613c453e43dd317dedd39a0043e2aa06d9a/merged”,
“UpperDir”: “/var/lib/docker/overlay2/686bb2c9c8ebc9d3fdc384345d044613c453e43dd317dedd39a0043e2aa06d9a/diff”,
“WorkDir”: “/var/lib/docker/overlay2/686bb2c9c8ebc9d3fdc384345d044613c453e43dd317dedd39a0043e2aa06d9a/work”
},
“Name”: “overlay2”
},
“Mounts”: [
{
“Type”: “bind”,
“Source”: “/home/pi/etc-dnsmasqF1.d”,
“Destination”: “/etc/dnsmasq.d_F1”,
“Mode”: “rw”,
“RW”: true,
“Propagation”: “rprivate”
},
{
“Type”: “bind”,
“Source”: “/home/pi/etc-pihole-F1”,
“Destination”: “/etc/pihole_F1”,
“Mode”: “rw”,
“RW”: true,
“Propagation”: “rprivate”
}
],
“Config”: {
“Hostname”: “52289454bc46”,
“Domainname”: “”,
“User”: “”,
“AttachStdin”: false,
“AttachStdout”: false,
“AttachStderr”: false,
“ExposedPorts”: {
“443/tcp”: {},
“53/tcp”: {},
“53/udp”: {},
“67/udp”: {},
“80/tcp”: {}
},
“Tty”: false,
“OpenStdin”: false,
“StdinOnce”: false,
“Env”: [
“TZ=America/Los_Angeles”,
“WEBPASSWORD=PASSWORD_REDACTED”,
“DNS1=208.67.222.222”,
“DNS2=208.67.220.220”,
“PATH=/opt/pihole:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin”,
“ARCH=armv7l”,
“UBUNTU_SUITE=buster”,
“DOCKER_REPO=multiarch/debian-debootstrap”,
“PIHOLE_ARCH=arm”,
“S6OVERLAY_RELEASE=https ://github. com/just-containers/s6-overlay/releases/download/v2.1.0.2/s6-overlay-arm.tar.gz”,
“PIHOLE_INSTALL=/root/ph_install.sh”,
“PHP_ENV_CONFIG=/etc/lighttpd/conf-enabled/15-fastcgi-php.conf”,
“PHP_ERROR_LOG=/var/log/lighttpd/error.log”,
“IPv6=True”,
“S6_LOGGING=0”,
“S6_KEEP_ENV=1”,
“S6_BEHAVIOUR_IF_STAGE2_FAILS=2”,
“ServerIP=0.0.0.0”,
“FTL_CMD=no-daemon”,
“DNSMASQ_USER=root”,
“VERSION=v5.2.4”
],
“Cmd”: null,
“Healthcheck”: {
“Test”: [
“CMD-SHELL”,
“dig +norecurse +retry=0 @127.0.0.1 pi.hole || exit 1”
]
},
“Image”: “pihole/pihole:latest”,
“Volumes”: {
“/etc/dnsmasq.d_F1”: {},
“/etc/pihole_F1”: {}
},
“WorkingDir”: “”,
“Entrypoint”: [
“/s6-init”
],
“MacAddress”: “6a:01:91:a1:96:33”,
“OnBuild”: null,
“Labels”: {
“com.docker. compose.config-hash”: “80188d898751a9ea008c0066b22a9ed509014a192f258a586bc6a73a5069950b”,
“com.docker. compose.container-number”: “1”,
“com.docker. compose.oneoff”: “False”,
“com.docker. compose.project”: “pi”,
“com.docker. compose.project.config_files”: “docker-compose.yml”,
“com.docker. compose.project.working_dir”: “/home/pi”,
“com.docker .compose.service”: “pihole_F1”,
“com.docker. compose.version”: “1.28.2”,
“image”: “pihole/pihole:v5.2.4_arm”,
“maintainer”: “adam@diginc.us”,
“url”: “https ://www.github. com/pi-hole/docker-pi-hole”
}
},
“NetworkSettings”: {
“Bridge”: “”,
“SandboxID”: “767a9b70eade6e653a103a5fb474be4ec9c26c67a4b634935479ba829988730b”,
“HairpinMode”: false,
“LinkLocalIPv6Address”: “”,
“LinkLocalIPv6PrefixLen”: 0,
“Ports”: {},
“SandboxKey”: “/var/run/docker/netns/767a9b70eade”,
“SecondaryIPAddresses”: null,
“SecondaryIPv6Addresses”: null,
“EndpointID”: “”,
“Gateway”: “”,
“GlobalIPv6Address”: “”,
“GlobalIPv6PrefixLen”: 0,
“IPAddress”: “”,
“IPPrefixLen”: 0,
“IPv6Gateway”: “”,
“MacAddress”: “”,
“Networks”: {
“pi_pi_vlan”: {
“IPAMConfig”: {
“IPv4Address”: “10.10.90.4”
},
“Links”: null,
“Aliases”: [
“pihole_F1”,
“52289454bc46”
],
“NetworkID”: “30846189dd69b05091790d3e3edd1d50fdb6c65248796f494c30bcf21dbf991c”,
“EndpointID”: “9c15ab4efc9ffd95cdb9c48386c3f727ceff524e23685d494b9651fee337c9d4”,
“Gateway”: “10.10.90.1”,
“IPAddress”: “10.10.90.4”,
“IPPrefixLen”: 24,
“IPv6Gateway”: “”,
“GlobalIPv6Address”: “”,
“GlobalIPv6PrefixLen”: 0,
“MacAddress”: “6a:01:91:a1:96:33”,
“DriverOpts”: null
}
}
}
}
]
Sorry for the walls of text and thank you ahead of time for the help =)
NOTE: I had to add spaces before anything .com so that it didn’t think it was a URL as new users can only post 2 URLs.