How to put live MikroTik network traffic on a wall display
A MikroTik router already knows which device is using the connection. The open-source mikrotik-home-netflow-plus collector turns that into a web interface with a page built for a small always-on screen: download and upload right now, a live chart, the top devices and destinations, and a banner when something is wrong. This guide gets the collector running, picks the right URL for the screen, and puts it on a Raspberry Pi that DisplayOps keeps on it.
What you are building
Three parts, on three devices. RouterOS 7 can export a record of every connection it forwards (Traffic Flow, as NetFlow or IPFIX). mikrotik-home-netflow-plus is an open-source collector, Apache 2.0 licensed, that receives those records, names the devices and destinations, keeps history, raises alerts and serves a web interface. One of its pages, /dashboard, is a full-screen wall display: always dark, no controls, pointer hidden, updated over a WebSocket. DisplayOps keeps a Raspberry Pi on that page.
Before you start
- A MikroTik router on RouterOS 7 and a terminal on it: WinBox › New Terminal, WebFig › Terminal, or SSH.
- A Linux machine on the same network with Docker and Compose v2. A Raspberry Pi 4 or 5 is enough; the published image is built for arm64 and amd64.
- A static address or a static DHCP lease for that machine. The router will be told to send flow records to it.
- A supported Raspberry Pi with a screen, and a free DisplayOps account, for the last part.
When you are done
- A screen that shows what the connection is doing right now, second by second, and which devices are responsible.
- A banner on that screen when the router stops exporting, the collector disappears or an alert fires.
- A page that updates itself, reconnects after a network blip and reloads when the collector is upgraded.
- A Pi that DisplayOps keeps on the page, switches off at night and reboots from your desk.
| Part | What it does | What it costs |
|---|---|---|
| Router | A MikroTik on RouterOS 7. It pushes IPFIX flow records to the collector over UDP 2055 and, optionally, answers a read-only API user for live rates and names. | Two lines in a terminal. The router's own CPU cost was not measurable in the project's testing. |
| Collector | One container on any Linux machine with Docker on the same network: a Raspberry Pi 4 or 5, a mini PC, a VM on the NAS. It decodes, names, stores and serves. | A 12 MB image, well under 200 MB of RAM, 2 GB of disk by default. |
| Screen | A Raspberry Pi running DisplayOps, showing the collector's /dashboard page full screen. A 7-inch 800×480 panel on a desk or a TV on the wall. | Three screens are free. The page updates itself; the Pi needs no refresh timer. |
Step 1Turn on flow export on the router
Two lines in a RouterOS terminal turn on Traffic Flow and point it at the collector. The read-only API user is optional but worth the extra minute: it is what gives the display second-by-second rates and real device names instead of a 90-second average and MAC addresses. Replace <COLLECTOR_IP> with the Docker host's address and <ROUTER_LAN_IP> with the router's LAN address.
Send flow records to the collector
active-flow-timeout=1mis the lowest value RouterOS accepts and the one the collector expects; the default of 30 minutes would hide a long download for half an hour. FastTrack can stay on: FastTracked traffic is included in the export.RouterOS terminal /ip traffic-flow set enabled=yes active-flow-timeout=1m /ip traffic-flow target add dst-address=<COLLECTOR_IP> port=2055 version=ipfix \ src-address=<ROUTER_LAN_IP> v9-template-refresh=20 v9-template-timeout=1mAdd a read-only API user
The
flowmongroup can read and use the API, nothing else: no writes, no SSH, no WinBox, no sensitive values. The account only works from the collector's address.RouterOS terminal /user group add name=flowmon policy=read,api /user add name=flowmon group=flowmon password=<STRONG_PASSWORD> address=<COLLECTOR_IP>/32Give the API a certificate
The encrypted API service (
api-ssl, port 8729) has no certificate out of the box. A self-signed one is enough; the collector pins it on first use and refuses any other afterwards. Wait for the sign command to finish before the last line.RouterOS terminal /certificate add name=api-cert common-name=router.lan key-size=2048 days-valid=3650 \ key-usage=key-cert-sign,crl-sign,digital-signature,key-encipherment,tls-server /certificate sign api-cert /ip service set api-ssl certificate=api-cert/ip traffic-flow target printshows one target pointing at the collector, and/ip service print where name=api-sslshowsapi-cert.
The project's router setup guide explains every setting, the IPFIX fields, running without TLS on port 8728, keeping the router clock right, and how to undo it all. Once the collector is running, its Status page shows this whole script with your addresses already filled in.
Step 2Run the collector
The collector is one container from Docker Hub, built for amd64 and arm64, so nothing needs compiling. The repository's compose file uses host networking: flow packets arrive with the router's real source address and the web interface is served on port 8080 with no port mapping to maintain.
Clone and configure
On the Docker host:
shell git clone https://github.com/thedyerman/mikrotik-home-netflow-plus.git cd mikrotik-home-netflow-plus cp deploy/env.example deploy/.env && chmod 600 deploy/.envThen edit
deploy/.env. The five lines that matter:deploy/.env NFP_EXPORTERS=192.168.88.1 # the router's LAN address: packets from anywhere else are dropped NFP_ROUTER_ADDR=192.168.88.1 # same address; leave empty to run from flow records only NFP_ROUTER_USER=flowmon NFP_ROUTER_PASSWORD=<STRONG_PASSWORD> NFP_ROUTER_TLS=trueStart it
shell docker compose -f deploy/docker-compose.yml up -dCheck the Status page
Open
http://<collector>:8080and click Status.Flow export says "Last export just now", Router API says "Connected" with the router's model, and after about five minutes of traffic the flow coverage is above 95%. The indicator at the bottom of the sidebar says Live.
The sister guide, MikroTik NetFlow collector with Docker Compose, deploys the same container as a release: the router password becomes an encrypted secret, the image is pinned to its digest, and upgrades and rollback are one click without SSH. Both guides end on the same screen.
Step 3Pick the wall display URL
/dashboard is a single page for an unattended screen. It sizes itself from the screen it is on, so the plain address is right for a 7-inch panel and a 1080p TV alike. Two query options change what it shows, and a third helps you preview.
| URL | What the screen shows | Best for |
|---|---|---|
/dashboard | Everything at once: download and upload right now, a live throughput chart, top devices, top destinations, today's totals and the status strip. Fills whatever screen it is on. | A screen on a desk or within a couple of metres. |
/dashboard?rotate=true | Larger type. The lower panel cycles through top devices, top destinations and today's totals. | A screen across the room. |
/dashboard?rotate=true&interval=20 | Seconds per panel when rotating. Default 12, minimum 4. | Slower rotation for a lobby, faster for a NOC. |
/dashboard?resolution=800x480 | Lays the page out for exactly that size and scales it to fit the window. Also 1024x768, 1080p, 720p or any WIDTHxHEIGHT. | Previewing a small panel in a desktop browser. Not for the screen itself. |
Try it in a desktop browser
Open
http://<collector>:8080/dashboard?resolution=800x480to see exactly what a 7-inch panel will get, then drop theresolutionparameter and decide whether the screen needsrotate=true. Pick by viewing distance: everything at once for a desk, rotating for across the room.Use an address the Pi can reach
The collector's IP address or a name the Pi resolves, plus the port. The Pi and the collector must be on the same network or routed to each other; a guest Wi-Fi that isolates its clients will not do. Test from any machine on the Pi's network:
http://192.168.88.10:8080/dashboard?rotate=trueThe page shows a green dot and Live in the strip along the bottom.
Step 4Optional: put a password on the collector
The web interface has no login by default. If anyone other than you can reach the Docker host, set a password. The main interface then shows a login form, but /dashboard asks for the password with HTTP basic authentication instead, because a screen has nobody to fill in a form. DisplayOps stores that password encrypted on the content item and answers the prompt itself.
Set the password
Add
NFP_AUTH_PASSWORD=<long random password>todeploy/.envand run theup -dcommand again.Check it
In a private window,
/dashboardshows the browser's own username and password box (any username, this password), not the login form.Tell DisplayOps
In the next section, tick The page asks for a username and password (HTTP authentication) on the content item. Never put the password in the URL. The HTTP authentication guide explains what happens under the hood.
Put it on the screen and keep it there
A Pi and a browser will show the page once. The failures come later: the browser leaks memory for a week, the TV sleeps, the Pi loses power, the collector gets a password. DisplayOps exists for that part. The steps assume a supported Raspberry Pi and a free account. A Pi 4 or 5 is the safe choice; the wall display is a light page (text and one chart), so a Pi 3B+ copes on a best-effort basis.
Flash and pair
In the portal click + Pair a display. Under Get the image download the
.img.xzand compare the SHA-256 shown next to it. Write it with Raspberry Pi Imager (Use custom); Wi-Fi can be preloaded in the imager's settings or with thedisplayops.conffrom the same portal page, and Ethernet needs nothing. About 40 seconds after power-on the screen shows a six-character code. Enter it under Pairing code, name the screen (Network wall) and click Pair display.Add the wall display as content
Content+ New content, type Website, URL from step 3. If you did step 4, tick The page asks for a username and password (HTTP authentication) and enter any username and the collector's password. Create.
http://192.168.88.10:8080/dashboard?rotate=trueAssign it
Open the display, choose the content under Now showing and click Assign. If you pick it under Show right away while pairing, this step is already done.
The screen switches within a few seconds and the strip shows a green dot with Live.
Leave auto refresh at Never
On the display's Settings card, Auto refresh stays at Never. The page updates over a WebSocket, reconnects by itself after a network interruption and reloads when the collector is upgraded. A timed reload would only make it blink.
Screen hours, and a look from your desk
In the same card, Screen on and Screen off switch the panel off at night. Screenshot in the display's header shows what the wall shows right now; use it to confirm there is no password box and the numbers are moving.
A Slideshow can alternate the wall display with other pages, for example the collector's flow map or a Grafana board. Give the wall display at least 30 seconds per turn so the chart has time to be read.
Three screens are free on the Personal plan. From a script, the same assignment is one call with an API key from DevelopersAPI keys:
curl -X POST https://app.simpledisplayops.com/api/v1/displays/DISPLAY_ID/content \
-H "Authorization: Bearer $SDO_KEY" -H "Content-Type: application/json" \
-d '{"type":"website","url":"http://192.168.88.10:8080/dashboard?rotate=true"}'Reading the status strip
The strip along the bottom of the display is the collector's own health report, so the screen tells you when the numbers behind it are stale. For the first 20 minutes after the collector's first start, new-device and new-tunnel alerts are suppressed while it learns the network; a quiet strip on day one is normal.
| Strip | Meaning |
|---|---|
| Green dot, Live, with connection and device counts | Both data sources work: flow records are arriving and the router API is connected. |
| Delayed: flow records only | No router API is configured. Numbers are up to about a minute behind, because RouterOS cannot export an active flow more often than that. |
| Amber: Router API unreachable | The collector lost its API session with the router. Rates are delayed until it returns. |
| Amber or red banner with a title | An alert is firing: a new device, an unusual upload, scan-like behaviour, a new VPN tunnel, low flow coverage, a router reboot. The Alerts page in the main interface has the details. |
| Red: No flow records from the router | The router has stopped exporting, or its packets no longer reach the collector. |
| Red: Collector unreachable, reconnecting | The Pi cannot reach the collector. The page keeps trying by itself and recovers without a reload. |
Troubleshooting
- Blank page or "cannot be reached". The Pi cannot reach the collector. Check the address and port, and that the Pi's network (a guest Wi-Fi, another VLAN) is allowed to reach the collector's.
- Red "Collector unreachable" after it worked. The collector is down or restarting; the page recovers by itself. On the host,
docker psanddocker logs mikrotik-home-netflow-plus. - The screen shows the full web interface, not the wall display. The URL is missing
/dashboard. - Text is too small from where you sit. Add
?rotate=true. - "Today" shows dashes. The collector is older than 1.1.0. The wall display needs 1.1.0 or newer; change the image tag and run
up -dagain. - A password box on the screen. The collector has a web password and the content item has no credential ticked, or the agent is older than 0.2.2 (the Device card shows the version; screens update on their own).
- Names look like
Apple 5f:9cinstead of host names. The router API is not configured, so the collector cannot read DHCP names. Do steps 1.2 and 1.3, or rename devices on the Devices page of the main interface. - "Delayed: flow records only" although the API user exists. Open the Status page. "TLS handshake failed" means
api-sslhas no certificate; "invalid user name or password" means the password or the user's address restriction is wrong; "connection refused" means the service is disabled or restricted to other addresses. - Old layout after upgrading the collector. The page reloads itself on the first update after the restart. If it does not, Refresh page in the display's header.
- The picture is rotated or does not fill the panel. That is a display setting on the Pi (Rotation in the Settings card), not something the page controls.
Security checklist
- The collector records what every device on your network connects to. Keep it on the LAN, and behind a password if anyone else can reach the host.
- The router account has the
readandapipolicies only and works only from the collector's address. Never give the collector an administrative account. - The API session is encrypted and the certificate pinned. Without TLS the password crosses the LAN in the clear.
- The web password lives on the DisplayOps content item, encrypted, and never in the URL.
- One password per screen or group. Rotate it when a screen is retired, then update the content item and Restart player.
- The collector makes no outbound connections except to the router and a webhook you configure. Nothing in this guide opens a port to the internet.
MikroTik traffic on a wall display: questions we get
Do I need DisplayOps or Simple Docker Ops to use this?
No. Plain Docker Compose runs the collector and any browser in kiosk mode can show the wall display. The two services take over the part that goes wrong later: keeping a Raspberry Pi on the page, answering the password prompt, screen hours and remote reboots on the display side; releases, encrypted secrets, health checks and rollback on the collector side.
Which screen size works best?
The page is sized for 800×480 (the common 7-inch panel), 1024×768 and 1920×1080 and everything in between, and lays itself out from the screen it is on. Plain /dashboard is right for every size; add ?rotate=true when the screen is far away. Preview any size on a desktop with ?resolution=WIDTHxHEIGHT.
Why is the display a minute behind without the router API?
RouterOS cannot export an active flow more often than once a minute, so flow records alone always lag by 15 to 75 seconds. The read-only API user lets the collector read current rates every second or two. The strip says "Delayed" whenever that second source is missing.
Does it show traffic between two devices on my LAN?
No. Traffic switched inside the LAN never reaches the router's flow export. The display shows what crosses the router: the internet, remote sites over VPN tunnels, and traffic to the router itself. Hardware-offloaded routing on some models is invisible too; the collector's coverage figure reveals it.
Can the screen show more than the wall display?
Yes. Put the wall display in a DisplayOps slideshow with other pages, or give the collector's flow map or a device page a screen of its own. Only /dashboard is designed for an unattended display; the other pages are the normal interface and expect a mouse.
Where does the data go?
Nowhere. Everything stays in one SQLite file on the Docker host. The collector makes no outbound connections except to your router and to a webhook you configure yourself; the organisation database it uses to name destinations is baked into the image at build time.
Which versions does this apply to?
RouterOS 7 (the collector was developed against 7.20), mikrotik-home-netflow-plus 1.1.0 or newer for the wall display, and a DisplayOps agent 0.2.2 or newer if you use the stored password. The collector is Apache 2.0 licensed and independent of both MikroTik and DisplayOps.
Related
Put the network on the wall and let the screen look after itself.
Three screens free. Flash, pair, paste the URL.