mihomo Docker 部署:bridge、host、TUN 怎么选?
简答:首次部署 mihomo Docker,优先使用 bridge 网络、只映射实际需要的代理端口,并把控制 API 与面板绑定到 127.0.0.1。本文以已核实的第三方集成镜像为例,给出 Compose、架构检查、启动验证和安全加固步骤;镜像变量、端口和目录不能直接套用到其他镜像。
定义:mihomo Docker 是把 mihomo 内核运行在 Docker 容器中,再通过端口映射、配置挂载或 TUN 权限为其他程序提供代理与管理能力。
先选部署模式:大多数人从 bridge 开始
本文是第三方使用指南,不是任何品牌或项目的官方页面。先给结论:只想让浏览器、开发工具或局域网设备使用 HTTP、SOCKS5 或混合代理,选择 bridge + 端口映射;只有需要直接使用宿主机网络栈时才考虑 host;只有需要接管宿主机或指定设备流量时,才进一步评估 TUN。
| 模式 | 适用场景 | 主要边界 | 回滚难度 |
|---|---|---|---|
| bridge | 首次部署、VPS、普通 NAS、显式代理 | 程序需要手动填写代理地址和端口 | 低 |
| host | 确实需要直接使用宿主机网络命名空间 | 端口冲突和暴露范围更大,不能继续使用同样的 ports 写法 | 中 |
| TUN | 需要接管主机或指定应用流量 | 涉及 /dev/net/tun、Linux 能力、路由、DNS 和防火墙 | 高 |
| 一体化镜像 | 希望同时获得内核、面板和订阅管理 | 环境变量、目录、端口和启动脚本均属于项目专属约定 | 中 |
不要把“能运行 mihomo 核心”与“提供面板、订阅自动生成和健康检查”混为一谈。当前检索到的 daitcl/mihomo 仓库是集成 mihomo、Metacubexd 和 Caddy 的第三方镜像仓库,不应称为 mihomo 官方镜像;其 README 和 Dockerfile 只代表该仓库当前实现。查看该镜像仓库 README 查看该镜像 Dockerfile
镜像选择与架构核对:先确认能不能跑
核心镜像:适合已经有配置文件、希望自行维护 Web UI 和订阅逻辑的用户。本文未核实存在一个由 mihomo 核心项目直接维护、适用于所有平台的官方 Docker 镜像,因此不要把任意 Docker Hub 或 GHCR 项目称作官方镜像。
带面板的第三方镜像:部署较快,但需要同时承担镜像作者对启动脚本、面板、配置生成、端口和更新策略的维护责任。当前 daitcl/mihomo README 明确列出 SUBSCRIBE_URL、SUBSCRIBE_NAME、CLASH_SECRET、LOG_LEVEL 和 TZ,并列出配置目录、面板目录及端口;这些变量只适用于该仓库当前实现。核对环境变量和目录
一体化镜像:例如公开的 Tsutomu-miku/mihomo-docker README 声明支持 linux/amd64、linux/arm64 和 linux/arm/v7,并把 mihomo、Metacubexd、Sub-Store 和数据文件整合在一起。但它是独立第三方项目,端口、数据目录和更新责任不能与前一个镜像互换。查看该一体化项目的平台说明
部署前执行:
uname -m:查看宿主机内核架构。docker version:确认 Docker Engine 可用。docker compose version:确认 Compose v2 命令可用。docker info --format '{{.Architecture}}':查看 Docker 报告的架构。docker manifest inspect ghcr.io/daitcl/mihomo:v1.19.33:尝试查看镜像清单;如果返回错误,不要据此断定支持当前 NAS 架构。
架构尤其要注意:当前检索到的 daitcl/mihomo Dockerfile 在构建阶段直接下载 mihomo-linux-amd64-compatible 文件,不能据此推断它支持 arm64 或 armv7。amd64 VPS 可继续核对;arm64、armv7 NAS 应优先选择明确列出对应平台的一体化镜像,或自行构建并验证。mihomo 官方 FAQ 也说明发布文件名会包含系统和架构信息。查看 mihomo 架构文件说明
bridge 模式的 Compose:只适用于当前第三方镜像
下面的示例不是通用 mihomo Compose,而是针对当前检索到的 daitcl/mihomo 仓库 README 所列环境变量、目录和端口。示例使用截至 2026-11-08 可在 GHCR 页面核对到的标签与 Digest;发布或部署时仍应重新打开仓库页面确认。查看当前标签与 Digest
先创建目录:
mkdir -p ~/mihomo-docker/clash-config ~/mihomo-docker/metacubexd-config
cd ~/mihomo-docker
umask 077
创建仅供本机验证的 .env:
SUBSCRIBE_URL=https://example.com/replace-with-your-subscription
CLASH_SECRET=replace-with-a-long-random-secret
随后执行:
chmod 600 .env
创建 compose.yaml:
services:
mihomo:
container_name: mihomo
image: ghcr.io/daitcl/mihomo@sha256:5a8252346c9062b09a3a18004d20d90e306b3ca15ab3aa9748f6b6a33dbc65f4
restart: unless-stopped
environment:
TZ: Asia/Shanghai
LOG_LEVEL: info
CLASH_SECRET: ${CLASH_SECRET}
SUBSCRIBE_URL: ${SUBSCRIBE_URL}
SUBSCRIBE_NAME: default
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
networks:
- clash-net
networks:
clash-net:
driver: bridge
这里没有自行添加 CONTROL_TOKEN、CONTROL_PORT、CLASH_API_PORT 或 MIXED_PORT。这些变量属于其他集成项目的命名方式,不能未经核对就加入当前镜像。7890、7891、7892、9090 和 8080 的用途,也只按该镜像 README 说明理解:分别对应 HTTP、SOCKS5、混合代理、控制 API 和 Web UI。其他镜像可能使用不同端口或职责。核对该镜像的端口和 Compose 示例
启动前执行:
docker compose config
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=100 mihomo
成功判据:Compose 能展开且没有变量缺失;容器状态为 Up;日志没有持续出现配置解析、订阅下载、端口占用或权限错误。不要把“宿主机目录自动出现某个文件”作为通用成功条件,因为是否生成配置取决于镜像入口脚本;应以日志、容器内实际文件和代理请求共同判断。
端口、控制 API 与面板:本机验证后再开放内网
mihomo 核心文档把外部控制器定义为 RESTful API,并示例使用 external-controller: 127.0.0.1:9090;API 密钥由配置中的 secret 控制。绑定 127.0.0.1 只允许宿主机本地访问,不等于容器内所有服务或远程设备都能访问。查看外部控制器、监听地址和 secret 配置
本机先检查监听:
ss -lntp | grep -E '7890|7891|7892|8080|9090'
再查看容器自身的健康状态和日志:
docker inspect mihomo --format '{{.State.Status}} {{.State.Health.Status}}'
docker compose logs --tail=200 mihomo
当前第三方镜像 Dockerfile 自带的健康检查是使用镜像内已安装的 curl 请求 http://localhost:8080/;因此不要另写未经核对的 wget /api/control/health 检查。README 中的 Compose 示例还覆盖了一个不同的 curl http://localhost:9090 检查,实际以镜像构建结果和当前版本行为为准;如果健康状态异常,先用日志和本机端口检查判断,不能单凭 unhealthy 认定核心不可用。核对镜像内置 HEALTHCHECK
若需要从同一台服务器测试代理:
curl -x http://127.0.0.1:7890 https://example.com -I
curl --socks5-hostname 127.0.0.1:7891 https://example.com -I
如果需要让局域网设备使用代理,不要直接改成 0.0.0.0 并开放所有来源。先查宿主机内网地址:
ip -br addr
将端口绑定到实际内网地址,例如把 Compose 中的端口写成:
- "192.168.1.10:7890:7890"
- "192.168.1.10:7891:7891"
然后只允许可信网段访问。以使用 UFW 的 Linux 主机为例:
sudo ufw allow from 192.168.1.0/24 to any port 7890 proto tcp
sudo ufw allow from 192.168.1.0/24 to any port 7891 proto tcp
sudo ufw deny 9090/tcp
sudo ufw deny 8080/tcp
上面的地址和网段只是示例,必须替换成你的实际内网规划;云服务器还要同步检查云防火墙或安全组。订阅 URL 和控制密钥不要提交到 Git,不要出现在公开截图、工单或日志中;修改 .env 后继续保持 chmod 600 .env。
host 与 TUN:什么时候需要,如何回滚
host 网络:只有当应用确实需要宿主机网络命名空间时才考虑。启用后容器直接使用主机网络,通常不能再写普通 bridge 模式的 ports 映射;应重新检查宿主机监听、端口冲突、防火墙和服务暴露面。首次部署不要同时切换镜像、网络模式和配置文件。
TUN 模式:mihomo 文档列出 enable、stack、auto-route、auto-redirect 和 dns-hijack 等字段,可用的 stack 值包括 system、gvisor、mixed 和 mips;因此 mips 本身是官方文档列出的合法值,但这不代表 Docker 中加入该字段就能自动接管宿主机或其他容器流量。查看 mihomo TUN 字段和协议栈说明
如果只是为当前容器增加 TUN 设备,至少要在当前镜像和主机上逐项核对:
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
这段只说明容器获得设备和能力,不等于已经完成路由、DNS 劫持或宿主机流量接管。Docker bridge、host、TUN 与宿主机路由的组合需要在实际 Linux 发行版、内核、防火墙和 Docker 网络上测试,因此本文不把它包装成通用可复制模板。
回滚步骤:
- 备份
clash-config和metacubexd-config。 - 执行
docker compose down,不要先删除数据目录。 - 将镜像恢复为已记录的标签或 Digest。
- 先删除 TUN、host 网络和额外权限,只恢复 bridge 配置。
- 执行
docker compose up -d,再按容器、日志、API、代理四层重新验证。
故障排查速查表
| 现象 | 先查什么 | 处理方向 |
|---|---|---|
| 容器反复重启 | docker compose logs --tail=200 mihomo | 检查 YAML、订阅 URL、配置解析和端口占用 |
| 状态为 unhealthy | docker inspect mihomo 与 Dockerfile | 确认镜像内置健康检查访问的是哪个端口,不要自定义未知路径 |
| 9090 无法访问 | ss -lntp、配置中的 external-controller 和 secret | 确认是否只绑定回环地址,以及密钥是否匹配 |
| 面板打不开 | 确认该镜像是否提供 8080 Web UI | 检查端口映射、Caddy 日志和宿主机防火墙 |
| 订阅导入后无节点 | 检查订阅下载和 YAML 解析日志 | 确认 URL、订阅名称、挂载目录和配置生成逻辑 |
| arm64 或 armv7 启动失败 | uname -m、镜像 manifest 和 Dockerfile | 不要默认使用只下载 amd64 核心的镜像,改用明确声明平台的镜像或自行构建 |
若问题发生在升级后,先记录当前镜像标签、Digest、配置目录备份和日志,再一次只改变一个变量。镜像标签、配置结构和面板数据目录是否兼容,必须以对应项目当前 README、Dockerfile 和实际启动结果为准。
常见问题
mihomo Docker 应该使用 latest 还是固定 Digest?
生产或长期运行环境更适合记录已验证的版本标签和 Digest,并在升级前备份配置。本文检索到的 GHCR 页面显示该第三方镜像存在 v1.19.33 及对应 Digest,但部署时仍应重新核对页面;不要把本文 Digest 当成所有镜像的通用版本。
daitcl/mihomo 是 mihomo 官方 Docker 镜像吗?
未核实为 mihomo 核心项目官方镜像。当前仓库 README 和 Dockerfile 显示它是集成 mihomo、Metacubexd 与 Caddy 的独立第三方项目,因此只能按该仓库当前文档使用,不能把它的环境变量和端口泛化到其他镜像。
为什么不建议一开始就使用 host 网络和 TUN?
bridge 模式更容易隔离问题,也更容易回滚。host 网络会改变端口和监听边界,TUN 还需要设备、NET_ADMIN、路由、DNS 和防火墙配合;先证明容器、控制接口和代理端口可用,再增加一个变量。
如何判断镜像是否支持 arm64 或 armv7?
先执行 uname -m 和 docker info --format '{{.Architecture}}',再查看镜像 manifest。不要只看项目标题或 README 中的“多架构”描述;还要检查 Dockerfile 是否下载了对应架构的 mihomo 核心。当前检索到的 daitcl Dockerfile 下载的是 amd64-compatible 文件,不能据此推断支持 ARM。
控制 API 和代理端口可以直接开放到公网吗?
不建议。首次验证时把控制 API 和面板绑定到 127.0.0.1;局域网使用时只绑定实际内网地址,并用防火墙限制来源网段。订阅 URL 和 secret 应放在权限为 600 的文件中,避免提交 Git 或出现在公开日志与截图。
为什么容器是 Up,但代理仍然不能用?
Up 只表示容器进程仍在运行。应继续检查日志中的配置解析和订阅下载结果、控制端口监听、mihomo 代理集合是否加载,以及使用 curl 通过 HTTP 或 SOCKS5 端口发起实际请求。