Manual

Containers on RouterOS

A small application alongside RouterOS on the same device, if your hardware can carry it.

RouterOS v7 can run containers: a ready made image, the same kind of image you know from Docker, running next to the operating system on the router. Pi-hole, a small DNS server, an MQTT broker, something that collects data. It is attractive because you do not have to add a device, and it goes wrong because the router was not built for it.

Read the rest of this chapter before you put this on a device that is in use. Containers need storage, memory and a confirmation by hand. It is the only part of the configurator where you have to be standing next to the device.

Which devices can run them

The Containers part only appears when your model can carry it. The configurator looks at the architecture for that: ARM64, x86 and Tile. A device with an older 32 bit ARM or MIPS is told that containers require ARM64 or x86, and that is the end of it.

The architecture is the only check the tool makes, and it is not enough. What you have to weigh yourself:

  • Memory. A router with 64 or 128 MB of RAM runs RouterOS and nothing else. Count on at least half a gigabyte before a container fits next to a working configuration.
  • Storage. The internal flash of a RouterBOARD is small and wears out from writing. Use a USB stick, an SSD or NVMe. That is not advice about tidiness, it is the reason devices die.
  • The package. container is a separate package that you download from MikroTik and install on the router yourself.

Device-mode

Containers sit behind device-mode, the protection RouterOS gained after devices were being used remotely as a botnet. So the first line of this part is:

/system device-mode
update container=yes

That line asks for a physical confirmation within five minutes: press the reset button, or take the power off and back on. Skip it and nothing happens. Because the rest of the part can only work once that is done, in practice this runs in two rounds: paste the script, confirm, then run the container part again. The script says so in a comment.

The System part has a switch called Apply parts blocked by device-mode later, which moves the blocked lines into a script that runs once at the next start. That helps here, but it also adds a step you have to remember: the device has to be powered off and on again within a day. See System and time.

The settings

Storage
The name of the disk used as root-dir, disk1 by default. Use /disk print to see what your disk is called; on a USB stick it is often usb1-part1. This is where the image layers, the temporary files and each container's files end up.
Container network
The router's address in the container network, 172.17.0.1/24 by default. This is the address containers get as their gateway. Pick something that does not occur anywhere else in your network.
Registry URL
Where the images come from, https://registry-1.docker.io by default. If you have your own registry or a mirror, put it here.

The containers themselves

Per container you fill in:

  • Name: it comes back as the comment, as the name of the veth interface and as a directory on your disk.
  • Image, for example pihole/pihole:latest. Pin a version instead of latest if you want a restart to keep doing the same thing.
  • IP in the container network, for example 172.17.0.2. In the same subnet as the address above.
  • Environment variables, one KEY=value per line. This is how a container gets its settings.
  • Mounts, one name:/path-in-container per line. The tool turns that into a directory on your disk, so the data survives a restart of the container.
  • Forward ports from the LAN, for example tcp:80,443 udp:53.

Environment variables end up in the script literally. Put a password in there and that password is in the script and in whatever you share. Treat the file accordingly.

What ends up in the script

  • The device-mode line, with the comment telling you to confirm.
  • A bridge called containers, the router address on it and a masquerade rule, so containers can reach the outside.
  • /container config with the registry and the directories for temporary files and layers on your disk.
  • Per container an /interface veth named veth-<name> with the address and the router as gateway, added as a port to the containers bridge.
  • /container envs and /container mounts if you filled them in, then the /container line itself with start-on-boot=yes and logging on.
  • A dst-nat rule per forwarded port, on the router's own address, from the LAN interface list.

The veth is the cable between RouterOS and the container: the container sees it as its network card, the router sees it as an interface in the bridge. Because all containers share that bridge, they can also see each other.

The port forwarding means, in practice, that you reach the container on the router's own address, on that port. Pi-hole on tcp:80 is therefore on your router's LAN address, not on 172.17.0.2.

What the script does not do

It does not start your container. The image has to be pulled first, which takes time and can fail. The last line of the part tells you how to start it yourself:

/container start [find comment="name"]
/log print where topics~"container"

start-on-boot=yes does make sure it comes up with every start after that.

Things that go wrong

  • Nothing happens. Nine times out of ten device-mode was not confirmed. Check with /system/device-mode/print.
  • The image will not download. The router needs working DNS and internet of its own for that, and enough room on the disk. Look in the log.
  • The disk name is wrong. If it says disk1 while your stick is called something else, everything writes to a path that does not exist. Check with /disk print before you paste.
  • The container is unreachable from a VLAN. If you marked that VLAN as isolated it may only reach the internet, and this is the isolation doing its job. See Firewall.
  • The router gets slow. A container shares CPU and memory with the routing itself. Use /system resource print to see what is left, and be willing to take the container away again.

When not to do this

A container on the router is attractive for one small thing on a device with room to spare. For anything that really matters, and certainly for your DNS, a separate little box is usually the better answer: when your router reboots for an update, your DNS would otherwise go down with it. A router that routes is a router you trust.

Further reading: Choosing your device, DNS and Services and tools.

Want to try it right away? Open the configurator