Hi.
I’m currently facing challenges with deploying a second Pi-hole instance within my Docker Swarm environment. This Pi-hole is intended to serve as a backup to a physical Pi-hole already in operation. My goal is to have this backup Pi-hole accessible with a fixed IP address on my LAN and also be reachable via Tailscale. However, despite multiple attempts, I’m encountering persistent issues, particularly with IP assignment via Macvlan and proper integration with Tailscale.
Setup Overview:
- Environment: Docker Swarm running on a cluster of Raspberry Pi nodes (network-booted), managed via Portainer. I have both Raspberry Pi nodes and AMD64 nodes in my Swarm, but I want the Pi-hole to be deployed only on the Raspberry Pi nodes (all of them use eth0 as network).
- Networking: I’m using a Macvlan network to assign a fixed IP within my LAN. The goal is for this service to be consistent and accessible both locally and also via Tailscale.
Docker Compose File: Here’s the current version of my Docker Compose file (Portainer stack)
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
ports:
- "53:53/tcp"
- "53:53/udp"
- "8089:80/tcp"
- "8443:443/tcp"
environment:
TZ: "Europe/Zurich"
WEBPASSWORD: "********"
DNSMASQ_LISTENING: "all"
DNSMASQ_USER: "root"
PIHOLE_UID: "1000"
PIHOLE_GID: "1000"
WEB_UID: "1001"
WEB_GID: "1001"
volumes:
- "/volumesOMV/pi_hole/etc-pihole:/etc/pihole"
- "/volumesOMV/pi_hole/etc-dnsmasq.d:/etc/dnsmasq.d"
restart: unless-stopped
networks:
mvlan_live_piCluster04:
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.labels.eth0netz == true
- node.hostname == piCluster04
#tailscale
tailscale_pihole:
image: tailscale/tailscale:latest
container_name: tailscale_pihole
privileged: true
hostname: dockerswarm_pihole
environment:
- TS_AUTH_KEY=tskey-client-*******
- TS_EXTRA_ARGS=--advertise-tags=tag:container
- TS_STATE_DIR=/var/lib/tailscale
volumes:
- /volumesOMV/pi_hole/tailscale:/var/lib/tailscale
- /dev/net/tun:/dev/net/tun
command: tailscaled --state=/var/lib/tailscale/tailscaled.state
network_mode: host
cap_add:
- net_admin
- sys_module
restart: unless-stopped
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.labels.eth0netz == true
- node.hostname == piCluster04
networks:
mvlan_live_piCluster04:
external: true
What I’ve Tried and Considered:
- Macvlan Configuration: I initially set up a Macvlan network and tried assigning a fixed IP via docker-compose. However, the container repeatedly received a different IP than specified.
- Router DHCP Config: I attempted to bypass Docker’s IP assignment by setting a static IP in the router based on the container’s MAC address, but this also failed to assign the correct IP.
- Single IP Range: I managed to get the container to receive the correct IP address by configuring the Macvlan network with a subnet mask of
/32
, effectively limiting the network to a single IP address (192.168.1.254
). However, this is a workaround, and the problem persists when I try to use a broader range (e.g.,/29
). - Tailscale Integration: The Tailscale setup doesn’t always register automatically. Even when it does, I cannot access the Pi-hole web interface through the Tailnet IP (neither on port 80 nor 8089).
pi-hole-logs from Docker
s6-rc: info: service s6rc-oneshot-runner: starting
s6-rc: info: service s6rc-oneshot-runner successfully started
s6-rc: info: service fix-attrs: starting
s6-rc: info: service fix-attrs successfully started
s6-rc: info: service legacy-cont-init: starting
s6-rc: info: service legacy-cont-init successfully started
s6-rc: info: service cron: starting
s6-rc: info: service cron successfully started
s6-rc: info: service _uid-gid-changer: starting
[i] Changing ID for user: www-data (33 => 1001)
[i] Changing ID for group: www-data (33 => 1001)
[i] Changing ID for user: pihole (999 => 1000)
s6-rc: info: service _uid-gid-changer successfully started
s6-rc: info: service _startup: starting
[i] Starting docker specific checks & setup for docker pihole/pihole
[i] Setting capabilities on pihole-FTL where possible
[i] Applying the following caps to pihole-FTL:
* CAP_CHOWN
* CAP_NET_BIND_SERVICE
* CAP_NET_RAW
[i] Ensuring basic configuration by re-running select functions from basic-install.sh
[i] Installing configs from /etc/.pihole...
[i] Existing dnsmasq.conf found... it is not a Pi-hole file, leaving alone!
[i] Installing /etc/dnsmasq.d/01-pihole.conf...
[✓] Installed /etc/dnsmasq.d/01-pihole.conf
[i] Installing /etc/.pihole/advanced/06-rfc6761.conf...
[✓] Installed /etc/dnsmasq.d/06-rfc6761.conf
[i] Installing latest logrotate script...
[i] Existing logrotate file found. No changes made.
[i] Assigning password defined by Environment Variable
[✓] New password set
[i] Added ENV to php:
"TZ" => "Europe/Zurich",
"PIHOLE_DOCKER_TAG" => "",
"PHP_ERROR_LOG" => "/var/log/lighttpd/error-pihole.log",
"CORS_HOSTS" => "",
"VIRTUAL_HOST" => "317f0dd26850",
[i] Using IPv4 and IPv6
[i] Installing latest Cron script...
[✓] Installing latest Cron script
[i] Preexisting ad list /etc/pihole/adlists.list detected (exiting setup_blocklists early)
[i] Existing DNS servers detected in setupVars.conf. Leaving them alone
[i] Applying pihole-FTL.conf setting LOCAL_IPV4=0.0.0.0
[i] FTL binding to default interface: eth0
[i] Enabling Query Logging
[i] Testing lighttpd config: Syntax OK
[i] All config checks passed, cleared for startup ...
[i] Docker start setup complete
[i] pihole-FTL (no-daemon) will be started as root
s6-rc: info: service _startup successfully started
s6-rc: info: service pihole-FTL: starting
s6-rc: info: service pihole-FTL successfully started
s6-rc: info: service lighttpd: starting
s6-rc: info: service lighttpd successfully started
s6-rc: info: service _postFTL: starting
s6-rc: info: service _postFTL successfully started
s6-rc: info: service legacy-services: starting
Checking if custom gravity.db is set in /etc/pihole/pihole-FTL.conf
s6-rc: info: service legacy-services successfully started
[✗] DNS resolution is currently unavailable
References and Tutorials Used:
- Tailscale Documentation: I followed Tailscale’s Docker guide for setting up Tailscale within Docker, ensuring proper authentication and tag management.
- Macvlan Configuration: I referenced several Docker and networking guides to ensure the Macvlan setup was correct, but the IP assignment remains inconsistent.
Current Status: Despite these efforts, the Pi-hole container either receives the wrong IP or experiences network conflicts that prevent it from functioning correctly. I’m reaching out for advice or suggestions from anyone who has successfully deployed a similar setup or encountered similar issues in docker swarm (as I’ve seen some people have working setups in stand-alone-docker-hosts).
Any help or insights would be greatly appreciated!