mihomo Docker 部署:固定镜像、端口映射与节点不显示排错
简答:如果你要在 Docker 中部署 Mihomo,先固定镜像版本或 digest,默认只把代理端口、API 和面板绑定到宿主机 127.0.0.1,先不启用 TUN。本文以 2026-10-31 可核验的 daitcl/mihomo:v1.19.33 为示例,但该镜像的环境变量、目录和面板能力属于项目实现,不等于 Mihomo 核心的通用配置。本文不覆盖公网开放控制 API、完整透明代理路由和多客户端混合部署。
定义:mihomo Docker 是把 Mihomo 核心放进 Docker 容器运行,并通过镜像参数、卷挂载、端口映射和配置文件管理代理入口、订阅、控制 API 与可选面板。
先试这一步:固定镜像、检查架构,再启动最小 Compose
本文使用 daitcl/mihomo 项目作为带面板的集成镜像示例。项目 README 声明该镜像集成 Mihomo 与 Metacubexd,并列出 SUBSCRIBE_URL、SUBSCRIBE_NAME、CLASH_SECRET、配置挂载目录和端口。下面只把这些能力归因于该项目,不把它们写成 Mihomo 核心的通用变量。
截至 2026-10-31,该项目 GHCR 页面显示 v1.19.33,摘要为 sha256:a865f13a9c06798b90efd271077e3c7a896a778a87ec3a1f7de52df9a6e75208。这是本次核验页面显示的版本与摘要,不代表页面未来不会变化;使用前仍应重新打开容器包页面确认。
- 确认 Docker 和 Compose 可用:
docker version、docker compose version。 - 查看主机架构:
uname -m。 - 检查镜像平台清单:
docker buildx imagetools inspect ghcr.io/daitcl/mihomo:v1.19.33。
Docker 文档说明,imagetools inspect用于查看注册表中的镜像详情和平台清单。若输出中没有与你主机匹配的平台,不要直接改用 latest;应先选择已确认支持的平台,或自行构建并承担维护。
停止条件:架构不匹配、Docker 版本异常或镜像无法拉取时,先不要创建容器。端口、订阅和 TUN 都应在镜像能够正常启动后再逐项处理。
最小 Compose:配置目录、订阅变量和本机端口绑定
先创建工作目录:
mkdir -p mihomo/clash-config mihomo/metacubexd-config
cd mihomo下面的示例使用固定 tag 和 digest,宿主机端口默认只绑定到 127.0.0.1。Docker Compose 的端口格式是“宿主机端口:容器端口”;如果省略宿主机 IP,Docker 可能绑定到所有网卡。Docker Compose 服务文档对此有明确说明。
请把订阅地址写入本地 .env,不要将真实订阅链接提交到公开仓库:
cat > .env <<'EOF'
SUBSCRIBE_URL=https://example.invalid/replace-with-your-subscription
SUBSCRIBE_NAME=default
CLASH_SECRET=replace-with-a-long-random-secret
EOF创建 compose.yaml:
services:
mihomo:
container_name: mihomo
image: ghcr.io/daitcl/mihomo:v1.19.33@sha256:a865f13a9c06798b90efd271077e3c7a896a778a87ec3a1f7de52df9a6e75208
restart: unless-stopped
env_file:
- .env
environment:
TZ: Asia/Shanghai
LOG_LEVEL: info
ports:
- "127.0.0.1:7890:7890"
- "127.0.0.1:7891:7891"
- "127.0.0.1:7892:7892"
- "127.0.0.1:9090:9090"
- "127.0.0.1:8080:8080"
volumes:
- ./clash-config:/root/.config/mihomo
- ./metacubexd-config:/config/caddy项目 README 和仓库 Compose 文件将 ./clash-config 挂载到容器内的 /root/.config/mihomo,将 ./metacubexd-config 挂载到 /config/caddy,并列出上述环境变量。由于这些文件位于项目的可变分支,发布时应按本次核验日期复查,不要把路径推广到其他镜像。项目 Compose 文件
先执行:
docker compose config
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=100 mihomo验证条件:容器处于运行状态,日志没有明显的配置解析、端口占用或订阅初始化错误。本文故意没有加入 Compose healthcheck,因为项目示例依赖容器内的 curl 和 9090 根路径响应;当前资料不足以把这两点推广为所有镜像的通用健康检查条件。
端口用途对照:容器端口、宿主机端口和安全边界
以下端口角色来自本文所选项目的 README,不代表其他 Mihomo 镜像或手写配置一定相同。Mihomo 官方文档也说明,实际入口取决于配置中的 port、socks-port、mixed-port、监听器和 TUN 设置。Mihomo 入站配置文档
| 容器端口 | 项目说明 | 本文宿主机绑定 | 适用镜像或配置 | 验证边界 |
|---|---|---|---|---|
| 7890 | HTTP 代理 | 127.0.0.1:7890 | daitcl/mihomo 项目示例 | 端口可连接不代表代理请求成功 |
| 7891 | SOCKS5 代理 | 127.0.0.1:7891 | daitcl/mihomo 项目示例 | 应使用 SOCKS5 请求单独验证 |
| 7892 | 混合代理 | 127.0.0.1:7892 | daitcl/mihomo 项目示例 | 具体协议支持以运行配置为准 |
| 7893 | TPROXY | 不发布 | 需要对应透明代理配置 | 未启用透明代理时不应盲目开放 |
| 7894 | REDIR | 不发布 | 需要对应透明代理配置 | 端口监听不等于系统流量已接管 |
| 9090 | Clash 外部控制 API | 127.0.0.1:9090 | daitcl/mihomo 项目示例 | API 有响应不代表代理出站正常 |
| 8080 | Metacubexd Web UI | 127.0.0.1:8080 | daitcl/mihomo 项目示例 | 浏览器能打开不代表订阅已成功 |
Mihomo 文档将 external-controller定义为 REST API 监听地址,并说明将监听地址改为 0.0.0.0会监听所有 IP;同时,secret用于 API 访问密钥。默认情况下,本文不在宿主机公网发布 9090 或 8080。Mihomo 通用配置文档
如果需要从本地电脑访问远程 VPS 上的面板,可以使用 SSH 隧道:
ssh -N -L 8080:127.0.0.1:8080 -L 9090:127.0.0.1:9090 user@your-server隧道建立后,在本地浏览器访问 http://127.0.0.1:8080。这不会改变容器端口的公网暴露范围。若必须开放局域网访问,只修改面板端口的宿主机绑定地址,并用防火墙限制来源;不要为了远程面板而无条件开放控制 API。
订阅、config.yaml 与节点不显示:按文件和日志分层检查
在本文示例中,宿主机的 clash-config对应容器内的 /root/.config/mihomo。项目 README 声明该目录用于 Mihomo 配置和订阅,并说明首次为空目录时会生成配置;同时声明 SUBSCRIBE_URL用于生成 proxy-providers。这些是该集成镜像的启动脚本行为,不是 Mihomo 核心仅凭环境变量就会自动完成的功能。项目 README
- 确认 Compose 实际展开的变量:
docker compose config。若输出仍有example.invalid或占位字符串,先停止。 - 确认挂载源和目标:
docker inspect mihomo --format='{{json .Mounts}}'。 - 查看宿主机配置目录:
find ./clash-config -maxdepth 3 -type f -print。 - 查看日志中的订阅和配置关键词:
docker compose logs mihomo | grep -Ei 'subscribe|provider|config|error|failed'。 - 查看容器内目录:
docker compose exec mihomo sh -c 'ls -la /root/.config/mihomo'。若镜像没有sh,改用docker inspect和宿主机挂载目录检查,不要把进入容器的命令当成通用能力。
如果 provider 文件没有出现,优先检查订阅地址是否完整、容器是否能访问该地址、宿主机目录是否可写,以及订阅返回内容是否为空。若 provider 已生成但面板没有节点,再检查 9090 API、面板连接地址和密钥。不要仅凭 8080 页面能打开就判断订阅有效。
停止条件:配置文件解析失败、目录挂载错误或订阅下载失败时,先恢复上一份配置,不要同时启用 TUN、host 网络和自定义 DNS,否则会增加定位变量。
代理出站验证:容器状态、API、HTTP 和 SOCKS5 分开测
建议按以下顺序验证,每一步都有不同边界:
- 查看容器状态:
这只能说明容器进程是否运行。docker compose ps - 查看 Mihomo 版本 API:
Mihomo API 文档列出curl --connect-timeout 5 -i http://127.0.0.1:9090/version/version为获取运行版本的接口;若设置了 API 密钥,应按当前 API 认证方式附带密钥。Mihomo API 文档 - 测试 HTTP 代理:
curl --connect-timeout 5 --max-time 15 --proxy http://127.0.0.1:7890 https://example.com/ - 测试 SOCKS5:
curl --connect-timeout 5 --max-time 15 --proxy socks5h://127.0.0.1:7891 https://example.com/ - 执行直连对比:去掉
--proxy,在相近时间访问同一测试地址。
example.com这里只是可替换的连通性测试地址,不是对任何目标站点可达性的承诺。如果测试地址本身不可访问,应换成你确认可访问的地址。API 失败时优先检查端口映射、监听地址和密钥;API 正常但代理请求失败时,再检查订阅、DNS、出站线路和日志。一次请求成功不能证明长期延迟、丢包或速度表现。
TUN 只是后置扩展:权限检查、完整配置边界与回滚
本文不提供完整的透明代理路由教程。若你只需要让单个应用使用 HTTP 或 SOCKS5 代理,可以先不启用 TUN。只有需要接管系统流量时,才进入这一阶段。
项目 Compose 文件给出了 NET_ADMIN capability 和 /dev/net/tun设备挂载片段:
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun这两项只解决容器权限和设备传递,不能单独证明宿主机路由、DNS 劫持、策略路由和防火墙已经正确。Mihomo 官方文档将 TUN 作为顶层入站配置,并说明它涉及系统流量接管、DNS 劫持和按应用路由。Mihomo 入站配置文档因此,本文把 TUN 定位为权限检查,不把上面两行包装成完整 TUN 部署。
启用前先检查:
test -e /dev/net/tun && echo tun-device-present || echo tun-device-missing
docker compose config
docker compose up -d
docker compose logs --tail=100 mihomo如果设备不存在、权限不足或日志出现 TUN 初始化错误,删除刚加入的 cap_add和 devices配置,恢复普通代理模式。除非确有系统级流量接管需求,不要把网络模式直接改为 host。
Docker 文档说明,network_mode: host会共享宿主机网络栈,不能同时使用端口映射,也不提供普通 Compose 服务名 DNS。Docker Compose 网络文档这意味着 host 模式会改变端口冲突、监听地址和排查边界。
升级前先确认实际挂载源:
docker inspect mihomo --format='{{json .Mounts}}'
cp -a clash-config "clash-config.backup-2026-10-31"
cp -a metacubexd-config "metacubexd-config.backup-2026-10-31"然后修改镜像 tag 或 digest,执行 docker compose pull && docker compose up -d。回滚时恢复之前记录的 tag 或 digest,再重新启动。不要只备份容器层,因为配置和面板数据位于 bind mount 中。
镜像选择速查:集成镜像、纯核心和自建镜像怎么区分
“mihomo Docker”不是一个统一镜像名称。不同项目可能使用不同的启动脚本、环境变量、配置目录、端口和面板。本文选择集成镜像,是为了让首次部署用户有一条可核验的 Compose 路径;它不代表这是唯一方案,也不代表项目维护状态、架构覆盖或性能长期不变。
| 方案 | 配置主体 | 面板 | 适合人群 | 核验重点 |
|---|---|---|---|---|
| 本文示例的集成镜像 | 项目启动脚本与挂载目录 | 项目 README 声明集成 Metacubexd | 希望较快完成容器、订阅和面板部署的用户 | 固定 tag/digest、环境变量、挂载路径、平台清单 |
| 纯 Mihomo 核心镜像 | 自行维护 config.yaml | 需另行部署或不使用 | 希望减少第三方启动脚本依赖的用户 | 镜像入口、工作目录、配置读取路径和更新方式 |
| 自建镜像 | Dockerfile、启动脚本和配置全部自管 | 按需集成 | 需要审计构建链或定制运行环境的用户 | 构建来源、依赖版本、架构和回滚流程 |
如果所选镜像没有明确说明环境变量、目录或端口,不要把本文的 SUBSCRIBE_URL、CLASH_SECRET、/root/.config/mihomo和 8080直接套用。更稳妥的顺序是:先读镜像 README 和 Compose 文件,再用 docker inspect确认实际挂载与端口,最后才扩展订阅、面板或 TUN。
本文是第三方使用指南,不是“大哥云”官方页面;涉及具体订阅内容、服务状态或品牌入口时,应以对应服务的公开说明为准。
常见问题
mihomo Docker 应该使用 latest 还是固定版本?
优先使用固定 tag,并在条件允许时同时记录 digest。本文核验到的示例是 v1.19.33及其 GHCR digest,但版本页面会变化;升级前重新检查容器包页面和平台清单,回滚时恢复旧 tag 或 digest。
config.yaml 应该放在哪里?
在本文选择的 daitcl/mihomo 项目中,宿主机 ./clash-config挂载到容器 /root/.config/mihomo。其他镜像不一定使用相同目录,必须以所选镜像的 README 或 Compose 文件为准。
为什么容器运行了,但节点不显示?
先执行 docker compose config确认订阅变量不是占位值,再用 docker inspect确认挂载,查看配置目录和日志中的 provider 信息,最后检查面板连接的 API 地址与密钥。浏览器能打开 8080 只能证明 Web UI 有响应。
9090 API 可以访问,是否说明代理正常?
不能。9090 只说明控制 API 有响应。还需要分别使用 HTTP、SOCKS5 或混合端口发送带超时的代理请求,并结合日志区分配置、订阅、DNS、出站和目标站点响应。
Docker 部署 Mihomo 一定要启用 TUN 吗?
不一定。只给单个应用配置 HTTP 或 SOCKS5 代理时,可以先不启用 TUN。需要接管系统流量时,再确认宿主机存在 /dev/net/tun,添加 NET_ADMIN和设备挂载,并单独处理 Mihomo 的 TUN、DNS、路由和防火墙配置。
如何从本地访问远程容器的 Web 面板?
若远程主机上的 8080 只绑定到 127.0.0.1,可使用 ssh -N -L 8080:127.0.0.1:8080 -L 9090:127.0.0.1:9090 user@your-server建立隧道,然后在本地访问 http://127.0.0.1:8080。这比直接把控制 API 暴露到公网更容易限制访问范围。
常见问题
mihomo Docker 应该使用 latest 还是固定版本?
优先使用固定 tag,并在条件允许时记录 digest。本文示例使用 v1.19.33 及对应摘要;升级前重新检查版本页面和平台清单。
config.yaml 应该放在哪里?
本文示例把宿主机 ./clash-config 挂载到容器 /root/.config/mihomo。其他镜像可能不同,必须以对应项目文档和实际 Mounts 为准。
节点不显示时先查什么?
先查订阅变量是否仍是占位值,再查容器日志、挂载目录、provider 文件和目录写权限,最后检查面板连接的 API 地址与密钥。
9090 API 能访问是否代表代理正常?
不能。还需要使用 HTTP、SOCKS5 或混合端口执行带超时的代理请求,并结合日志检查订阅、DNS、出站和目标响应。
mihomo Docker 必须启用 TUN 吗?
不必须。单应用代理可先使用 HTTP 或 SOCKS5;只有需要接管系统流量时,才进一步处理 TUN 权限、配置、DNS、路由和防火墙。