Router OS 7.4 finally added back support for Linux Containers (Docker) and I couldn’t wait a minute longer to give it a try! [main topic]
For an introduction, you can follow the Container Wiki Page including a tutorial to enable containers and set up a Pihole DNS server.
I’ve decided to create a generic container image to be able to SSH into it and play around. It is probably not the best use of Docker containers but gives you a tiny handy isolated Linux server running directly inside the router to try different ideas and do benchmarks without the hassle of externally creating and testing images each time.
Prebuilt containers include common utilities such as vim, curl, speed-test and iperf3 with an enabled open-ssh server. You can install additional packages using apt-get (debian) or apk (alpine) or build a customized version from the Docker files provided.
Here are some screenshots of the Debian and Alpine containers running on my RB5009UG+S+IN.
Step 0: Backup and Requirements
Make sure to backup your router configuration and be aware this is still an experimental feature. And make sure to have:
- RouterOS device with RouterOS v7.4beta or later and installed Container package
- Physical access to a device to enable container mode
- Attached hard drive or USB drive for storage - formatted as ext3/ext4
Step 1: Upgrade and enable containers
Download the latest 7.4beta version of router os + extra packages (container). Then move them to the router using Winbox > Files and reboot to install.
After reboot, enable container mode. You need physical access to turn off or reboot the router to enable container mode.
/system/device-mode/update container=yes
Step 2: Create network
Add veth interface for the container:
/interface/veth/add name=veth1 address=172.17.0.2/16 gateway=172.17.0.1
Create a bridge for containers and add veth to it:
/interface/bridge/add name=dockers
/ip/address/add address=172.17.0.1/16 interface=dockers
/interface/bridge/port add bridge=dockers interface=veth1
Setup NAT for outgoing traffic:
/ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.17.0.0/16
Step 3: Download image
Download the docker image and transfer it to the router.
If you prefer to build the images yourself for a different architecture use Docker files and entry from this gist and build against your router’s CPU architecture. I’ve hosted some prebuilt images for easy use.
We the fetch tool to download into the router directly but you can use your preferred method to fetch the links.
[ARM64] Debian (300MiB): (if you have enough space on an external disk, go for it!)
/tool/fetch url=https://dl.home.pi0.io/mikrotik/docker/debian.arm64.tar dst-path=disk1/images/linux.tar
[ARM64] Alpine slim (7.8 MiB): (super-slim build. you can add other packages using apk)
/tool/fetch url=https://dl.home.pi0.io/mikrotik/docker/alpine-slim.arm64.tar dst-path=disk1/images/linux.tar
[ARM64] Alpine (40 MiB): (a moderate build with alpine base)
/tool/fetch url=https://dl.home.pi0.io/mikrotik/docker/alpine.arm64.tar dst-path=disk1/images/linux.tar
Step 4: Configure the container
Set an env to autoconfigure SSH root password (value is an example. use something more secure!)
/container/envs/add list=linux_envs name=PASSWD value="letmein"
Create persisted data volume (ssh keys and home dir):
/container/mounts/add name=linux_data src=disk1/docker/linux_data dst=/data
Create the container:
/container/add file=disk1/images/linux.tar interface=veth1 envlist=linux_envs root-dir=disk1/docker/linux_root mounts=linux_data hostname=mikrotik
What for status from “extraction” to be “Stopped”. It might take few minutes based on your storage speed.
/container print
Finally, start it:
/container start 0
Wait and check for the status to be “running”:
/container print
Note: If you have more than one container, the second might not be starting. I’m still trying to figure out why but removing the first one using /container/stop 0
and /container remove 0
fixed the problem for me.
Step 5: Connect to the container
You can ssh into the container using ssh -v root@172.17.0.2
. Use the password defined in earlier steps (default is letmein).
Happy hacking and please share your feedback and ideas in the forum!