What the router needs
This page lists what has to be in place before mikroscope install can write
anything: three things on the router the tool cannot do for you, the resources
and firewall lists it checks, and what the host you run it from needs.
mikroscope doctor checks all of it read-only, in one ssh connect, and prints
the exact command or physical step for anything missing.
A container-capable device
Section titled “A container-capable device”The router must run RouterOS 7.24 or later on one of three architectures: arm64, arm (32-bit RouterOS on the hEX refresh line) or x86_64. Not MIPS, not TILE.
7.24 is the floor because the container step writes privileged=, an attribute
RouterOS added in that release. doctor prints the version and checks nothing
against it, so on an earlier 7.x the install runs as far as the container and
fails there with RouterOS’s error about an unknown privileged parameter —
and a write that prints anything counts as a failure, so the install stops and
takes the uploaded tar back with it. --privileged=false is the way through,
at the price of everything the container’s user namespace hides:
What privileged buys lists it.
Tell the CLI which one with --arch: arm64 (the default), arm or amd64.
doctor compares it with the router’s architecture-name and, on a mismatch,
names the flag to re-run with.
| Your device | architecture-name |
--arch |
The agent build |
|---|---|---|---|
| RB5009, CCR2004, hAP ax³ and other 64-bit ARM | arm64 |
arm64 |
linux/arm64 |
| hEX Refresh / hEX S (2025), any EN7562CT board | arm |
arm |
linux/arm/v5 |
| Other 32-bit ARM (hAP ac², hAP ax², …) | arm |
arm |
linux/arm/v5 or v7 |
| CHR and x86 RouterOS | x86_64 |
amd64 |
linux/amd64 |
Scroll sideways to see every column
32-bit ARM is two things, not one. MikroTik’s container documentation
states that devices with the EN7562CT CPU — the hEX Refresh line — “support
only arm32v5 container images”, while its other 32-bit ARM boards run an ARMv7
userland. An ARMv5 binary runs on both; an ARMv7 one does not run on the first,
and the way it fails is an exec format error in the container log after a
successful install. So --goarm defaults to 5, the level that starts
everywhere, and the image declares the matching variant. --goarm 7 builds the
ARMv7 one for a board where that instruction set is wanted; what the difference
costs has not been measured, because this project has no ARM hardware.
--remote-image makes the question go away: the published index carries
linux/amd64, linux/arm64, linux/arm/v7 and linux/arm/v5, and the router
picks its own.
The container package
Section titled “The container package”Download the container package for your architecture and RouterOS version
from mikrotik.com, upload it to the router and reboot; then
/. That is the fix doctor prints, and it
counts the package as present only when it is installed and not disabled.
device-mode container=yes
Section titled “device-mode container=yes”MikroTik gates containers behind a physical step:
-
Run, on the router’s console:
/system/device-mode/update container=yes -
The console answers:
update: please activate by turning power off or pressing reset or mode button in 5m00s -
Within those five minutes, press the reset or mode button, or power-cycle the router. If nobody does, the change is cancelled.
After three failed attempts the router says
too many unsuccessful attempts … to reset attempt-count and needs a power
cycle before it accepts another.
What doctor checks
Section titled “What doctor checks”doctor prints device: with the board, the RouterOS version and the
architecture, then one line per check marked ok or MISSING, with what it
found in parentheses and, for a missing one, a fix: line. It ends with
doctor: every prerequisite is met, or fails with
N prerequisite(s) missing; nothing was written. install runs the same checks
first unless you pass --no-doctor.
| Check, as printed | Passes when | The fix it names |
|---|---|---|
| registry-url is https://<host> | with --remote-image, / names the reference's registry host. Without --remote-image doctor does not ask: the setting is global to the device and mikroscope never writes it | / on the router, which applies to every container on it, or install from a tar with --agent-tar |
| container package installed and enabled | a container package exists with disabled=no | download, upload, reboot; then / |
| device-mode container=yes | /system/device-mode reports container=yes | /, then the reset or mode button, or a power cycle, within 5 minutes |
| architecture matches --arch <arch> | the router's architecture-name is the one --arch maps to (arm64, arm, x86_64) | re-run with the --arch it names |
| free memory ≥ <--memory-max> | free-memory is at least what --memory-max asks for, 64 MiB by default | free memory on the router, or ask for less with --memory-max |
| free flash ≥ <size> (image tar + extracted root) | without --disk: free-hdd-space is at least twice the image plus 4 MiB | free flash, or install with --disk tmpfs or --ephemeral where a tmpfs disk exists |
| disk <disk> exists | with --disk or --ephemeral: a disk with that slot exists; its free space is not checked | /disk/add type=tmpfs tmpfs-max-size=64M slot=tmpfs for a RAM disk, or name an existing disk with --disk |
| interface list <list> exists (raw rule trap) | the --iface-list list (default LAN) exists | /, or pass the list your in-interface-list=!… drop rule uses |
| address list <list> has entries (raw rule trap) | the --addr-list list (default LANs) has at least one entry | pass the list your drop local if not from default IP range rule uses; an empty list is fine only if there is no such rule |
| veth name <veth> is free or ours | always reported ok, with the count found | none: a collision is caught by install itself |
Scroll sideways to see every column
The flash check uses the real tar size under install. doctor on its own
assumes a 7 MiB image, so it asks for 18.0 MiB. Twice the image because the tar
and the root extracted from it are on the disk together until install deletes
the tar; with --remote-image no tar is uploaded, so the check asks for the
4 MiB of headroom alone. The memory threshold follows --memory-max: it asks
for at least what that flag asks for, which is 64 MiB by default, so
--memory-max 128M on a router with 70 MiB free is caught here rather than by
a container that will not start.
The registry-url check runs only with --remote-image, and only when the
reference carries a registry host. /container/config is global to the device
and shared with every other container on it, so mikroscope reads that setting
and never writes it. RouterOS ships it as https:/, so the
Docker Hub reference, --remote-image jmrplens/, needs
nothing set there on an untouched router, and the GHCR reference is the one that
needs the setting changed first.
Four ways to install has the
command to set it by hand.
The two list checks exist because of two raw firewall rules that drop every
packet a container sends; The two firewall traps
explains them. doctor marks an empty address list missing even on a router
that has no such rule; there, --no-doctor is the way past it, and it skips
every other check with it.
What your host needs
Section titled “What your host needs”- ssh to the router as a user that can write, your own admin access. The CLI
runs the system
sshwithBatchMode=yesandConnectTimeout=15, so it cannot answer a password prompt: use a key or an ssh agent.--routertakesuser@hostor an ssh config alias;--ssh-portand--ssh-key(MIKROSCOPE_SSH_PORT,MIKROSCOPE_SSH_KEY) fall back to your ssh configuration when unset. The image goes up withscp, on the two routes that upload one. The RouterOS script route needs no ssh at all. - An agent image, by one of four routes. The CLI can build one
(
go build .from a checkout, which needs Go 1.27), take the tar the release publishes (/ cmd/ mikroscope-agent --agent-tar, no toolchain and no checkout), or let the router pull the image itself (--remote-image, nothing uploaded). The fourth route needs no CLI on your machine at all:plan --rscwrites a RouterOS script you paste into the router. Four ways to install has the commands, what each route needs and how to verify a download. - A way to reach the agent once it runs: a route to the container’s /30
through the router, the relay over the RouterOS API, or
--expose. See Reaching the agent. - A RouterOS API user, only for the relay transport,
--log-markersand the collector’s API tier. It stays on your machine; its policy is on The API user.