Motrix 服务器版(Docker)
Motrix Server 把 Motrix 下载内核和 aria2 打包成非 root、多架构的容器镜像,适合 NAS 与家庭服务器。它与桌面版共用下载内核和任务模型,通过浏览器访问。设置按服务器环境提供,不包含桌面端的启动、通知偏好和 NAT 控件。
带 tag 的正式发布会把同一个镜像推送到两个 registry:
- Docker Hub——
docker.io/motrixapp/motrix-server - GitHub Container Registry——
ghcr.io/agalwood/motrix-server
每个发布镜像都同时包含 linux/amd64 和 linux/arm64,Docker 会自动选择匹配的 manifest。不支持 32 位 ARM。
容器对外提供什么
服务器模式默认在两个端口上提供两项彼此独立的服务。两者都是 HTTP,但用途不能互换。原始 aria2 RPC 是第三个独立 endpoint,除非按本页后文显式开启,否则只监听容器 loopback。
| 地址 | 提供的服务 |
|---|---|
http://NAS_HOST:8080 | Web 界面、operator API,以及公开的 GET /healthz 探针 |
http://NAS_HOST:16801 | MDXP endpoint——单次调用 POST /mdxp、事件流 GET /mdxp/events、CLI/agent 的 device-code 配对,以及显式开启后供浏览器扩展使用的 MBP1 路由 |
Important
远程浏览器扩展使用 MDXP over MBP1,不会复用旧 beta Server 的 URL token 或 aria2 RPC token。升级现有 Server 时,请同时更新 Motrix Server 与浏览器扩展,删除扩展中旧的 Server 配置,再按新的 WS/WSS 地址重新配对。未包含远程 MBP1 路由的旧 Server 通常会在 /discovery 或 /nonce 返回 404;这不是把端口改成 8080 就能解决的问题。
开始之前
- 一台 64 位主机(
amd64或arm64),装好 Docker 和 Compose 插件。 - 在持久化存储上准备两个目录:一个存状态,一个存下载文件,分别挂载到
/data和/downloads。 - 两个目录的 owner 必须是容器运行时使用的数字 UID/GID——不做覆盖时是
1000:1000。
Warning
/data 里存放 SQLite 数据库、设置、aria2 session 与 DHT 状态、种子元数据、operator token 和已安装的插件。重建容器时如果少了这个挂载,这些数据全部丢失。/data 必须备份;/downloads 按你自己的数据策略决定。
用 Docker Compose 快速开始
直接使用仓库自带的 compose.yaml:
name: motrix
services:
server:
image: "${MOTRIX_IMAGE:-motrixapp/motrix-server:latest}"
init: true
read_only: true
user: "${MOTRIX_UID:-1000}:${MOTRIX_GID:-1000}"
security_opt:
- no-new-privileges:true
restart: unless-stopped
stop_grace_period: 2m
tmpfs:
- /tmp:rw,noexec,nosuid,size=64m,mode=1777
environment:
MOTRIX_DATA_DIR: /data
MOTRIX_TEMP_DIR: /data/tmp
MOTRIX_PLUGIN_DIR: /data/plugins
MOTRIX_DEFAULT_SAVE_DIR: /downloads
MOTRIX_ALLOWED_SAVE_DIRS: /downloads
MOTRIX_ARIA2_RPC_LISTEN_ALL: "${MOTRIX_ARIA2_RPC_LISTEN_ALL:-false}"
MOTRIX_MDXP_HOST: 0.0.0.0
MOTRIX_MDXP_PORT: 16801
MOTRIX_PUBLIC_URL: "${MOTRIX_PUBLIC_URL:-}"
MOTRIX_REMOTE_EXTENSION_ENABLED: "${MOTRIX_REMOTE_EXTENSION_ENABLED:-false}"
MOTRIX_REMOTE_EXTENSION_PUBLIC_URL: "${MOTRIX_REMOTE_EXTENSION_PUBLIC_URL:-}"
MOTRIX_ALLOW_INSECURE_OPERATOR_HTTP: "${MOTRIX_ALLOW_INSECURE_OPERATOR_HTTP:-false}"
ports:
- "${MOTRIX_WEB_BIND_IP:-${MOTRIX_BIND_IP:-0.0.0.0}}:${MOTRIX_HTTP_PORT:-8080}:8080"
- "${MOTRIX_MDXP_BIND_IP:-${MOTRIX_BIND_IP:-0.0.0.0}}:${MOTRIX_MDXP_PUBLIC_PORT:-16801}:16801"
volumes:
- ./motrix-data:/data
- ./downloads:/downloads
然后创建目录并启动服务:
mkdir -p motrix-data downloads
# 使用专用非 root 账户;以下命令使用当前账户。
export MOTRIX_UID="$(id -u)"
export MOTRIX_GID="$(id -g)"
chown "$MOTRIX_UID:$MOTRIX_GID" motrix-data downloads
export MOTRIX_PUBLIC_URL='http://nas.example.lan:8080'
docker compose pull server
docker compose up -d --wait
docker compose ps
不改 Compose 文件也能用 MOTRIX_IMAGE 选择 registry、tag 或 digest,例如 ghcr.io/agalwood/motrix-server:2.0.0,或者用 @sha256: digest 得到完全可复现的部署。:latest 这类 floating tag 在 NAS 上最省事;需要受控升级和回滚时,请用不可变的 SemVer tag 或 digest。
Caution
不要为了绕过挂载权限错误就把 runtime UID 设为 0 或开启 privileged 模式,请去修正那两个目录的 owner。启动过程会对每个需要的路径做实际写入测试,出错时会带着确切的绝对路径失败。
等价的 docker run 写法
docker run -d \
--name motrix-server \
--init \
--restart unless-stopped \
--stop-timeout 120 \
--read-only \
--tmpfs /tmp:rw,noexec,nosuid,size=64m,mode=1777 \
--security-opt no-new-privileges:true \
--user "$(id -u):$(id -g)" \
-e MOTRIX_PUBLIC_URL='http://nas.example.lan:8080' \
-e MOTRIX_MDXP_HOST=0.0.0.0 \
-p 8080:8080 \
-p 16801:16801 \
-v "$PWD/motrix-data:/data" \
-v "$PWD/downloads:/downloads" \
motrixapp/motrix-server:latest
镜像本身已经定义了 healthcheck、非 root 用户、数据路径和优雅的 SIGTERM 处理。MOTRIX_MDXP_HOST=0.0.0.0 控制的是容器内的 listener,而两个 -p 选项才决定宿主上哪些接口能访问它。
显式开启原始 aria2 RPC
aria2 引擎 RPC endpoint 与 Motrix Web/API、MDXP 是相互独立的服务,默认只在容器内的 loopback(127.0.0.1)监听。正常使用 Web、CLI 与 agent 时请保持默认值;支持 MDXP 的浏览器集成也应优先使用 MDXP,而不是原始 aria2 RPC。
只有可信的外部 aria2 RPC 客户端确实需要直连引擎时,才设置 MOTRIX_ARIA2_RPC_LISTEN_ALL=true。重启前请先在设置 → 高级 → RPC中设置非空 RPC secret,并核对 RPC 端口。RPC secret 为空时,服务器模式会拒绝在所有接口上监听。
上面的 Compose 示例会把该 opt-in 变量传入容器,但有意不发布 16800 端口。启用后,同一 Compose network 内的客户端可以连接 http://server:16800/jsonrpc。如果客户端运行在 Docker 宿主上,请把以下显式 override 保存为 compose.aria2-rpc.yaml:
services:
server:
ports:
- "127.0.0.1:16800:16800"
然后同时启用 listener 和端口发布,并重建 service:
export MOTRIX_ARIA2_RPC_LISTEN_ALL=true
docker compose -f compose.yaml -f compose.aria2-rpc.yaml up -d --wait
使用 docker run 时,请改为增加 -e MOTRIX_ARIA2_RPC_LISTEN_ALL=true 和 -p 127.0.0.1:16800:16800。如果需要从可信 LAN 访问,请把宿主侧的 127.0.0.1 换成 NAS 的具体 LAN 地址,并在宿主 firewall 中只允许所需来源。若已在 Motrix 设置中修改 RPC 端口,映射两侧也要同步修改。外部客户端必须配置相同的 RPC secret;aria2 会把它作为 token:<secret> 鉴权参数。
Warning
原始 aria2 RPC 不受 Motrix operator 鉴权和下载路径策略约束,并且没有 TLS 保护。持有该 RPC secret 基本等同于获得下载引擎控制权。切勿把它直接发布到公网;优先使用私有 Docker network、宿主 loopback、VPN 或其他带鉴权的加密 tunnel。
首次登录:operator token
首次启动时,Motrix 会以 0600 权限在 /data/operator-token 生成一个随机 operator token。重启容器或替换镜像后,这个 token 保持不变。
按上面的 bind mount 布局,在宿主上这样读取。这里用 printf 补齐行尾,兼容早期生成的、末尾没有换行的 token 文件:
printf '%s\n' "$(cat motrix-data/operator-token)"
如果使用 named volume,或者不方便直接读取宿主目录,可以从容器内读取:
docker compose exec server sh -c 'token=$(cat /data/operator-token); printf "%s\n" "$token"'
Note
某些 shell(尤其是 zsh)会在没有换行的输出末尾显示一个 %,表示上一条输出没有以换行结束。这个 % 是终端提示,不是 operator token 的一部分,不要复制到解锁输入框。上面的两条命令对新旧 token 文件都会只输出 token,并以正常换行结束。
打开 http://NAS_HOST:8080,Web 界面会显示 「解锁 Motrix」 页面,其中有一个 「Operator token」 输入框。把 token 粘贴进去,点击 「解锁」。
你也可以自己设置 MOTRIX_OPERATOR_TOKEN,但环境变量能从容器元数据里读到——单机部署用自动生成的文件更安全。
Tip
解锁失败时,请重新读取当前的 /data/operator-token。从另一套部署复制来的 token 永远不会生效。
你大概会用到的环境变量
| 变量 | 镜像默认值 | 作用 |
|---|---|---|
PORT | 8080 | 容器内 Web/API 监听端口 |
MOTRIX_DATA_DIR | /data | 状态目录,必须是可写的绝对路径 |
MOTRIX_DEFAULT_SAVE_DIR | /downloads | 新任务默认保存到哪里 |
MOTRIX_ALLOWED_SAVE_DIRS | /downloads | 以冒号分隔的绝对根目录清单,由服务端强制执行 |
MOTRIX_PUBLIC_URL | 未设置 | 交给配对客户端的、外部可访问的 Web 审批 URL |
MOTRIX_REMOTE_EXTENSION_ENABLED | false | 显式开启浏览器扩展使用的四条远程 MBP1 路由 |
MOTRIX_REMOTE_EXTENSION_PUBLIC_URL | 未设置 | 扩展中应填写的准确 WS/WSS Server 地址,可包含反向代理的基础路径 |
MOTRIX_ALLOW_INSECURE_OPERATOR_HTTP | false | 仅在可信局域网中显式允许 HTTP operator 页面;公网或不可信网络不要开启 |
MOTRIX_OPERATOR_TOKEN | 自动生成文件 | operator 凭据;不想读文件时可以自己提供 |
MOTRIX_ARIA2_RPC_LISTEN_ALL | false | 显式开启带鉴权、监听所有接口的 aria2 RPC;是否发布 16800 端口需要单独配置 |
MOTRIX_FFMPEG_PATH | 自动探测 | 你自行提供的 FFmpeg 可执行文件绝对路径 |
LOG_LEVEL | info | 输出到容器 stdout 的日志级别 |
要增加第二个下载根目录,必须同时挂载并允许它,只做一半会让任务被拒绝:
environment:
MOTRIX_ALLOWED_SAVE_DIRS: /downloads:/archive
volumes:
- /srv/archive:/archive
完整的环境变量参考——插件来源、secret seed、宿主绑定地址、MDXP listener 细节——见本页末尾链接的部署指南。
配对 CLI 与 AI agent
桌面版走的本机 socket 捷径在这里并不存在,所以远程的 motrix CLI 或 agent 需要通过 MDXP 用 device code 配对。
MOTRIX_PUBLIC_URL 就是返回给客户端的 Web 审批 URL。它没有 localhost 默认值:请把它设成其他机器实际使用的地址——用 Web 端口(或它的反向代理 URL),不要用 MDXP 端口,也不要用 localhost、127.0.0.1 或 0.0.0.0。留空不会禁用配对,但客户端拿不到可用的审批链接。
先在客户端发起配对,然后用以下两种方式之一批准:
- 在 Web 界面里——打开 设置 → 「集成」→「命令行工具」,请求会带着验证码出现在 「待审批」 里,点 「批准」(或 「拒绝」)。
- 通过 SSH——在运行中的容器里批准指定的验证码:
docker compose exec server motrix-admin pairing pending
docker compose exec server motrix-admin pairing approve ABCD-EFGH
docker compose exec server motrix-admin pairing deny ABCD-EFGH
motrix-admin 只通过容器 loopback 与运行中的服务器通信,不会输出 operator 凭据或客户端 token。它刻意不提供 approve-latest、approve-all 或远程 endpoint——你必须手动输入客户端显示的那串验证码。Web 审批仍然是正常路径,这条命令是 headless 部署下的恢复手段。
配对远程浏览器扩展(MBP1)
远程扩展配对默认关闭。最容易混淆的两个地址用途不同:
MOTRIX_PUBLIC_URL是浏览器打开的 Web 审批地址,通常使用 8080 或它的 HTTPS 反向代理地址。MOTRIX_REMOTE_EXTENSION_PUBLIC_URL是扩展设置中填写的 Server 地址,直连时通常使用 MDXP/MBP1 端口 16801,而不是 Web 端口 8080。
在可信局域网直连 NAS 时,可以显式允许 HTTP operator 页面,并使用 WS:
export MOTRIX_REMOTE_EXTENSION_ENABLED=true
export MOTRIX_REMOTE_EXTENSION_PUBLIC_URL='ws://nas.example.lan:16801'
export MOTRIX_PUBLIC_URL='http://nas.example.lan:8080'
export MOTRIX_ALLOW_INSECURE_OPERATOR_HTTP=true
docker compose up -d --wait
docker compose logs server
服务准备好后,日志会输出类似下面这一行。把其中的地址原样填入扩展,不要自行猜端口:
Motrix Extension pairing ready. Enter this Server address in the Extension: ws://nas.example.lan:16801
WS 不会被拒绝:MBP1 仍会加密业务内容并验证已配对的 Server 实例。不过 WS 缺少 TLS 对连接元数据和首次服务器身份的额外保护;HTTP operator 页面还会让 operator token、配对码、Cookie 和管理操作暴露给同一路径上的攻击者。因此这组配置只适用于你完全信任的局域网。
公网、不可信局域网或希望验证 TLS 服务器身份时,应在可信反向代理终止 TLS:
export MOTRIX_REMOTE_EXTENSION_ENABLED=true
export MOTRIX_REMOTE_EXTENSION_PUBLIC_URL='wss://motrix.example.com/bridge'
export MOTRIX_PUBLIC_URL='https://motrix.example.com'
unset MOTRIX_ALLOW_INSECURE_OPERATOR_HTTP
docker compose up -d --wait
反向代理必须把 /bridge/discovery、/bridge/nonce、/bridge/pair 和 /bridge/v1 转发到 http://127.0.0.1:16801,且不能剥掉 /bridge。同时保留 Host、Origin、Upgrade、Connection 和 Sec-WebSocket-Protocol。origin 的 8080 和 16801 端口应由防火墙挡住,只让反向代理访问。
在扩展里添加该 Server 并发起配对。Motrix Web 的 operator 界面会显示请求和八位配对码;核对浏览器与扩展身份后,把配对码输入扩展即可完成认证。若请求不是你发起的,请在 Motrix 中拒绝。配对成功后,扩展会把凭据限定在这个 Server 地址和已认证实例;更换协议、主机、端口、基础路径或 Server 实例后,都应重新配对。MBP1 v1 没有旧 token 回退或协议降级。
安全边界
普通 Web 界面可以在可信 LAN 使用 HTTP。远程浏览器扩展启用时,如果 MOTRIX_PUBLIC_URL 是 HTTP,还必须显式设置 MOTRIX_ALLOW_INSECURE_OPERATOR_HTTP=true;这是风险确认,不是额外加密。
Warning
不要以明文 HTTP 把任何一个端口暴露到公网。公网访问必须做两件事:在可信反向代理上终止 TLS,并且用防火墙保护 origin 端口——两项服务都要做。只转发 8080 不会发布 MDXP,只转发 16801 也不会提供审批界面。代理需要保留 cookie、Authorization header 和流式响应。
不要用禁用配对的方式来实现这些保护。远程 CLI 与 agent 配对始终是一项需要 operator 审批的正常流程。
容器自身默认已经加固:以非 root 用户运行、根文件系统只读、启用 no-new-privileges,并为 /tmp 挂一个小的 noexec tmpfs。请保持这些设置——不要挂载 Docker socket,也不要把整个文件系统交给容器。
与桌面版的差异
Note
Web 界面的 设置 → 「关于」 里会写明 「此 Web 版本由部署管理员负责更新。」 这里没有应用内更新按钮:升级的方式是拉取新镜像并重建容器。升级前先备份 /data、记下正在替换的 digest;跨主版本前请先读 release notes。
其他需要如实说明的差异:
- 浏览器扩展的配对链路不同。 桌面版通过 native messaging 发现本机 Motrix;Server 版默认关闭远程入口,启用后通过 MDXP over MBP1 配对。两者都需要用户批准,但凭据和信任作用域不互通。参见浏览器扩展。
- 官方镜像不含 FFmpeg。 依赖它的插件需要基于官方镜像做一层派生镜像,安装 Alpine 的
ffmpeg包,并设置MOTRIX_FFMPEG_PATH=/usr/bin/ffmpeg。 - Web 版的一键 registry 安装即将推出。 你现在可以浏览插件目录,但安装要么在界面里上传
.moext包,要么用MOTRIX_PLUGIN_INSTALL_URLS/MOTRIX_PLUGIN_IMPORT_DIRS在启动时声明来源。已安装的包、授权、配置和 secret 都持久化在/data,替换容器后仍然保留。参见插件。
除此之外——HTTP 与 BitTorrent 任务、速度限制、tracker、代理——行为都和本手册其他章节所写的一致。
NAS 平台
群晖 DSM 7 的 Container Manager 和飞牛 fnOS 都可以把 compose.yaml 作为项目导入,两者的做法是同一套:在真实存储池上创建那两个目录,把它们交给一个专用非管理员账户的数字 UID/GID,把 MOTRIX_UID / MOTRIX_GID 设成相同的数字,把 MOTRIX_PUBLIC_URL 设成其他设备实际访问的 URL,然后启动项目,等 health 状态正常后再打开 Web 界面。不要启用「高权限」,也不要让 NAS 做本地镜像 build——它应该直接拉取已发布的镜像。两个平台的逐步说明见部署指南。
接下来
- Motrix 命令行工具——安装
@motrix/cli并与这台服务器配对。 - 插件——插件能做什么,以及怎么安装。
- 疑难排解——下载不动了怎么办。
镜像签名与 provenance、tag 策略、named volume、反向代理拓扑、升级与回滚流程、/api/diagnostics、DSM 与 fnOS 的完整步骤,以及完整的环境变量表格,都在完整部署指南里。