RouterOS 7 can run containers — actual OCI images, on the router itself. Pi-hole, a WireGuard UI, a Prometheus exporter, a tiny web service: on the box that's already always-on, instead of a separate Raspberry Pi you have to power and maintain. It's the most "small, sharp, composable" feature MikroTik has shipped in years, and the docs are thin. Here's the honest build.
The container feature runs OCI (Docker) images directly on RouterOS. It is not a full Docker Engine — no compose, no swarm, minimal orchestration — but it runs a single image with an interface, environment, and mounts, which covers a surprising amount: DNS ad-blocking, a metrics exporter, a management UI, a small automation helper. The pitch is consolidation: the router is already the always-on box at every site, so a lightweight service belongs there rather than on another device to power, patch, and worry about.
Three things make this feel un-MikroTik and trip people up: it needs the container package and a deliberate device-mode opt-in (a security gate — you physically confirm it), it needs real storage for the image root, and the image architecture must match the board (ARM/ARM64/x86). Get those three right and the rest is networking you already know. Pairs with fleet management and, naturally, the Prometheus exporter post.
01
Containers are powerful enough that MikroTik gates them behind an explicit, physically-confirmed opt-in. This is deliberate: a container is arbitrary code on your router.
# 1. Install the separate 'container' package (download the extra # package bundle for your version/arch, upload, reboot). > /system package print # confirm 'container' is enabled after reboot # 2. Turn on container support in device-mode. This will NOT take effect # until you confirm by power-cycling or pressing the reset button. > /system device-mode update container=yes ... device-mode update requires confirmation — power-cycle the board or press the reset/mode button within the timeout.
The physical-confirmation gate exists for a reason: whatever runs in the container runs on your router, with whatever network access you give the veth. Treat container images like any third-party dependency — pin versions, pull from trusted registries, and give the container its own isolated bridge/VLAN with a tight firewall, never a straight bridge onto your LAN. On an internet-facing edge, a compromised container is a foothold behind your perimeter. This is exactly the kind of surface the hardening and offensive posts care about — power with responsibility.
02
A container gets a virtual ethernet (veth) interface. Put it on a dedicated bridge with its own subnet, masquerade for outbound, and you control exactly what it can reach.
# The container's virtual NIC, with a gateway pointing at our bridge. > /interface veth add name=veth-pihole address=172.19.0.2/24 gateway=172.19.0.1 # A dedicated bridge for containers — NOT your LAN bridge. > /interface bridge add name=containers > /interface bridge port add bridge=containers interface=veth-pihole > /ip address add address=172.19.0.1/24 interface=containers # Let the container reach the internet (to pull updates etc). > /ip firewall nat add chain=srcnat src-address=172.19.0.0/24 \ out-interface-list=WAN action=masquerade
03
Point the registry, set environment and mounts, add the container against the veth, and start it. Pi-hole makes a good first target — DNS ad-blocking for the whole site, hosted on the router.
# Where to pull from, and a temp dir on real storage for the layers. > /container config set registry-url=https://registry-1.docker.io tmpdir=disk1/pull # Env vars and a persistent mount (so config survives a container rebuild). > /container envs add name=ph-envs key=TZ value="Europe/Athens" > /container mounts add name=ph-etc src=disk1/pihole/etc dst=/etc/pihole # Create the container against the veth, rooted on disk, then start it. > /container add remote-image=pihole/pihole:latest interface=veth-pihole \ root-dir=disk1/pihole/root envlist=ph-envs mounts=ph-etc \ logging=yes start-on-boot=yes > /container print # status: extracting -> stopped > /container start [find] # -> running; point LAN DNS at 172.19.0.2
04
Containers are handy but the small boards are not servers. Know the constraints before you build a site around one.
| Constraint | What it means in practice |
|---|---|
| Architecture must match | ARM image on an ARM board — an x86 image won't run on an RB. Check the tag. |
| Storage required | root-dir + layers need real disk (USB/NVMe); flash-only boards can't. |
| RAM/CPU are modest | Fine for Pi-hole/exporters; not for anything hungry. Watch /system resource. |
| Use mounts for state | Anything not on a mount is lost on rebuild — persist config explicitly. |
| No compose/orchestration | One image at a time, wired by hand. It's a helper, not a platform. |
The killer uses are the small, always-on helpers that used to justify a separate Raspberry Pi: Pi-hole DNS filtering, a Prometheus/SNMP exporter (see the metrics post), a WireGuard UI for the VPN, a webhook/automation shim. One fewer box per site to power, patch, and lose. Match the ambition to the board and it's a genuinely elegant piece of consolidation.
Takeaways
NOCTIS consolidates edge services onto the RouterOS boxes you already run across Crete — DNS filtering, metrics, VPN UIs — properly isolated and firewalled, one fewer thing to power and patch.
Book a Discovery Call →