$ -weight: 600;">sudo vi /etc/systemd/resolved.conf
-weight: 600;">sudo vi /etc/systemd/resolved.conf
-weight: 600;">sudo vi /etc/systemd/resolved.conf
DNSStubListener=no
DNSStubListener=no
DNSStubListener=no
-weight: 600;">sudo rm /etc/resolv.conf
-weight: 600;">sudo ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
-weight: 600;">sudo rm /etc/resolv.conf
-weight: 600;">sudo ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
-weight: 600;">sudo rm /etc/resolv.conf
-weight: 600;">sudo ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart systemd-resolved
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart systemd-resolved
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart systemd-resolved
-weight: 500;">docker run -d \ --name pihole \ -p 192.168.64.15:53:53/tcp \ -p 192.168.64.15:53:53/udp \ -p 127.0.0.1:800:80/tcp \ -e TZ=Europe/Budapest \ -e FTLCONF_webserver_api_password=<your_password> \ -e FTLCONF_dns_listeningMode=ALL \ -e FTLCONF_dns_upstreams="8.8.8.8;8.8.4.4" \ -v /home/pihole/etc-pihole:/etc/pihole \ --cap-add NET_BIND_SERVICE \ ---weight: 500;">restart unless-stopped \ pihole/pihole:latest
-weight: 500;">docker run -d \ --name pihole \ -p 192.168.64.15:53:53/tcp \ -p 192.168.64.15:53:53/udp \ -p 127.0.0.1:800:80/tcp \ -e TZ=Europe/Budapest \ -e FTLCONF_webserver_api_password=<your_password> \ -e FTLCONF_dns_listeningMode=ALL \ -e FTLCONF_dns_upstreams="8.8.8.8;8.8.4.4" \ -v /home/pihole/etc-pihole:/etc/pihole \ --cap-add NET_BIND_SERVICE \ ---weight: 500;">restart unless-stopped \ pihole/pihole:latest
-weight: 500;">docker run -d \ --name pihole \ -p 192.168.64.15:53:53/tcp \ -p 192.168.64.15:53:53/udp \ -p 127.0.0.1:800:80/tcp \ -e TZ=Europe/Budapest \ -e FTLCONF_webserver_api_password=<your_password> \ -e FTLCONF_dns_listeningMode=ALL \ -e FTLCONF_dns_upstreams="8.8.8.8;8.8.4.4" \ -v /home/pihole/etc-pihole:/etc/pihole \ --cap-add NET_BIND_SERVICE \ ---weight: 500;">restart unless-stopped \ pihole/pihole:latest
-weight: 500;">docker exec pihole pihole-FTL --config dns.hosts \ '["192.168.64.15 home.arcade-lab.io", "192.168.64.15 portainer.arcade-lab.io", "192.168.64.15 grafana.arcade-lab.io", "192.168.64.15 prometheus.arcade-lab.io", "192.168.64.15 transmission.arcade-lab.io", "192.168.64.15 filebrowser.arcade-lab.io", "192.168.64.15 jellyfin.arcade-lab.io", "192.168.64.15 pi-hole.arcade-lab.io"]'
-weight: 500;">docker exec pihole pihole-FTL --config dns.hosts \ '["192.168.64.15 home.arcade-lab.io", "192.168.64.15 portainer.arcade-lab.io", "192.168.64.15 grafana.arcade-lab.io", "192.168.64.15 prometheus.arcade-lab.io", "192.168.64.15 transmission.arcade-lab.io", "192.168.64.15 filebrowser.arcade-lab.io", "192.168.64.15 jellyfin.arcade-lab.io", "192.168.64.15 pi-hole.arcade-lab.io"]'
-weight: 500;">docker exec pihole pihole-FTL --config dns.hosts \ '["192.168.64.15 home.arcade-lab.io", "192.168.64.15 portainer.arcade-lab.io", "192.168.64.15 grafana.arcade-lab.io", "192.168.64.15 prometheus.arcade-lab.io", "192.168.64.15 transmission.arcade-lab.io", "192.168.64.15 filebrowser.arcade-lab.io", "192.168.64.15 jellyfin.arcade-lab.io", "192.168.64.15 pi-hole.arcade-lab.io"]'
pihole_local_dns_records: - domain: home.arcade-lab.io - domain: portainer.arcade-lab.io - domain: grafana.arcade-lab.io - domain: prometheus.arcade-lab.io - domain: transmission.arcade-lab.io - domain: filebrowser.arcade-lab.io - domain: jellyfin.arcade-lab.io - domain: pi-hole.arcade-lab.io
pihole_local_dns_records: - domain: home.arcade-lab.io - domain: portainer.arcade-lab.io - domain: grafana.arcade-lab.io - domain: prometheus.arcade-lab.io - domain: transmission.arcade-lab.io - domain: filebrowser.arcade-lab.io - domain: jellyfin.arcade-lab.io - domain: pi-hole.arcade-lab.io
pihole_local_dns_records: - domain: home.arcade-lab.io - domain: portainer.arcade-lab.io - domain: grafana.arcade-lab.io - domain: prometheus.arcade-lab.io - domain: transmission.arcade-lab.io - domain: filebrowser.arcade-lab.io - domain: jellyfin.arcade-lab.io - domain: pi-hole.arcade-lab.io - Edit the resolved configuration file: - Find the line #DNSStubListener=yes and change it to: - Replace /etc/resolv.conf with a symlink to the runtime version that uses your Netplan DNS settings: - Restart the -weight: 500;">service: - 192.168.64.15:53:53/tcp and 192.168.64.15:53:53/udp: DNS ports bound to the server's LAN IP. This is the key part — devices on the local network can point their DNS to 192.168.64.15 and Pi-hole will handle their queries. I deliberately did not bind to 0.0.0.0 to keep it as targeted as possible.
- 127.0.0.1:800:80/tcp: The Pi-hole web admin interface, bound to localhost only. This follows the same pattern I established in Part 4 — all web UIs are bound to 127.0.0.1 and proxied through Nginx with SSL. Port 800 is used because port 80 is already taken by Nginx itself. - FTLCONF_webserver_api_password: Sets the web admin password. Note that in v6, settings configured via environment variables become read-only — you can't change them from the web UI afterward.
- FTLCONF_dns_listeningMode: ALL: Required when running in Docker's default bridge network mode. Without this, Pi-hole would only listen for queries from the container's internal network.
- FTLCONF_dns_upstreams: The upstream DNS servers Pi-hole forwards queries to. I'm using Google's 8.8.8.8 and 8.8.4.4. - The /etc/pihole volume persists Pi-hole's databases and configuration across container recreations. This is important because Pi-hole stores its blocklists, query logs, and settings here.
- NET_BIND_SERVICE is the only capability needed — it allows the process to bind to port 53. Other capabilities like NET_ADMIN are only required if you're using Pi-hole as a DHCP server, which I'm not. - https://portainer.arcade-lab.io — Container management
- https://grafana.arcade-lab.io — Monitoring dashboards
- https://prometheus.arcade-lab.io — Metrics
- https://transmission.arcade-lab.io — BitTorrent client
- https://filebrowser.arcade-lab.io — File browser
- https://jellyfin.arcade-lab.io — Media streaming
- https://pi-hole.arcade-lab.io — Pi-hole admin itself - macOS: System Settings → Wi-Fi → Details → DNS → set 192.168.64.15
- iOS: Settings → Wi-Fi → (i) → Configure DNS → Manual → 192.168.64.15
- Linux: Edit your Netplan or /etc/resolv.conf to set nameserver 192.168.64.15
- Windows: Network adapter settings → IPv4 → Preferred DNS server → 192.168.64.15 - Network-wide ad blocking — every device on my network benefits from blocked ads and trackers without installing anything.
- Centralized local DNS — all my *.arcade-lab.io subdomains resolve correctly from any device, managed in one place.
- A nice dashboard — the Pi-hole web interface at https://pi-hole.arcade-lab.io shows me exactly what's happening on my network: how many queries are being made, what's being blocked, and which domains are the most popular.