Installing Pihole with Docker on Synology NAS DSM6

corcoran
4 min readMay 26, 2020
or “start your pi-hole”

I’ve had some spare time recently to write a bunch of stories on medium that link together. This is the third (and final) in the series about getting Pihole setup once you’ve successfully:

  1. Using Cloudflare for DDNS with LetsEncrypt for TLS Certs — medium story
  2. Configured macvlan networking for Docker — medium story

My Cloudflare/LetsEncrypt certificate has a SAN name for ‘pihole’ so once I’ve deployed the basic Pihole service, I can also add my TLS cert into the lighttpd configuration. I’ve also got DDNS on my router here, so I’ve created a matching entry for it for accessing the fully qualified domain name internally.

Other Hot-takes

I pieced together a couple blogs for Pihole here:

  1. Started here — anything Scott can do, I can probably do in time x 3, and less well: https://scotthelme.co.uk/securing-dns-across-all-of-my-devices-with-pihole-dns-over-https-1-1-1-1/
  2. This Docker script was hugely helpful — https://gist.github.com/xirixiz/ecad37bac9a07c2a1204ab4f9a17db3c
  3. Docker-compose .env files made my service repeatable (and pretty) https://stackoverflow.com/questions/36283908/re-using-environmental-variables-in-docker-compose-yml
  4. Tony Lawrence’s blog was my starter-for-ten http://tonylawrence.com/posts/unix/synology/running-pihole-inside-docker/
  5. This thread on pi-hole cleared up a few blurry bits (especially around networking) https://discourse.pi-hole.net/t/setup-on-synology-docker/18067/2

So YAMPS (Yet another Medium Pihole Story) where I try to wrap all that up as neatly as possible for you. Because I want to create Docker services for my Synology box — rather than just spinning up random Docker files; I put everything together onto Github: https://github.com/farmerbean/synodocker Yes, the README needs updating.

Basics

Firstly, I’m running all my commands ssh’d onto my Synobox as an admin user. I have Docker installed through DSM; and have git installed from synoCommunity (as I’m using it for other things). So I create a folder in my /homes/admin directory, and run ‘git clone https://github.com/farmerbean/synodocker’. Now I have a working docker-compose service(s) ready(ish) to install.

Docker-Compose

My main docker-compose file (v2) is simply a service and networking manifest file. This means I can take services or apps up and down independently, or throw everything up and forget-about-it:

docker-compose index

As you can see, I have 2 services, and one macvlan network. It points (extends) each service to its own docker-compose file in a subfolder. Neat. When I run ‘docker-compose up -d’, it brings up both services together (detached), and creates a network called synodocker_home. I can bring up the pihole service with ‘docker-compose up -d pihole’ or because I’m lazy, more like:

echo "alias piup='sudo docker-compose up -d pihole'" >> ~/.bashrc

.env (Docker environment vars)

Within the root of my project, I also have an .env file, which makes things a little simpler if you clone the repo; all of my services currently use this .env but you can add .env’s for each folder/service as required (closer takes precedence).

DOCKERHOME=/volume2/docker #my Docker home is on a small secondary array
CERTHOME=/usr/local/share/acme.sh #I’ve used acme.sh as detailed in my intro
DOMAINNAME=farmerbean.dev #my Cloudflare domain name
PIHOST=pihole #my err.. pihole hostname
DSMHOST=syno #my dsm hostname

Pihole Service Config

So down in my pihole/docker-compose file, I have:

pihole docker-compose file

This means is quick and easy to change your DOCKERHOME, CERTHOME, PIHOST and DOMAINNAME vars in one file (or add more).

A quick note on the volume mapped configuration:

  1. /etc/localtime to keep time in sync
  2. pihole-configs for my pihole configs
  3. dnsmasq.d for my dnsmasq.d config
  4. external.conf is my https configuration for the pihole web interface #OPTIONAL (see below)
  5. $(CERTHOME) maps my LetsEncrypt cert directory into pihole so I can add it into external.conf (above)

Configuring the HTTPS Interface

If you add the volume mapping for external.conf (above) you’ll need to make changes to the LetsEncrypt certificates and modify the file before bringing up the service. Sorry.

Assuming you’re using acme.sh for your certs, they’ll be in /usr/local/share/acme.sh/${domainname}. Apparently you can’t just use the cer and key (like every other app allows you to) but you have to bundle up the cert and use that — this could be problematic when it comes to renewals, so except an update around July 2020 on this story.

Firstly, assuming you’re still ssh’d to the command-prompt, cat and tee the certs into a single file:

$ sudo cat /usr/local/share/acme.sh/${DOMAINNAME}/${DOMAINNAME}.key \
/usr/local/share/acme.sh/${DOMAINNAME}/${DOMAINNAME}.cer | \
sudo tee /usr/local/share/acme.sh/${DOMAINNAME}/${DOMAINNAME}.combined.pem

Ugh.

I’ve bundled an external_template.conf file, which you should copy to external.conf and update with your own values. Copy that file into the location specified in your volume mappings before running docker-compose.

Spinning it up

So you’ve prepped your https config, and created your combined certs. Either run ‘sudo docker-compose up -d’ for every service, or ‘sudo docker-compose up -d pihole’ for your pihole service. Enjoy.

Updating Gravity

You will want to do periodic updates to the Gravity lists on pihole. Ideally unattended. Create a simple bash_script.sh as follows. I assume you have also called your Pi-hole docker container ‘pihole’:

#!/bin/bash
docker exec pihole pihole updateGravity

In DSM, open Control Panel -> Task Scheduler and create a weekly task to execute your bash_script to keep your blocklists up-to-date.

--

--

corcoran

Is this bio too short? Or is it just the right length?