MikroTik Solutions

Changes To Container Limitations
Login

Changes To Container Limitations

Changes to "Container Limitations" between 2025-05-28 18:21:46 and 2025-05-28 18:35:39

52
53
54
55
56
57
58
59

60
61
62
63
64
65
66

67
68
69
70
71

72
73

74
75

76
77

78
79

80
81
82
83

84
85

86
87

88
89

90
91

92
93

94
95
96
97
98
99
100
52
53
54
55
56
57
58

59
60
61
62
63
64
65

66
67
68
69
70

71
72

73
74

75
76

77
78

79
80
81
82

83
84

85
86

87
88

89
90

91
92

93
94
95
96
97
98
99
100







-
+






-
+




-
+

-
+

-
+

-
+

-
+



-
+

-
+

-
+

-
+

-
+

-
+








## <a id="create" name="load"></a>Container Creation

The single biggest area of difference between the likes of Docker and the RouterOS `container.npk` feature is how you create containers from [OCI] images. It combines Docker’s `create` and `load` commands under `/container/add`, the distinction expressed by whether you give it the `remote-image` or `file` option, respectively.

Given the size of the output from `docker create --help`, it should not be surprising that the bulk of that is either not available in RouterOS or exists in a very different form. Most of these limitations stem from [the list above](#global). For instance, the lack of any CPU usage limit features means there is no equivalent under `/container` for the several `docker create --cpu*` options. Rather than go into these options one by one, I’ll cover the ones where the answers cannot be gleaned through a careful reading of the rest of this article:

*   **`--env`**: The equivalent is this RouterOS command pair:
*   <a id="create-env"></a>**`--env`**: The equivalent is this RouterOS command pair:

        /container/envs/add name=NAME …
        /container/add envlist=NAME …

    This is in fact closer to the way the **`--env-file`** option works, except that under RouterOS, this particular “file” isn’t stored under `/file`!

*   **`--expose`/`--publish`**: <a id="publish"></a>The VETH you attach the container to makes every listening socket visible by default; the `EXPOSE` directive given in your `Dockerfile` is completely ignored. Everything the big-boy container engines do related to this is left up to you, the RouterOS administrator, to do manually:
*   <a id="create-expose"></a>**`--expose`/`--publish`**: <a id="publish"></a>The VETH you attach the container to makes every listening socket visible by default; the `EXPOSE` directive given in your `Dockerfile` is completely ignored. Everything the big-boy container engines do related to this is left up to you, the RouterOS administrator, to do manually:

    *   block **unwanted** services exposed within the container with `/ip/firewall/filter` rules
    *   port-forward **wanted** services in via `dstnat` rules

*   **`--health-cmd`**: Because health-checks are often implemented by periodic API calls to verify that the container continues to run properly, the logical equivalent under RouterOS is to [script] calls to [`/fetch`](https://help.mikrotik.com/docs/display/ROS/Fetch), which then issues `/container/{stop,start}` calls to remediate any problems it finds.
*   <a id="create-health-cmd"></a>**`--health-cmd`**: Because health-checks are often implemented by periodic API calls to verify that the container continues to run properly, the logical equivalent under RouterOS is to [script] calls to [`/fetch`](https://help.mikrotik.com/docs/display/ROS/Fetch), which then issues `/container/{stop,start}` calls to remediate any problems it finds.

*   **`--init`**: Although there is no direct equivalent to this in RouterOS, nothing stops you from doing it the old-school way, creating a container that calls “`ENTRYPOINT /sbin/init`” or similar, which then starts the subordinate services inside that container. It would be somewhat silly to use systemd for this in a container meant to run on RouterOS in particular; a more suitable alternative would be [Alpine’s OpenRC](https://wiki.alpinelinux.org/wiki/OpenRC) init system, a popular option for managing in-container services.
*   <a id="create-init"></a>**`--init`**: Although there is no direct equivalent to this in RouterOS, nothing stops you from doing it the old-school way, creating a container that calls “`ENTRYPOINT /sbin/init`” or similar, which then starts the subordinate services inside that container. It would be somewhat silly to use systemd for this in a container meant to run on RouterOS in particular; a more suitable alternative would be [Alpine’s OpenRC](https://wiki.alpinelinux.org/wiki/OpenRC) init system, a popular option for managing in-container services.

*   **`--label`**: The closest equivalent is RouterOS’s `comment` facility, which you can apply to a running container with “`/container/set 0 comment=MYLABEL`”.
*   <a id="create-label"></a>**`--label`**: The closest equivalent is RouterOS’s `comment` facility, which you can apply to a running container with “`/container/set 0 comment=MYLABEL`”.

*   **`--mac-address`**: If RouterOS had this, I would expect it to be offered as “`/interface/veth/set mac-address=…`”, but that does not currently exist. As it stands, a VETH interface’s MAC address is random, same as the default behavior of Docker.
*   <a id="create-mac-address"></a>**`--mac-address`**: If RouterOS had this, I would expect it to be offered as “`/interface/veth/set mac-address=…`”, but that does not currently exist. As it stands, a VETH interface’s MAC address is random, same as the default behavior of Docker.

*   **`--mount`**: The closest equivalent to this in RouterOS is quite different, being the `/container/mounts/add` mechanism. The fact that you create this ahead of instantiating the container might make you guess this to be a nearer match to a “`docker volume create …`” command, but alas, there is no container volume storage manager. In Docker-speak, RouterOS offers bind-mounts only, not separately-managed named volumes that only containers can see.
*   <a id="create-mount"></a>**`--mount`**: The closest equivalent to this in RouterOS is quite different, being the `/container/mounts/add` mechanism. The fact that you create this ahead of instantiating the container might make you guess this to be a nearer match to a “`docker volume create …`” command, but alas, there is no container volume storage manager. In Docker-speak, RouterOS offers bind-mounts only, not separately-managed named volumes that only containers can see.

    Prior to RouterOS 7.20, there was an additional limitation here: `container.npk` could bind-mount whole directories only, not single files as Docker and Podman allow. This was a particular problem when trying to inject a single file under `/etc` since the workaround was to copy the entire subdirectory out of the container, modify the one file you needed changed, and then map the whole mess back in over the top.

*   **`--network`**: This one is tricky. While there is certainly nothing like “`/container/add network=…`”, it’s fair to say the equivalent is, “RouterOS.” You are, after all, running this container atop a highly featureful network operating system. Bare-bones the `container.npk` runtime may be, but any limitations you run into with the network it attaches to are more a reflection of your imagination and skill than to lack of command options under `/container`.
*   <a id="create-network"></a>**`--network`**: This one is tricky. While there is certainly nothing like “`/container/add network=…`”, it’s fair to say the equivalent is, “RouterOS.” You are, after all, running this container atop a highly featureful network operating system. Bare-bones the `container.npk` runtime may be, but any limitations you run into with the network it attaches to are more a reflection of your imagination and skill than to lack of command options under `/container`.

*   **`--pid/uts`**: The RouterOS container runner must use Linux namespaces under the hood, but it does not offer you control over which PID, file, network, user, etc. namespaces each container uses. See also [this](#root).
*   <a id="create-pid"></a>**`--pid/uts`**: The RouterOS container runner must use Linux namespaces under the hood, but it does not offer you control over which PID, file, network, user, etc. namespaces each container uses. See also [this](#root).

*   **`--read-only`**: RouterOS offers precious little in terms of file system permission adjustment. As a rule, it is best to either shell into the container and adjust permissions there or rebuild the container with the permissions you want from go. Any expectations based on being able to adjust any of this between image download time and container creation time are likely to founder.
*   <a id="create-read-only"></a>**`--read-only`**: RouterOS offers precious little in terms of file system permission adjustment. As a rule, it is best to either shell into the container and adjust permissions there or rebuild the container with the permissions you want from go. Any expectations based on being able to adjust any of this between image download time and container creation time are likely to founder.

*   **`--restart`**: <a id="restart"></a>The closest RouterOS gets to this is its `start-on-boot` setting, meaning you’d have to reboot the router to get the container to restart. If you want automatic restarts, you will have to [script] it.
*   <a id="create-restart"></a>**`--restart`**: <a id="restart"></a>The closest RouterOS gets to this is its `start-on-boot` setting, meaning you’d have to reboot the router to get the container to restart. If you want automatic restarts, you will have to [script] it.

*   **`--rm`**: No direct equivalent, and until we get a `run` command and an image cache, it’s difficult to justify adding it.(^There is a manual `/container/remove` command, but it does something rather different.)
*   <a id="create-rm"></a>**`--rm`**: No direct equivalent, and until we get a `run` command and an image cache, it’s difficult to justify adding it.(^There is a manual `/container/remove` command, but it does something rather different.)

*   **`--volume`**: This is largely covered under `--mount` above, but it’s worth repeating that `container.npk` has no concept of what Docker calls “volumes;” it _only_ has bind-mounts. In that sense, RouterOS does not blur lines as Docker and Podman attempt to do in their handling of the `--volume` option.
*   <a id="create-volume"></a>**`--volume`**: This is largely covered under `--mount` above, but it’s worth repeating that `container.npk` has no concept of what Docker calls “volumes;” it _only_ has bind-mounts. In that sense, RouterOS does not blur lines as Docker and Podman attempt to do in their handling of the `--volume` option.

That brings us to the related matter of…

[script]: https://help.mikrotik.com/docs/display/ROS/Scripting


# <a id="run"></a>There Is No “Run”