Run Pi-hole on Your MikroTik Router
A step-by-step guide to running Pi-hole as a Docker container directly on RouterOS v7, providing network-wide ad blocking without a separate device.
Overview
RouterOS v7 includes a Container feature that can run Docker-compatible images directly on your router. Pi-hole is an ideal workload for this — it’s lightweight, runs happily on ARM64, and its network position on the router actually makes it easier to configure as your DNS server.
Your devices (phones, laptops, TVs)
│ DNS queries
â–¼
MikroTik Router (192.168.88.1)
│
â–¼
Pi-hole container (172.17.0.2) <── running on RouterOS
│ filtered queries only
â–¼
Upstream DNS (e.g. 1.1.1.1)
Prerequisites
Step-by-Step Setup
Download the Container package for your RouterOS version from mikrotik.com/download. Upload it to your router via Winbox (Files section), then reboot.
Verify it’s installed:
/system/package/print
You should see container listed as an installed package.
Container mode is disabled by default and requires physical access to enable. Run the following command, then press the reset button on the router when prompted to confirm:
/system/device-mode/update container=yes
Plug in your USB drive. Check what RouterOS has named it, then format it:
# Check the disk name first /disk/print # Format as ext4 (replaces any existing data) /disk/format-drive [find] filesystem=ext4
Then set the container registry and temp directory:
/container/config/set \ registry-url=https://registry-1.docker.io \ tmpdir=disk1/tmp
disk1 with the actual disk name shown in /disk/print if it differs.
Create a virtual network interface and bridge for the container to communicate through:
# Create virtual ethernet interface for the container /interface/veth/add name=veth1 address=172.17.0.2/24 gateway=172.17.0.1 # Create a bridge and assign an IP /interface/bridge/add name=containers /ip/address/add address=172.17.0.1/24 interface=containers # Add the veth interface to the bridge /interface/bridge/port add bridge=containers interface=veth1 # Allow container to reach the internet (for upstream DNS) /ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.17.0.0/24
Pi-hole needs a few environment variables. Set your timezone and a web admin password:
/container/envs/add list=ENV_PIHOLE key=TZ value="Australia/Adelaide" /container/envs/add list=ENV_PIHOLE key=FTLCONF_webserver_api_password value="your-secure-password" /container/envs/add list=ENV_PIHOLE key=DNSMASQ_USER value="root"
Replace Australia/Adelaide with your timezone and set a strong password for the web panel.
These mounts ensure Pi-hole’s configuration and data survive container restarts:
/container/mounts/add list=MOUNT_PIHOLE_PIHOLE \ src=disk1/volumes/pihole/pihole \ dst=/etc/pihole /container/mounts/add list=MOUNT_PIHOLE_DNSMASQD \ src=disk1/volumes/pihole/dnsmasq.d \ dst=/etc/dnsmasq.d
Pull and create the Pi-hole container. This will begin downloading the image — it may take a few minutes:
/container/add \ remote-image=pihole/pihole \ interface=veth1 \ root-dir=disk1/images/pihole \ mountlists=MOUNT_PIHOLE_PIHOLE,MOUNT_PIHOLE_DNSMASQD \ envlist=ENV_PIHOLE \ name=pihole \ start-on-boot=yes \ logging=yes
Monitor the download status:
/container/print
Wait until status=stopped appears (meaning it has downloaded and is ready). Then start it:
/container/start pihole
To access the Pi-hole dashboard from your browser, add a NAT rule to forward port 80 on the router’s LAN IP to the container:
/ip/firewall/nat/add \ chain=dstnat \ dst-address=192.168.88.1 \ dst-port=80 \ protocol=tcp \ action=dst-nat \ to-addresses=172.17.0.2 \ to-ports=80
You can now access the Pi-hole admin panel at http://192.168.88.1/admin
Tell RouterOS to use Pi-hole as the DNS server. The second address is a fallback — if Pi-hole goes down, DNS falls back to Cloudflare automatically:
/ip/dns/set servers=172.17.0.2,1.1.1.1 allow-remote-requests=yes
Then update your DHCP server to hand out the router’s IP as the DNS server to all your devices:
/ip/dhcp-server/network/set [find] dns-server=192.168.88.1
ipconfig /renew on Windows.
Verifying It Works
Open the Pi-hole dashboard at http://192.168.88.1/admin and log in with the password you set. After a few minutes you should see DNS queries appearing in the Query Log as your devices browse normally.
You can also check the container is running:
/container/print # Should show status=running # View live logs /log/print
Quick Reference
| Item | Value | Notes |
|---|---|---|
| Container IP | 172.17.0.2 |
Pi-hole’s internal address |
| Router/Gateway IP | 172.17.0.1 |
Container network gateway |
| Web admin panel | http://192.168.88.1/admin |
Accessible from LAN devices |
| Start container | /container/start pihole |
|
| Stop container | /container/stop pihole |
|
| View logs | /log/print |
Requires logging=yes on container |
| Open shell | /container/shell pihole |
Access Pi-hole’s Linux shell directly |
| Update image | /container/update pihole |
Pulls latest Pi-hole image |
Troubleshooting
Container stays at “extracting” for a long time
USB drives with slow random I/O can make extraction take 10–20 minutes. Check with /container/print and be patient. If it never changes, check /log/print for errors.
Can’t reach the admin panel
Confirm the container is running (/container/print should show status=running). Also verify the NAT rule was added correctly with /ip/firewall/nat/print.
DNS stops working for the whole network
If Pi-hole crashes, the fallback DNS (1.1.1.1) set in Step 9 should keep your network online. Check the container status and restart it if needed:
/container/start pihole
Pi-hole isn’t blocking ads
Check the Query Log in the Pi-hole dashboard to confirm queries are arriving. If the log is empty, your devices may still be using their old DNS server — force a DHCP renewal or manually set DNS to 192.168.88.1 on a test device.
Tested on MikroTik hAP ax³ running RouterOS v7.x · Pi-hole container image: pihole/pihole:latest · Guide last updated June 2026



