DEV Community

Fran Torres
Fran Torres

Posted on

Pi-Hole setup using Quadlets

I've had an old Raspberry Pi Model B running Pi-Hole at home for quite a long time, but I always wanted to dig a bit deeper into using containers to deploy applications. Because of that, I recently purchased a RPi 4 and this week found some time to figure out a way to deploy it using podman.

Since I started reading about containers, podman and such, it always looked a bit convoluted the way to run an application from the command line; many parameters basically, I didn't want to have one script launching one 100 characters command.
I then learnt docker-compose files, which are nice, but in my absolutely ignorant opinion seem to be only useful for local services (like on a development environment to spin a database); things you don't want to live forever as a service. And the second problem was: I wanted to use podman and, ideally, only native podman-related solutions.
Fast forward until recently. I read about systemd-units and quadlets and liked what I saw, so here we are.

Quadlets

I won't go too deep into all the details about podman, systemd and quadlets as Daniel Schier did it already way better than I will ever be able to.
Basically you can split a container deployment within its multiple dependant components (volumes, network, the container itself...) and generate systemd services that can be easily managed. You can either do it manually by running the container from the command line (via podman) and then generate the systemd unit with podman generate systemd OR you can use quadlets to have a single centralised set of files that systemd will use to automatically generate the service units for you.

Decissions and future goals

[x] Use rootfull containers for now (it felt easier not having to worry about port mapping).
[x] openSUSE MicroOS will be the host system. I want to automate maintenance as much as possible and using an immutable & self updatable system is a first step.
[ ] Automatically update the container.
[ ] Use unbound.
[ ] Use rootless containers.

Deploying Pi-Hole via Quadlets

Previous step

Without going into much details, first of all make sure there are no processes blocking at least ports 53 (tcp and udp) and 80 tcp if Pi-Hole will only be acting as the DNS server and not DHCP.
For example, here's the default installation of openSUSE MicroOS and, as you can see there's nothing listening on those ports. For that we'll use the command ss -tunlp.

Port mapping check in openSUSE MicroOS proving that nothing is listening in ports 53 or 80

By contrast, a default installation of Fedora shows the service systemd-resolved listening on ports 53.

Port mapping check in Fedora showing systemd-resolved listening in port 53

I'll leave that up for research if you need to disable the service, but there's plenty of documentation on the topic.

Provisioning needed files

As we are going to use a rootfull container, we need to place our Quadlets in /etc/containers/systemd/. We will create a bunch of files:

  • Two .volume files for the volumes Pi-Hole needs.
  • One .network file to configure the network for the container.
  • One .container file for the main container.

pihole-dnsmasq.volume

[Unit]
Description=PiHole dnsmasq Container Volume

[Volume]
Label=app=pihole
Enter fullscreen mode Exit fullscreen mode

pihole-pihole.volume

[Unit]
Description=PiHole Data Container Volume

[Volume]
Label=app=pihole
Enter fullscreen mode Exit fullscreen mode

pihole.network

[Unit]
Description=PiHole Container Network

[Network]
Label=app=pihole
DisableDNS=true
Enter fullscreen mode Exit fullscreen mode

pihole.container

[Unit]
Description=PiHole Service Container

[Container]
Label=app=pihole
ContainerName=pihole
HostName=pihole
Image=docker.io/pihole/pihole:latest
Network=pihole.network
Volume=pihole-pihole.volume:/etc/pihole
Volume=pihole-dnsmasq.volume:/etc/dnsmasq.d
AddCapability=NET_ADMIN
AutoUpdate=registry
PublishPort=53:53/tcp
PublishPort=53:53/udp
PublishPort=80:80/tcp
# Ignore the next 2 ones if not using pi-hole as dhcp server and not using https
PublishPort=67:67/udp
PublishPort=443:443/tcp

Environment=DNSMASQ_LISTENING=all
# Next variables to be customised
Environment=WEBPASSWORD="pihole"
Environment=TZ=Europe/Madrid
Environment=DNS1=208.67.222.222
Environment=DNS2=208.67.220.220
Environment=TEMPERATUREUNIT=c

[Service]
Restart=unless-stopped

[Install]
WantedBy=multi-user.target default.target
Enter fullscreen mode Exit fullscreen mode

Change the webUI password to something better, set your timezone and temperature unit, and choose an upstream DNS provider (the one above is OpenDNS).

Generate and run service

Let's ask systemd to generate services from these files now. Run the following command as root:

systemctl daemon-reload
Enter fullscreen mode Exit fullscreen mode

And lastly, run the service. As we said at the beginning this service is rootfull, so needs to be run as root. Just run the next command in a terminal and you should be done:

systemctl start pihole.service
Enter fullscreen mode Exit fullscreen mode

If there are any failures you can check what happened with systemctl status pihole.service.

I have created a repository to hold this code for future use.

References

Top comments (0)