Skip to content

Four ways to install

The agent is a container image, and the four routes below differ in one thing only: how that image reaches the router. Everything else install writes — the veth, the address, the two list memberships, the envlist, the container and its tag — is the same whichever route you take, and so are the prerequisites: What the router needs comes first in all four, because device-mode container=yes needs a hand on the device and no route works around it.

Route Needs Prefer it when
A registry pull — start here the router can reach Docker Hub; nothing else almost always: one command, nothing to choose, nothing uploaded
A RouterOS script a terminal on the router; --remote-image you reach the router through WinBox or WebFig and not over ssh
A checkout, with Go Go 1.27 and the repository; ssh to the router you are working on mikroscope and want the agent from your tree
The published tar the release assets, the right one for the board; ssh to the router the router cannot reach a registry

Take the first one unless something stops you. A registry pull is a single command with nothing to pick: the published image index carries every platform a MikroTik container can be, so the router matches its own and no one has to know whether the board is 64-bit ARM or one of the two 32-bit kinds. Nothing lands on the flash, and uninstall has no file to account for.

The tar is last on purpose. It is the right route for a router with no way out to a registry, and it is the only one where you pick the architecture — the way that goes wrong is an image that installs, starts and dies with exec format error in the container log. If you take it, read which tar before downloading.

The recommended route, and the shortest. One command, nothing to download, nothing uploaded:

Terminal window
mikroscope install --router user@192.168.88.1 \
--remote-image jmrplens/mikroscope-agent:1.0.4

Nothing is uploaded, no tar lands on the device, and uninstall has no file to account for: the container step becomes /container/add remote-image="jmrplens/mikroscope-agent:1.0.4" … and the plan prints the router pulls … (nothing is uploaded) where the upload line would be. The release publishes the image twice, as jmrplens/mikroscope-agent:1.0.4 on Docker Hub and as ghcr.io/jmrplens/mikroscope-agent:1.0.4 on GHCR. Both carry linux/amd64, linux/arm64, linux/arm/v7 and linux/arm/v5, and RouterOS picks the one its architecture needs — which is why this route asks nothing about the board: the two kinds of 32-bit ARM MikroTik ships are both in the index.

The reference above is the Docker Hub one, and it carries no registry host: the router pulls it from whatever /container/config registry-url already names, and RouterOS ships that setting as https://registry-1.docker.io. On a router where nobody has changed it, the command above needs nothing set first — on the RB5009 this project is measured on, that setting reads https://registry-1.docker.io. The GHCR reference is the alternative, and it needs /container/config/set registry-url=https://ghcr.io on the device first, which is a change to every container on it.

It needs two things the other routes do not: the router has to reach the registry, and it has to have room in RAM for the layers while it extracts them.

A reference with no host — jmrplens/mikroscope-agent:1.0.4 — leaves the registry to whatever the router is already configured for, and doctor then checks nothing about it. --remote-image reads its default from MIKROSCOPE_REMOTE_IMAGE, and upgrade takes it too; image refuses it, because there is no tar to write.

For a router you reach through WinBox or WebFig, or where you do not want ssh from another machine at all:

Terminal window
mikroscope plan --rsc \
--remote-image jmrplens/mikroscope-agent:1.0.4 \
--out install.rsc

The file holds the same commands install runs, in the same order, each object tagged the same way, so status and uninstall from the CLI recognise them afterwards. Read it, then paste it into the router’s terminal, or upload it and /import it. Without --out it goes to standard output. It carries its own header: the tag it writes, what to check before running it, and, at the end, /container/print where name~"mikroscope" and the /healthz URL the agent answers on.

Two caveats, both stated in the script itself:

  • It cannot upload anything. A script running on the router has no way to put the image there, so pair it with --remote-image. Without one, the header says instead which filename to put on the device first — the name the container step expects — and how to regenerate the script for a registry pull.
  • With --token, the file is a credential. The envlist line carries the token in clear, because the router needs it in clear. The CLI writes the file 0600; what you do with it afterwards is the exposure.

Nothing in the script checks anything. There is no doctor, no question about what the objects it creates would collide with, and no confirmation prompt: it writes. Run mikroscope doctor from a machine that can, or read What the router needs and check the three prerequisites by hand, before you paste it.

All four routes were run end to end against the reference RB5009UG+S+ (RouterOS 7.24.2, arm64) on 2026-09-17, one after another, each installing under its own name, veth and /30 so that nothing already on the device was touched, and each removed again before the next. In every one the agent answered /healthz from the collector host: the checkout build and the published mikroscope-agent-arm64.tar at a 2 ms round trip, the router’s own pull of jmrplens/mikroscope-agent:1.0.4 from Docker Hub at 2 ms, and the plan --rsc script — uploaded and /imported, with no CLI involved in the install itself — at 15 ms on its first samples. uninstall then verified by ownership count in each case, and the router’s /export after all four was byte-identical to the one taken before them.