Running Pi-Hole on a Mikrotik router in Docker
My router history
As I mentioned earlier, I have a Mikrotik hAP ac3 router. I always liked fine-tuning my routers, the previous one was a TP-Link device with OpenWRT installed on it. I bought the Mikrotik router after much deliberation since I was sure that I have the adequate level of networking knowledge to comfortably play with OpenWRT, RouterOS is a different kind of animal. Oh boy, was I not wrong! Everything they tell you in forums and in person is true about Mikrotik: the learning curve is so steep that you have to hang on for dear life all the way. You see, I worked as a network admin, and also dabbled a little in the telco sector so I had my fair share of network related issues and knowledge but that did not prepare me for the freedom RouterOS hands you so casually. Maybe this will worth another post at some time but now, back to the original topic.
Ad(vanced) needs
After configuring the router for my default needs I turned to the more advanced functions, for example ad-blocking. In OpenWRT I used the adblock package and wanted something similar for RouterOS, but unfortunately found nothing, so I turned towards hosting Pi-Hole on my NAS, which worked fine and also worth another post, now that I mention it.
But of course, this was not enough for me, I wanted the network functions provided by my network device, so let’s see what we can do.
Mikrotik containers
From RouterOS version 7.5 Mikrotik provides docker container support, which is just what I needed. The final push for me was this YouTube video from Mikrotik, demonstrating the container functionality with
…pause for dramatic effect…
Pi-Hole.
The following how-to is created based on this page from Mikrotik, but I commented and changed some things here and there.
Prerequisites
- Upgrade to RouterOS 7.5 or newer
- Enable the container functionality: this requires physical access to the device!
- The router’s internal storage will not be enough to store the container files so an external USB drive is recommended
Enable the container functionality
- Download the extra packages file for the proper architecture from mikrotik.com
- copy the .npk file to the root dir of the router
- Reboot
- After reboot we need to enable the container functionality:
/system/device-mode/update container=yes - After on more reboot the container functionality is enabled and available in the menu
Add external storage
- Plug in the USB drive
- Format it in
/system/disktoext4
Network config for docker
Create a bridge for containers
/interface/bridge/add name=dockers
Assign an IP address range to the bridge
/ip/address/add address=172.17.0.1/24 interface=dockers
Create a virtual interface
/interface/veth/add name=veth1 address=172.17.0.2/24 gateway=172.17.0.1
Add the new veth1 interface as a port to the dockers bridge
/interface/bridge/port/add bridge=dockers interface=veth1
Add firewall rule so the containers can access the internet
This is needed so the images can be downloaded to the router.
/ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.17.0.0/24
Allow HTTP traffic through to the container
This rule forwards all HTTP traffic to the Pi-Hole container’s web page.
|
|
Container config
Add container environment variables
|
|
Add container mount points
|
|
Add docker registry URL
/container/config/set registry-url=https://registry-1.docker.io tmpdir=disk1/pull
Pull the image
Using the pihole:2022.11.1 tag because I don’t like to use the latest tag for mission critical services. Later this will be updated manually every time after a new release.
/container/add remote-image=pihole/pihole:2022.11.1 interface=veth1 root-dir=disk1/pihole mounts=dnsmasq_pihole,etc_pihole envlist=pihole_envs
Wait for the image to be pulled and extracted. This can take 10-15 minutes on my system.
Start the container
/container/start 0
Set up the Pi-Hole container as DNS server
/ip dns set servers=172.17.0.2
Additional settings
There are a few additional things I configured.
Start the container on reboot
/container/set 0 start-on-boot=yes
Limit RAM usage
As far as I understand this is a setting for all the containers combined.
/container/config/set ram-high=40M
Logging
/container/set 0 logging=yes
Shell access
If you’d like to check out the inside of the container for some reason:
/container/shell 0