引言
本教程旨在介绍如何通过 Docker Compose 部署 Mihomo(原 Clash.Meta)并梳理其运行限制。虽然最简便的方式是在服务器直接运行二进制文件,但长此以往,散落在系统后台的进程不仅难以溯源,更给运维审计带来了不便。容器化部署提供了以下优势:
- 环境隔离:避免与宿主机系统产生冲突
- 版本管理:轻松升级/回滚版本
- 配置持久化:配置文件与容器分离
- 易于迁移:一次配置,多处部署
资源限制:可精确控制 CPU/内存使用
如果你追求极致的部署速度且不在意管理成本,可以跳过本文,直接参考Metacubex。
注意:受 Docker Hub 政策调整及国内网络环境影响,传统的国内镜像加速服务已近乎失效。在不配置系统代理的情况下,不仅无法搜索和拉取官方镜像,即便使用自建仓库或第三方镜像源,也常因镜像同步不全而导致部署中断。
准备工作
- 离线部署镜像(在个人PC拉取镜像)
在无法直接访问 Docker Hub 的环境下,我们可以先在本地(或海外服务器)通过
docker save导出镜像包,再利用scp远程传输。bash docker pull metacubex/mihomo:latest docker pull ghcr.io/metacubex/metacubexd:latest # 导出镜像为 tar 包 docker save metacubex/mihomo:latest ghcr.io/metacubex/metacubexd:latest | gzip > mihomo-images.tar.gz # 格式:scp -i [私钥路径] [本地文件] [用户名]@[目标IP]:[远程路径] scp -i ~/.ssh/my_proxy_key.pem mihomo-images.tar.gz demo@目标服务器:~/ - 登录目标服务器执行( 演示系统为:Ubuntu 24.04 LTS)
bash # 执行以下命令加载 Docker 镜像(报错的话建议加sudo,要么把当前用户加入sudo用户组) docker load < mihomo-images.tar.gz # 删掉之前的镜像文件(删不删看个人) rm mihomo-images.tar.gz mkdir -p ~/.mihomo/config && cd ~/.mihomo - 内核参数配置
bash # 开启 IP 转发(必须) sudo sysctl -w net.ipv4.ip_forward=1 sudo sysctl -w net.ipv6.conf.all.forwarding=1 # 持久化配置 echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf echo "net.ipv6.conf.all.forwarding=1" | sudo tee -a /etc/sysctl.conf sudo sysctl -p # 检查 TUN 设备(TUN 模式必需) ls -la /dev/net/tun # 如果不存在,创建它 sudo mkdir -p /dev/net sudo mknod /dev/net/tun c 10 200 sudo chmod 600 /dev/net/tun - 创建
docker-compose.yaml
# version: '3'
services:
mihomo:
container_name: mihomo
image: metacubex/mihomo:latest
restart: unless-stopped
privileged: true # 开启特权模式(TUN 模式最简单的方式)
pid: host # 共享 PID 命名空间(便于调试和进程管理)
ipc: host # 共享 IPC 命名空间
network_mode: host # 使用宿主机网络栈(性能最优,TUN 必需)
cap_add:
- ALL
security_opt:
- apparmor=unconfined # 禁用 AppArmor 限制(某些系统需要)
volumes:
- ~/.mihomo/config:/root/.config/mihomo
- /dev/net/tun:/dev/net/tun # TUN 设备(TUN 模式必需)
# 共享host的时间环境
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
# mihomo内置的有管理界面,也挺好用,如果不想额外折腾,下面可以删掉
metacubexd:
container_name: metacubexd
image: ghcr.io/metacubex/metacubexd
restart: unless-stopped
# 网络配置(与 mihomo 分离,仅提供 Web 访问)
network_mode: bridge
# 依赖 mihomo 服务(确保顺序启动)
depends_on:
mihomo:
ports:
- '127.0.0.1:28002:80'
volumes:
- ~/.mihomo/caddy:/config/caddy:rw
# 共享host的时间环境
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
下载代理文件 注意,需要下载为clash格式,命令:
curl -o config/config.yaml ✈️订阅链接编辑修改配置文件:
# port of HTTP port: 7890 # port of SOCKS5 socks-port: 7891 allow-lan: true # 设置为true,允许局域网 bind-address: "*" # Rule / Global/ DIRECT (default is Rule) mode: rule # set log level to stdout (default is info) # info / warning / error / debug log-level: info # A RESTful API for clash external-controller: 0.0.0.0:7090 # 这个是内置的管理界面, # Secret for RESTful API (Optional) secret: "你的管理界面登录密码" tun: enable: true stack: system # 推荐使用 system 栈,兼容性最好 auto-route: true # 自动设置系统路由,实现“无感”代理 auto-detect-interface: true # 自动识别物理网卡,防止流量回环 dns-hierarchical: true mtu: 1400 # 调小 MTU,防止 TLS 握手时 Unexpected EOF dns: enable: true ipv6: false enhanced-mode: fake-ip listen: 0.0.0.0:53 fake-ip-range: 198.18.0.1/16 default-nameserver: - 119.29.29.29 - 114.114.114.114 - 223.5.5.5 - 8.8.8.8 nameserver: - 119.29.29.29 - 114.114.114.114 - 223.5.5.5 - https://223.5.5.5/dns-query - https://dns.alidns.com/dns-query - https://doh.pub/dns-query fake-ip-filter: - "*.lan" - "*.local" - +.miwifi.com - +.docker.io - +.market.xiaomi.com - +.push.apple.com你也可以参考 clash.wiki和 MetaCubeX配置适合自己的代理方式
- 启动容器
bash docker compose up -d docker logs -n 100 -f mihomo # 如果日志没报Error基本就没啥问题 - 访问管理界面你的Yacd或
192.168.X.X:28002 代理不通不能使用等问题的 原因通常是防火墙和DNS问题 ,如果使用TUN模式,代理可能会劫持你的DNS服务 ,需要注意修改对应系统设置
yacd