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

  1. Download the extra packages file for the proper architecture from mikrotik.com
  2. copy the .npk file to the root dir of the router
  3. Reboot
  4. After reboot we need to enable the container functionality: /system/device-mode/update container=yes
  5. After on more reboot the container functionality is enabled and available in the menu

Add external storage

  1. Plug in the USB drive
  2. Format it in /system/disk to ext4

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.

1
2
/ip firewall nat
add action=dst-nat chain=dstnat dst-address=192.168.88.1 dst-port=8088 protocol=tcp to-addresses=172.17.0.2 to-ports=80

Container config

Add container environment variables

1
2
3
4
/container/envs
add key=TZ name=pihole_envs value=Europe/Budapest
add key=WEBPASSWORD name=pihole_envs value=verysecretpassword
add key=DNSMASQ_USER name=pihole_envs value=root

Add container mount points

1
2
3
/container/mounts
add dst=/etc/pihole name=etc_pihole src=/disk1/etc
add dst=/etc/dnsmasq.d name=dnsmasq_pihole src=/disk1/etc-dnsmasq.d

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