Containers

Pihole Docker Swarm Configuration with Nginx Proxy Manager

Learn how to configure a Pihole Docker Swarm configuration with Nginx Proxy Manager using host networking and docker networking

As you guys know, I have been a huge proponent of Docker Swarm. I think it is still a very viable option as a middle ground between standalone Docker hosts and Kubernetes when you need more availability than a single host can provide but you don’t want the complexity of Kubernetes. One extremely popular solution to run in the home lab is Pi-Hole. Pihole is a network-wide ad-blocker that also does DNS resolution. While it is fairly easy to get up and running on a standalone Docker host, there are a few nuances to be aware of with Docker Swarm. Let’s look at Pihole Docker Swarm configuration with Nginx Proxy Manager.

Brief overview of Pihole

Pi-hole is a network wide ad-blocker. It uses DNS sinkholing technology to blacklist traffic to known telemetry, ad related, and even malware domains. When a client requests a resource from a domain on a blocklist, it simply “sinkholes” the request and it isn’t returned.

Pihole
Pihole

This not only is a great security solution to add, it also saves on network bandwidth since your clients aren’t having to pull down resources that you don’t knowingly request, like ads.

Brief overview of Docker Swarm

Docker Swarm is Docker on steroids. In other words, think of it like adding multiple docker hosts together to host your containers as a single entity rather than multiple standalone hosts. Once you add them to the Docker Swarm cluster, they are managed as a cluster and your containers are managed as services.

You need to have shared storage to pull this off. But using the open source solution Ceph, you can easily do this. Read my tutorial here on how to use Microceph to spin up a shared storage environment for docker swarm: Try Microceph for an Easy Ceph Install.

Docker swarm cluster with cephfs storage running docker services
Docker swarm cluster with cephfs storage running docker services

For a video walkthrough, take a look at my complete walkthrough on the best Docker setup using Docker Swarm here:

Pihole Docker Swarm configuration

Take a look at the Pihole Docker swarm configuration below. In this config, we tell Docker Swarm how we want to publish the ports for DNS and DHCP on the “host” interface. Usually you will have issues when trying to use a locally-scoped network in Swarm. It squawks and wants you to use a network that is Swarm compliant like the overlay network type.

Host networking is an exception to Swarm’s restriction on local-scoped networks. Docker Swarm allows network_mode: host because it bypasses Docker’s networking stack entirely and uses the host’s networking interface connection directly.

Considerations: When you use host networking, you run the chance of having ports conflict with one another. So, with publishing the ports that we are going to do for Pihole this way, make sure you have port 53 and 67 open on the host and you don’t already have another solution listening on these.

Why are we doing this? Well, it has to do with how Pihole behaves when you just place it on the normal overlay network that Docker Swarm creates. This causes Pihole to only show only the service ip on the connected clients list. This in turn leads to problems in Pihole. For instance, if you have exceptions for specific IPs on your network, these will no longer work as the clients won’t be appearing to Pi-hole as the IP they are on the network.

We are using the long-form method of publishing the ports. When we publish ports using the long format port mapping, we can set DNS ports 53 and DHCP port 67 bound directly to the host network. Again, this bypasses the ingress/overlay network.

Below is the Docker Compose code for the Pihole service running in Docker Swarm. I have pasted in my configuration and bolded the items you likely want to change, including the volume bind mounts.

Note: The cool thing with the below is that we are actually using a mix of networking connections. Publishing the ports on host networking for ports 53 and 67 uses the host connection, but then as you notice we are still including the network at the bottom of the code for our Nginx Proxy manager network. This means that the other ports (web admin) will be available on this network. This makes for the perfect combination of having things work for Pihole DNS and showing clients correctly and still having the ability to terminal SSL using Nginx Proxy Manager.

version: '3.8'

services:
  pihole:
    image: pihole/pihole:latest
    ports:
      - target: 53
        published: 53
        protocol: tcp
        mode: host
      - target: 53
        published: 53
        protocol: udp
        mode: host
      - target: 67
        published: 67
        protocol: udp
        mode: host
    environment:
      TZ: 'America/Chicago'
      WEBPASSWORD: 'password'  
      PIHOLE_DNS_: 1.1.1.1;9.9.9.9  
      DNSSEC: 'false'
      WEBTHEME: default-dark
      PIHOLE_DOMAIN: lan
      DNSMASQ_LISTENING: all
    volumes:
      - /mnt/cephfs/pihole/pihole:/etc/pihole
      - /mnt/cephfs/pihole/dnsmasq.d:/etc/dnsmasq.d
    networks:
      - npm-stack_nginxproxy
    deploy:
      replicas: 1
      restart_policy:
        condition: any
        delay: 5s
        max_attempts: 3

networks:
  npm-stack_nginxproxy:
    external: true

Save this as docker-compose.yml. Once you have the file saved, then run:

docker-compose up -d

Verifying the Pihole container and troubleshooting if needed

Make sure the container is up and running, which you can see with the output of:

docker ps

If you don’t see it running, see if it is stopped:

docker ps -a

If it is not running and exited, you can check the logs:

docker logs pihole

Nginx Proxy Manager configuration

Now, we can look at the Nginx Proxy Manager configuration. Nginx Proxy Manager as you may already know is an easy way to have SSL termination, a GUI interface for Nginx config and automated SSL certificate renewal all in one.

The installation and configuration of Nginx Proxy manager is outside the scope of this blog. However, I have written about this in detail here:

Once you have Nginx Proxy Manager configured, you can simply setup a new proxy host for your Pi-hole instance like the following:

  • Set your domain name (needs to match your public domain if you are doing proper Let’s Encrypt certs)
  • Set the scheme to http
  • Hostname or IP set to pihole
  • Forward port set to 80
  • I normally flag on block common exploits and websockets support
Nginx proxy manager configuration for pihole
Nginx proxy manager configuration for pihole

Viewing clients in Pihole

Now that you have the pihole container running and have Nginx Proxy Manager configuration set, as long as you have your DNS configured correctly, you should be able to browse out to the DNS name and not see a certificate error (if using Let’s Encrypt).

Pihole login screen
Pihole login screen

Now we see clients that are on my home lab networks, and not the internal services IP of the service in Docker Swarm. The subnets 192.168.1.0/24 and 10.1.149.0/24 are subnets outside of the cluster which is what I want to see.

Viewing clients in pihole
Viewing clients in pihole

Wrapping up

Running Pihole in Docker Swarm is not too difficult. It does require the little tweak of publishing ports using the host network instead of simply allowing these to come up on the overlay network that is internal to Docker Swarm. Pihole will work without doing this in Docker Swarm, but you will lose all visibility to which client is doing what and your whitelists based on clients won’t work. Let me know in the comments if you are running this config in your home lab.

Subscribe to VirtualizationHowto via Email ๐Ÿ””

Enter your email address to subscribe to this blog and receive notifications of new posts by email.



Brandon Lee

Brandon Lee is the Senior Writer, Engineer and owner at Virtualizationhowto.com, and a 7-time VMware vExpert, with over two decades of experience in Information Technology. Having worked for numerous Fortune 500 companies as well as in various industries, He has extensive experience in various IT segments and is a strong advocate for open source technologies. Brandon holds many industry certifications, loves the outdoors and spending time with family. Also, he goes through the effort of testing and troubleshooting issues, so you don't have to.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.