My first post. Hi all.
I’m running containers in RAM, not to wear out FLASH, and it works well. I thought it would be neat to have a script pulling the container at boot.
- That part I didn’t get working. /system/script. Container exits with code 255
Here is my instruction:
#
Run iperf3 Container in RAM (No USB) on MikroTik hEX Refresh (RouterOS 7.20)
This guide explains how to run an **iperf3 container** on a MikroTik hEX Refresh router without using a USB stick, by leveraging **tmpfs** (RAM-based filesystem). This approach prevents flash wear and meets functional and resilience requirements.
- Make an initial configuration, connected to port 2, and remove firewall blocking other than LAN
- You must also get the container package i.e. container-7.20.arm. MikroTik · Downloads
- After this, connect port 1 (Internet) to a network providing DHCP
- Good practice is to update RouterOS & firmware. **RouterOS 7.20 or later**
- The router needs Internet acces for updates and for pulling Docker image
## Requirements.
- Functional Requirement: Run containers without adding USB memory
- Cost requirement: Reducing Opex (less parts to maintain) & Capex (Cost of USB memory)
- Resilience Requirement: Run 1M times without wearing out Flash Memory. (Using tmpfs)
- Functional requirement: 100Mbps minimum
- Security requirement: not covered here
## 1. SCP container package to the router & Enable Container Support
On your computer
scp container-7.20.5-arm.npk ``admin@192.168.5.210``:.
On router
/system reboot
After reboot:
/system device-mode update container=yes
Now power cycle the router
/system device-mode print
## 2. Create tmpfs for Container Root Directory
/disk add type=tmpfs tmpfs-max-size=64M
/file print where type=disk
# Find the name (e.g., tmp1)
# tmp1 was created
This creates a RAM-backed filesystem. We’ll use `tmp1/iperf3` as the container root directory.
## 3. Networking Setup
/interface bridge add name=containers
/interface veth add name=veth1 address=172.17.0.3/24 gateway=172.17.0.1
/interface bridge port add bridge=containers interface=veth1
/ip address add address=172.17.0.1/24 interface=containers
/ip firewall nat add action=masquerade chain=srcnat out-interface-list=WAN
/ip firewall nat add action=dst-nat chain=dstnat dst-port=5201 protocol=tcp to-addresses=172.17.0.3 to-ports=5201
/ip firewall nat add action=dst-nat chain=dstnat dst-port=5201 protocol=udp to-addresses=172.17.0.3 to-ports=5201
### Firewall Best Practices
/ip firewall filter add action=accept chain=input comment="accept established,related,untracked" connection-state=established,related,untracked
/ip firewall filter add action=drop chain=input comment="drop invalid" connection-state=invalid
/ip firewall filter add action=accept chain=input comment="accept ICMP" protocol=icmp
/ip firewall filter add action=accept chain=input comment="allow iperf3 TCP" dst-port=5201 protocol=tcp
/ip firewall filter add action=accept chain=input comment="allow iperf3 UDP" dst-port=5201 protocol=udp
## 4. Configure Container Registry
/container config set registry-url=https://registry-1.docker.io tmpdir=tmp1
## 5. Startup Script for Resilience
Create a script to recreate the container at every boot:
/system script set [find where name=recreate-iperf3-on-boot] source={
# Wait for boot stability
:delay 20s;
# Clean existing container if any
:local id [/container find where name=iperf3];
:if ([:len $id] > 0) do={
/container stop $id;
/container remove $id;
};
# Ensure clean root directory
:if ([:len [/file find where name="tmp1/iperf3"]] = 0) do={
/file add name=tmp1/iperf3 type=directory;
};
# MY EXACT MANUAL COMMAND 1
/container add name=iperf3 remote-image="johneff/armv5-iperf3:latest" interface=veth1 root-dir=tmp1/iperf3 start-on-boot=no logging=yes hostname=iperf3;
# Wait for import (like I do manually)
:delay 15s;
# MY EXACT MANUAL COMMAND 2
/container start [find where name=iperf3];
:log info "iperf3 container started successfully";
}
Schedule it at boot:
/system scheduler add name=init-iperf3 interval=0s on-event=recreate-iperf3-on-boot start-time=startup
#/system scheduler remove [find where name=init-iperf3]
## 6. Pull and Start Container
/container add name=iperf3 remote-image="johneff/armv5-iperf3:latest" interface=veth1 root-dir=tmp1/iperf3 start-on-boot=no logging=yes hostname=iperf3
/container start [find where name=iperf3]
## 7. Test iperf3
From your PC:
iperf3 -c <router-LAN-IP> -t 10
Or check port:
nc -zv <router-LAN-IP> 5201
## Network Topology Diagram
```Mermaid
graph TD
subgraph Router
A[Bridge: containers
IP: 172.17.0.1/24]
B[veth1
IP: 172.17.0.3/24]
C[Container
iperf3]
end
LAN[LAN: 192.168.x.x/24] -->|dst-nat TCP/UDP port 5201| A
A --> B
B --> C
##
Key Benefits
- No USB required → Lower cost and fewer parts
- RAM-based container → No flash wear
- Automatic recreation on boot → High resilience