Apps
Apps 菜单提供可通过容器部署的预配置应用目录,支持自动配置 RouterOS 并兼容多个容器注册表,需要 Container 软件包。
Apps
摘要
子菜单: /app
所需软件包: container
App 菜单提供可通过几次点击部署的应用目录。每个应用可以由一个或多个预配置容器组成,并会自动应用必要的 RouterOS 配置,例如防火墙规则和地址转换。该目录由 MikroTik 准备和维护,但容器镜像来自多个注册表,例如 Docker Hub、GCR 和 Quay。
不过,配置参数可以在启用应用之前编辑,并且可以随时查看应用的 yaml 文件。
要求
App 系统继承与 Container 软件包相同的要求:
- 架构支持: arm64 和 x86 架构。
- Container 软件包: 必须已安装。
- 设备模式: 必须启用容器模式(需要物理接触并重置设备)。
- 外部存储: 强烈建议使用,以获得最佳性能。
- 内存要求: 容器运行需要足够的 RAM(16MB SPI 闪存设备可能需要外部存储来存放镜像)。
- 架构限制: 不支持采用 EN7562CT CPU 的设备(例如 hEX Refresh)。
安全注意事项
与底层 Container 系统一样,App 菜单也继承相关安全影响:
- 首次启用容器支持需要物理接触。
- 启用后,可以远程管理容器。
- 设备被攻破后,可能利用容器安装恶意软件。
- 设备安全性与运行容器的安全性等同。
- 第三方容器镜像可能引入安全漏洞。
属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| auto-update | yes | no | no | 在有新的容器镜像版本可用时启用或禁用自动更新。 |
| check-certificate | yes | no | yes | 拉取容器镜像前,根据路由器的证书存储验证注册表证书。 |
| container-command-lines | string | (空) | 指定启动容器时传递给应用程序的命令行参数。 |
| devices | string | (空) | 指定要透传给容器应用的附加硬件设备。 |
| environment | string | (空) | 定义运行中应用可用的环境变量。以键值对列表形式指定。 |
| extra-mounts | string | (空) | 指定要附加到容器的其他挂载点。 |
| firewall-redirects | string | (空) | 配置从主机设备到容器的端口重定向。 |
| network | default | lan | internal | default | 指定容器使用的网络:internal(NAT 之后)、lan(LAN 网络上)或 default(因应用而异;可以是 internal 或 lan)。 |
| network-outgoing-access | yes | no | yes | 允许特定容器应用访问外部网络;设置为 no 时会创建 mangle 丢弃规则。 |
| pvid | integer | 1 | 设置网桥中容器虚拟以太网接口的端口 VLAN ID(PVID)。 |
| required-hw-devices | string | (空) | 容器启动时主机上必须存在的硬件设备。仅在添加 YAML 配置后才可以配置此属性。Compose 格式:[host-hw-device]:[device-in-app] |
| required-mounts | string | (空) | 容器启动所需的挂载目录。仅在添加 YAML 配置后才可以配置此属性。Compose 格式:[dir-on-host]:[dir-in-app] |
| use-https | yes | no | yes | 为应用 URL 使用 HTTPS。此选项在不支持云服务的设备上不会生效。 |
| yaml | string | (空) | 提供应用的 YAML 组合。配置示例请参阅文档。 |
只读属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| app-size | 应用的总大小。 | ||
| app-store-url | string | 安装该应用的应用商店 URL。 | |
| cpu-usage | 应用当前占用的 CPU 百分比。 | ||
| custom | yes | no | 指示该应用是否为用户创建的自定义应用。 | |
| data-size | 应用存储的数据大小。 | ||
| default-credential | string | 应用所需的默认凭据。 | |
| default-network | lan | internal | 应用使用的默认网络。有效值为 lan 或 internal。 | |
| description | string | YAML 配置 descr 参数中定义的应用描述。 | |
| from-app-store | yes | no | 指示该应用是否从自定义应用商店安装。 | |
| interface | string | 应用使用的 VETH 接口。 | |
| ip-address | IP | 分配给 VETH 接口的 IP 地址。 | |
| memory-current | 应用当前使用的内存量。 | ||
| name | string | YAML 配置 name 参数中定义的应用名称。 | |
| project-page | string | YAML 配置 page 参数中定义的应用项目页面 URL。 | |
| running | 指示应用当前是否正在运行。 | ||
| status | acquire veth | configuring container(s) | downloading/extracting | starting | 应用的当前状态。可能的值表示应用正在获取 VETH 接口、配置容器、下载/解压或启动。 | |
| ui-url | string | 为应用 Web 界面生成的 URL(如果可用)。 | |
| variables-to-be-used-in-environment | 应用环境中存在的所有变量列表。 |
设置向导
App 菜单包含设置向导(GUI 中的 "Setup" 按钮,或命令 /app/setup)。该向导会自动完成原本需要多个手动步骤的网络、存储和注册表设置。
步骤 1:选择存储
选择用于安装应用的存储磁盘。系统会自动检测可用的已格式化磁盘驱动器(例如 nvme1、usb1、disk1 及类似设备)。如果列表中没有合适的磁盘,必须先用 ext4 或 btrfs 文件系统格式化磁盘,然后通过 /disk 菜单挂载它。
要求:
- 建议顺序读/写速度至少为 100 MB/s。
- 建议随机 IOPS(每秒输入/输出操作数)至少为 10,000。
- 继续操作前,使用
/disk/test命令验证存储性能。 - 强烈建议使用外部存储设备以获得最佳性能。
步骤 2:配置网桥
选择用于容器网络的 LAN 网桥接口。此配置可在本地网络上启用自动端口转发和应用自动发现。设置向导会自动配置以下内容:
- 创建虚拟以太网(veth)接口
- 将 veth 接口添加到已配置的网桥
- 出站连接的 NAT 规则
步骤 3:配置 IP
定义路由器的 IP 地址以启用应用访问。系统会自动检测主 IP 地址;但复杂网络设置支持手动配置。指定的 IP 地址用于:
- 生成应用 UI URL。
- 创建自动端口转发规则。
- 提供 WebFig 集成链接。
完成
完成设置向导后,App 系统即可立即使用。您可以直接通过界面启用应用。系统会自动处理所有底层容器配置。
配置
应用配置可通过 /app/settings 访问,与手动 Container 配置相比提供了更简化的设置。
属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| app-store-urls | string | (空) | 自定义应用商店 URL。该 URL 必须指向一个 YAML 数组,其中每个应用是数组中的一个元素。 |
| auto-update | yes | no | no | 为所有已安装应用包启用自动更新的全局设置。 |
| disk | string | (空) | 指定用于存储操作的磁盘的全局设置。 |
| download-path | string | (空) | 手动指定存储所有下载内容的目录路径。 |
| lan-bridge | string | (空) | 手动指定代表局域网(LAN)的网桥接口。 |
| media-path | string | (空) | 手动指定存储所有媒体文件的目录路径。 |
| registry-mirrors | string | (空) | 指定一个或多个用于获取容器镜像的注册表镜像 URL 地址。 |
| router-ip | IP | (空) | 手动指定可访问当前 RouterOS 设备的 IP 地址。 |
| show-in-webfig | yes | no | yes | 控制是否在 WebFig 登录页面显示已启用应用的链接。 |
自动配置的设置
某些参数最初会根据网络检测自动配置。如有需要,这些值始终可以手动覆盖。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| assumed-router-ip | IP | (检测值) | 自动检测到的 RouterOS 设备网络 IP 地址。 |
| assumed-lan-bridge | string | (检测值) | 自动检测到的用于 LAN 连接的网桥接口。 |
| assumed-media-path | string | disk/media | 默认媒体存储路径,通常位于系统磁盘上。 |
| assumed-download-path | string | disk/media/downloads | 默认下载目录路径,通常位于媒体存储区域内。 |
应用管理
应用通过 /app 接口管理,提供与底层 /container 系统类似的状态监控和生命周期控制:
/app> print
Flags: X - DISABLED, R - RUNNING
Columns: NAME, UI-URL, MEMORY-CURRENT, APP-SIZE, DATA-SIZE, CATEGORY, DESCRIPTION
状态指示符和元数据
- 标志:
- X(DISABLED)- 可以表示两种状态:未下载/安装(APP-SIZE 和 DATA-SIZE 为空),或已下载但已禁用(APP-SIZE 和 DATA-SIZE 显示存储使用量)。
- R(RUNNING)- 应用正在运行且可访问。
- UI-URL: 应用运行时可直接访问的 Web 界面 URL。
- MEMORY-CURRENT: 实时内存消耗,单位为 MiB(仅运行时显示)。
- APP-SIZE: 容器镜像存储消耗,单位为 MiB(下载后显示已用空间)。
- DATA-SIZE: 应用持久数据大小,单位为 KiB/MiB(显示配置和用户数据)。
- CATEGORY: 应用功能分类。
- DESCRIPTION: 应用功能描述。
应用生命周期管理
部署过程
手动部署 Container 需要多个配置步骤(veth 接口、网桥设置、环境变量、挂载和防火墙规则),而 App 部署会自动完成整个过程:
- 选择: 通过 CLI 或 WebFig 从目录中选择应用。
- 下载: 自动下载并解压容器镜像。
- 网络设置: 自动配置 veth 接口和网桥。
- 端口转发: 自动创建用于 Web 访问的防火墙规则。
- 启动: 使用预配置设置初始化容器。
- 访问: UI-URL 可用后即可立即访问 Web 界面。
清理命令
清理命令会彻底移除应用,包括所有关联数据。此操作具有破坏性且不可逆:
/app> cleanup pihole
App data will be lost, continue? [y/N]:
清理过程:
- 停止正在运行的容器。
- 移除所有应用数据和配置文件。
- 从存储中删除容器镜像。
- 将应用重置为未安装状态(APP-SIZE 和 DATA-SIZE 为空)。
- 移除该应用专用的网络配置。
警告
所有用户数据、配置设置和应用状态都将永久丢失。应用将恢复到目录中的原始状态,清理后需要重新进行完整配置。
自定义应用
从 RouterOS v7.22 开始,您可以使用 'compose' YAML 文件创建自己的自定义应用。这让有经验的用户能够构建适合其特定网络需求的解决方案。
工作原理:
- 使用 YAML 格式定义应用内部结构和有限的 RouterOS 配置
- RouterOS 拉取指定的镜像并创建您的应用
- 应用在 RouterOS 硬件上运行,无需额外成本即可提供新功能
- 可选地,使其与我们的 API 交互
使用理由:
- 精确构建网络所需的功能
- 无需等待官方应用发布
- 非常适合自动化、自定义路由或专用服务
- 声明式设置使管理更容易
如何添加应用
有三种方式,但都依赖 YAML。
方式 1:创建空白应用并编辑 YAML
首先,创建应用并将其分配到 LAN 网络:
/app/add network=lan
默认情况下,应用将命名为 "app"。
接下来,添加 YAML 配置。在终端中运行:
/app/edit app yaml
这会打开一个文本编辑器,您可以在其中粘贴 YAML。粘贴后,按 <kbd>Control</kbd>+<kbd>O</kbd> 保存更改。最后,启用应用以启动它。
方式 2:从文件导入
或者,将 compose 文本保存到文件并上传到设备。然后,使用以下命令将该文件设置为应用的 YAML:
/app/add yaml=[/file/get alpine-iperf.yml contents]
当您有准备好导入的预配置 YAML 文件时,此方法很有用。
方式 3:添加自定义应用商店 URL
如果您或您认识的人在 Web 服务器上托管了自己的应用或应用列表,只需将 URL 添加到 APP 设置中即可。这样就可以拥有动态更新的自定义应用目录。
/app/settings set app-store-urls="<custom_url>"
要使其正常工作,该 URL 应直接返回 YAML 文件的文本内容,其中多个应用按照标准 YAML 语法列在一个简单列表中。
为自定义应用编写 YAML
此示例使用现有的 openEuler 基础镜像创建 iperf3 应用。
name: openeuler-iperf
descr: openEuler container running iperf3 server
page: https://iperf.fr/
category: networking
default-credentials: none
services:
iperf:
image: docker.io/openeuler/iperf:latest
ports:
- 5201:5201:tcp
- 5201:5201/udp:udp
command: /bin/sh -c "iperf3 -s"
关键区别:
- 基础镜像已安装 iperf
- 必要端口被转发/映射到路由器 IP
- 'command' 在容器启动时执行并运行 iperf3
或者,您可以使用 Alpine Linux 等普通基础镜像,并通过 'command' 安装 iperf3。
name: alpine-iperf
descr: Alpine Linux container running iperf3 server
page: https://iperf.fr/
category: networking
default-credentials: none
services:
iperf:
image: docker.io/alpine:latest
command: /bin/sh -c "apk add --no-cache iperf3 && iperf3 -s"
networks:
default:
name: lan
external: true
关键区别:
- 干净的基础镜像
- 每次启动时安装并运行 iperf3
- 应用网络设置为您的 LAN(端口转发的替代方案)
此外,如果希望确保 'command' 只执行一次某些操作,可以考虑使用如下条件单行命令:
command: /bin/sh -c "if ! command -v iperf3 >/dev/null 2>&1; then apk add --no-cache iperf3; fi; exec iperf3 -s"
端口映射
映射端口时,使用 X:Y 或 X:Y:Z 语法,其中 X 是路由器上的端口,Y 是容器上的端口,Z 是端口名称;不过某些名称具有特殊功能,例如 'web' 会使 RouterOS 设置反向代理并生成自动 URL。 以下是一些有效示例:
2211:21
888:80:web
9000:9000:api
9001:9001:api-secure
默认情况下,所有端口都设置为 TCP,除非将它们定义为 UDP,如下所示:
6000:6000/udp:udp
8000:8000/udp:custom_name
警告
默认情况下,端口
80被视为 Web 端口,除非明确将其设置为其他类型。有一个健康检查会探测此端口 - 如果没有监听,应用会看起来卡在starting状态。当未映射端口80时,将使用第一个定义的端口。为避免歧义,请明确命名使用的端口。
YAML 字段参考
YAML 文档定义一个 App:包含 App 元数据的应用级部分,以及包含一个或多个容器定义的 services 部分。
应用级字段
| 字段 | 类型 | 说明 |
|---|---|---|
name | string | App 的唯一名称。 |
descr | string | 应用描述。 |
page | string | 项目页面 URL,显示为 App 的 project-page 属性。 |
category | string | App 列表中显示的分类组(例如 network、system、utilities)。 |
default-credentials | string | 采用 username:password 格式的登录凭据。仅供参考;可以留空。 |
icon | string | 在 WebFig 登录页面显示的图标图像 URL。 |
url-path | string | 附加到 App URL 的路径,例如 /login 或 /web。 |
auto-update | boolean | 当为 true 时,有新容器镜像可用时自动更新 App。 |
supported-archs | string 列表 | App 支持的 CPU 架构:arm、arm64、arm_v5 和 x86。不匹配指定架构的设备不会显示该应用。 |
compatible-boards | string 列表 | App 支持的板卡名称,例如 RDS2216。接受 * 通配符。不匹配指定板卡名称的设备不会显示该应用。 |
services | map | 容器服务定义。至少需要一个服务。 |
volumes | map | 服务使用的命名卷声明。 |
secrets | map | App 的机密名称,在 environment 中通过 [secret:name] 引用。 |
configs | map | 挂载到服务中的配置文件声明。 |
networks | map | 服务使用的网络声明。 |
服务字段
| 字段 | 类型 | 说明 |
|---|---|---|
image | string | 容器使用的 App 镜像。必需。 |
container_name | string | 与特定镜像一起使用的名称,如 /container 菜单中所示。 |
command | string | 在容器内执行的启动命令。 |
entrypoint | string | 用作容器入口点的可执行文件。 |
environment | 列表或 map | 传递给容器的环境变量。 |
volumes | 列表 | 附加到容器的挂载点。 |
ports | 列表 | 从路由器到容器的端口映射。 |
expose | 列表 | 向其他容器暴露但不在路由器上发布的端口。 |
restart | string | 容器的重启策略。unless-stopped、always 和 on-failure。 |
depends_on | 列表 | 必须在此服务之前启动的服务名称。 |
healthcheck | map | 容器启动时运行健康检查。参见下方示例。 |
shm_size | string | 共享内存大小,例如 512mb 或 1gb。 |
stop_grace_period | string 或 int | 优雅关闭的超时时间,例如 30s 或 0。默认 30 秒。 |
devices | 列表 | 透传给容器的硬件设备,例如 - /dev/ttyACM0:/dev/ttyACM0。 |
user | string | 容器运行使用的 Linux 用户或 UID。 |
hostname | string | 在容器中设置的主机名。 |
security_opt | 列表 | 容器安全选项。 |
build | map | 本地构建镜像的构建配置。 |
secrets | 列表 | 此服务可用的机密名称,作为文件挂载到 /run/secrets/<name>。 |
configs | 列表 | 挂载到此服务中的配置文件。 |
健康检查
健康检查会探测服务以验证应用是否正常运行。'test' 参数在容器内运行,当命令返回退出码 0 时,服务被视为健康:
healthcheck:
test: ["CMD", "curl -f http://localhost:8080/ || exit 1"]
interval: 30s
retries: 3
start_period: 30s
timeout: 10s
运行时占位符
环境变量值和 default-credentials 字段可以包含占位符,RouterOS 会在 App 运行时替换它们。
| 占位符 | 说明 |
|---|---|
[accessIP] | 用于从外部访问 App 的 IP 地址或主机名。 |
[accessPort] | 映射到 App Web 界面的路由器端口。 |
[accessProto] | 用于访问 App 的协议,http 或 https。 |
[containerIP] | 分配给容器的 IP 地址。 |
[containerInterface] | 为 App 创建的 VETH 接口名称。 |
[routerIP] | 路由器在 App 网络上的 IP 地址。 |
[env:variable] | App 的环境变量值。 |
[env:service:variable] | 特定服务的环境变量值。 |
[secret:name] | 应用级 secrets 部分声明的机密值。 |
在环境值中使用占位符可自动配置服务:
environment:
- NEXTCLOUD_TRUSTED_DOMAINS=[accessIP]
- APP_URL=[accessProto]://[accessIP]:[accessPort]
卷
为服务添加持久数据:
services:
app:
image: docker.io/example/app:latest
volumes:
- data:/data # persistent directory in the App storage
- appdata/conf:/etc/app # sub-directory, mounted at /etc/app
- ./custom:/custom # relative to the storage path
机密
机密将密码和密钥与环境分开存储。在应用级 secrets 部分声明机密,并在环境值和 default-credentials 中使用 [secret:name] 引用它们。RouterOS 会在 App 运行时生成机密值:
secrets:
db_password:
admin_password:
services:
db:
image: docker.io/postgres:17
environment:
POSTGRES_PASSWORD: "[secret:db_password]"
server:
image: docker.io/example/server:latest
environment:
ADMIN_PASSWORD: "[secret:admin_password]"
或者,在服务下列出机密,将其作为文件挂载到 /run/secrets/<name>:
services:
server:
image: docker.io/example/server:latest
environment:
DB_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
配置
配置以文本形式向容器提供配置文件。在应用级 configs 部分声明内容,并使用 source、target 和可选的 mode 将其挂载到服务中。
configs:
mosquitto_conf:
content: |
listener 1883
allow_anonymous true
services:
mosquitto:
image: docker.io/eclipse-mosquitto:latest
configs:
- source: mosquitto_conf
target: /mosquitto/config/mosquitto.conf
mode: 0644
source 是应用级配置声明的名称,target 是容器内的路径,mode 是文件权限。
网络
默认情况下,App 在 NAT 之后的内部网络上运行,服务通过映射端口访问。要将 App 直接放在某个网络上,请在应用级 networks 部分使用外部网络定义默认网络。
networks:
default:
name: lan
external: true
自定义应用商店
App 系统支持以 YAML 数组形式提供的自定义应用商店,数组中的每个元素都是一个应用定义。该文件必须托管在设备可以通过网络访问的服务器上。
包含两个应用的 YAML 数组示例:
- name: code-server-xxx
descr: Code-server is VS Code running on a remote server, accessible through the browser.
page: https://coder.com
category: development
icon: https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/code-server-logo.png
default-credentials: <no_username>:password
services:
code-server:
image: lscr.io/linuxserver/code-server:latest
container_name: code-server
user: "0:0"
environment:
PUID: 0
PGID: 0
PASSWORD: password
PWA_APPNAME: code-server
volumes:
- config:/config
- media:/data/media
ports:
- 8443:8443:web
- name: code-server-yyy
descr: Code-server is VS Code running on a remote server, accessible through the browser.
page: https://coder.com
category: development
icon: https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/code-server-logo.png
default-credentials: <no_username>:password
services:
code-server:
image: lscr.io/linuxserver/code-server:latest
container_name: code-server
user: "0:0"
environment:
PUID: 0
PGID: 0
PASSWORD: password
PWA_APPNAME: code-server
volumes:
- config:/config
- media:/data/media
ports:
- 8443:8443:web
提示和最佳实践
-
存储: 为获得最佳性能和更大容量,请考虑使用外部存储设备,例如 USB 驱动器、SATA 驱动器或 NVMe SSD。
-
内存: 在终端中运行
/app/print命令,持续关注应用的内存消耗。 -
更新: 仅在需要且认为必要时更新系统。自动更新可以提供安全补丁和新功能,但在启用或应用更新之前,请评估您的具体用例是否需要更新。
-
网络: 应用会自动管理端口转发并生成用于外部访问的必要 URL。
-
数据持久性: 应用数据存储在指定的存储路径中,即使应用重启或系统重启也会保持完整。