基于 mihomo(Clash.Meta 内核)的 Docker 化代理网关,内置 zashboard 管理面板与 subconverter 订阅转换能力。一条命令拉起,自动拉取订阅、转换配置并对外提供 HTTP/SOCKS 代理与可视化控制台。
适用场景:在服务器/网关上以
host网络模式运行,为局域网或本机提供全局/规则代理出口。
docker run 即可运行,无需手动安装依赖。x86_64 下自动调用 subconverter 转换为标准格式。:9090/ui 直接访问,支持节点选择、延迟测试、规则调试。Country.mmdb,支持基于地理位置的规则分流。linux/amd64、linux/arm64、linux/arm/v7。┌─────────────────────────────────────────────────────────────┐
│ Docker 容器 │
│ │
│ /bin/sh -c /root/endpoint.sh (容器入口 / PID 1) │
│ │ │
│ ├─ bash /root/clash/start.sh │
│ │ 1. 解析 CLASH_URL / CLASH_SECRET │
│ │ 2. curl/wget 下载订阅 → temp/clash.yaml │
│ │ 3. 格式检测(proxies/proxy-groups/rules) │
│ │ ├─ 标准 → 直接使用 │
│ │ ├─ Base64 → 解码后再检测 │
│ │ └─ 非标准(x86_64) → subconverter 转换 │
│ │ 4. 拼接模板 + 代理段 → conf/config.yaml │
│ │ 5. 注入 external-ui 与 secret │
│ │ 6. nohup mihomo -d /root/clash/conf & │
│ │ │
│ └─ while true; do sleep <周期>; bash reload.sh; done │
│ reload.sh: 重新执行 ①~⑥,再 killall mihomo 重启 │
│ │
│ mihomo (Clash.Meta) │
│ ├─ :7890 HTTP 代理 │
│ ├─ :7891 SOCKS5 代理 │
│ └─ :9090 RESTful API + /ui (zashboard) │
└─────────────────────────────────────────────────────────────┘
关键点
mihomo 以 -d /root/clash/conf 指定配置目录,端口、external-controller、Secret、external-ui 全部来自该目录下的 config.yaml。config.yaml 由模板(temp/templete_config.yaml)与订阅中的代理段拼接而成,模板决定端口/模式等全局设置。reload.sh 会先从已生成的 config.yaml 中读取现有 Secret 再重新生成,因此定时刷新不会改变登录口令。clash_docker/
├── Dockerfile # 镜像构建(alpine:3.21 + mihomo + 依赖)
├── .dockerignore
├── .gitignore
├── Readme.txt # 本文档入口
├── endpoint.sh # 容器入口:启动 + 定时刷新循环
├── .github/workflows/
│ └── docker-image.yml # 多架构镜像 CI
└── clash/
├── start.sh # 首次启动:拉取订阅 → 转换 → 生成配置 → 拉起 mihomo
├── reload.sh # 定时刷新:重新拉取订阅 + 重启 mihomo(保留 Secret)
├── restart.sh # 仅重启内核(不重新拉取订阅)
├── shutdown.sh # 停止内核
├── .env # 本地/非 Docker 部署的订阅配置样例
├── README.md # 服务器裸机部署说明
├── conf/
│ ├── config.yaml # ⚠ 运行时由脚本生成,初始为空
│ └── Country.mmdb # GeoIP 数据库
├── temp/
│ ├── templete_config.yaml# 配置模板(文件名确为 templete,历史拼写)
│ ├── clash.yaml # 订阅原始下载
│ ├── clash_config.yaml # 转换后的标准配置
│ ├── config.yaml # 拼接中间产物
│ └── proxy.txt # 提取出的代理段
├── scripts/
│ ├── get_cpu_arch.sh # 获取 CPU 架构
│ └── clash_profile_conversion.sh # 订阅格式检测与转换
├── tools/subconverter/ # subconverter 二进制与配置(仅 x86_64 转换用)
├── dashboard/public/ # zashboard 静态资源(external-ui)
└── logs/
└── clash.log # mihomo 运行日志(log-level: silent,默认极小)
| 项目 | 说明 |
|---|---|
| Docker | 任意较新版本(建议 20.10+) |
| 网络模式 | 必须使用 --net host,代理端口才能直接暴露在宿主机 |
| 权限 | 默认以 root 运行;仅用 port/socks-port 时无需额外 cap-add,需透明代理(redir-port)时才需 NET_ADMIN |
| 订阅 | 自备有效的 Clash/Mihomo 订阅地址(CLASH_URL) |
| 架构 | amd64 / arm64 / arm/v7 |
注意:因使用
--net host,容器内端口即宿主机端口,请勿与宿主机上其他服务(尤其是另一个 clash 实例)的7890/7891/9090冲突。
docker run -d \
--name clash \
--net host \
--restart unless-stopped \
-e CLASH_SECRET='your_secret_here' \
-e CLASH_URL='https://your-subscription-url/xxx' \
admibo/clash_vpn
如需覆盖默认配置模板(修改端口、代理模式、DNS 等),将宿主机模板文件挂载到容器模板路径:
docker run -d \
--name clash \
--net host \
--restart unless-stopped \
-e CLASH_SECRET='your_secret_here' \
-e CLASH_URL='https://your-subscription-url/xxx' \
-v /root/auto/nsfcous.yaml:/root/clash/temp/templete_config.yaml \
admibo/clash_vpn
模板文件即
clash/temp/templete_config.yaml的格式(含port/socks-port/mode/external-controller等)。挂载后每次reload.sh都会基于该文件重新拼接配置。
# 查看日志
docker logs clash
# 检查端口监听(应在 *:9090 / *:7890 / *:7891)
docker exec clash sh -c "netstat -tlnp 2>/dev/null | grep -E '9090|7890|7891'"
# 只应存在 1 个 mihomo 进程
docker exec clash sh -c "pidof mihomo | wc -w"
docker run -e)| 变量 | 必填 | 说明 |
|---|---|---|
CLASH_URL | ✅ | 订阅地址。脚本会下载并按需转换。 |
CLASH_SECRET | ⭕ | Dashboard / API 登录口令。为空时脚本自动生成随机串(每次重建容器会变)。建议显式设置以便持久登录。 |
SAFE_PATHS | ❌ | external-ui 安全路径,镜像内已默认设置,通常无需覆盖。 |
ENV / --build-arg)| 变量 | 默认值 | 说明 |
|---|---|---|
MIHOMO_VERSION | v1.19.29 | mihomo 内核版本,构建时从 GitHub Release 拉取对应架构二进制。 |
SAFE_PATHS | /root/clash/dashboard/public | Dashboard 静态目录。 |
默认模板位于 clash/temp/templete_config.yaml,内容节选:
port: 7890 # HTTP 代理端口
socks-port: 7891 # SOCKS5 代理端口
redir-port: 0 # 透明代理端口(0=关闭)
allow-lan: true # 允许局域网连接
mode: Global # Rule / Global / Direct
log-level: silent # silent/info/warning/error/debug
external-controller: '0.0.0.0:9090'
secret: 'b&ZlKTte5OnEt2Sn' # 占位,运行时会由脚本注入真实 Secret
# external-ui: /root/clash/dashboard/public
自定义方式
mode/dns 等;-v /path/your_template.yaml:/root/clash/temp/templete_config.yaml 挂载进容器;reload,新模板即生效。
secret行无需手动维护——start.sh/reload.sh会用CLASH_SECRET(或已有值)自动覆盖注入。
| 端口 | 协议 | 用途 | 监听地址 |
|---|---|---|---|
7890 | HTTP | HTTP 代理入口 | 0.0.0.0(allow-lan) |
7891 | SOCKS5 | SOCKS5 代理入口 | 0.0.0.0 |
9090 | HTTP | RESTful API + Dashboard /ui | 0.0.0.0 |
客户端配置示例
http://<宿主机IP>:7890socks5://<宿主机IP>:7891proxy_on / proxy_off 函数(写入 /etc/profile.d/clash.sh),可在容器内一键开关系统级代理:source /etc/profile.d/clash.sh
proxy_on # 导出 http_proxy/https_proxy 指向 127.0.0.1:7890
proxy_off # 取消导出
http://<宿主机IP>:9090/uiAPI Base URL 填入 http://<宿主机IP>:9090Secret 填入 CLASH_SECRET(或容器日志中输出的 Secret)面板为 zashboard(Clash.Meta 生态的现代 Dashboard),非旧版 yacd。
容器内 /root/clash/ 下提供以下脚本:
| 脚本 | 作用 | 是否重新拉取订阅 |
|---|---|---|
start.sh | 首次启动:拉订阅→转换→生成配置→拉起 mihomo | ✅ |
reload.sh | 定时刷新:重新拉订阅→生成配置→killall mihomo→重启(保留 Secret) | ✅ |
restart.sh | 仅重启内核(基于已有 conf/config.yaml,不更新订阅) | ❌ |
shutdown.sh | 停止内核并清理 /etc/profile.d/clash.sh | — |
在容器内手动执行示例:
docker exec clash bash /root/clash/reload.sh # 立即刷新订阅并重启
docker exec clash bash /root/clash/restart.sh # 仅重启(不刷新节点)
docker exec clash bash /root/clash/shutdown.sh # 停止
实现说明(killall 策略):由于基础镜像为 Alpine(busybox),
ps的列序与 GNU 不同,脚本统一采用killall mihomo终止全部内核进程后再启动,确保不会出现多实例堆积、且端口不被旧进程占用。
endpoint.sh 在首次启动后进入循环:
while true; do
sleep 267840 # ≈ 74 小时
bash /root/clash/reload.sh
done
reload.sh 重启时复用已有 Secret,Dashboard 登录态不中断。sleep 值观察刷新效果(注意过短的周期会频繁请求订阅源)。docker build -t admibo/clash_vpn:local .
docker run -d --net host -e CLASH_URL=... -e CLASH_SECRET=... admibo/clash_vpn:local
.github/workflows/docker-image.yml 通过 docker/build-push-action 构建并推送 linux/amd64、linux/arm64、linux/arm/v7 三架构镜像至 admibo/clash_vpn。
建议在 CI 中使用
github.sha或经过清洗的标签作为镜像 tag,避免直接把 commit message(可能含空格/特殊字符)用作 tag 导致推送失败。
Q1:Dashboard 连不上 / 端口没监听
--net host;docker exec clash sh -c "pidof mihomo" 确认内核在运行;docker logs clash 与 /root/clash/logs/clash.log。Q2:两个 clash 容器同时跑,端口疑似冲突
--net host 下所有实例共享宿主机端口。请确保只有一个实例使用 7890/7891/9090,或给不同实例分配不同端口(通过自定义模板)。Q3:UI 里看不到代理节点
Q4:日志出现 error: unsupported rule type RULE-SET
Q5:定时刷新后节点没变 / 出现多个 mihomo 进程
reload.sh(会 killall 旧进程);旧版通过 ps|awk 取 PID 在 Alpine 下取到的是 USER 而非 PID,会导致旧进程残留。当前版本已修复。Q6:订阅是 https 但下载报错证书相关
-k 跳过证书校验(兼容性考虑)。如订阅源证书可信,可移除 -k 以提升安全性。port/socks-port 时并非必需,如需降权请评估透明代理(redir-port/TPROXY)对 NET_ADMIN 的需求。CLASH_SECRET 通过环境变量传入,docker inspect 可见。生产环境建议使用编排平台的 secret 管理机制。--restart unless-stopped;若遗漏,容器退出后不会被 Docker 拉起(且 mihomo 非 PID 1,其崩溃不会连带停止容器)。-k:跳过 TLS 校验,存在中间人篡改风险,仅在订阅源证书异常时必要。external-controller 监听 0.0.0.0:9090 且 allow-lan: true,请确保 Secret 强度足够,避免 Dashboard/API 暴露到公网被未授权访问。Content type
Image
Digest
sha256:31afb87c5…
Size
36.8 MB
Last updated
3 days ago
docker pull admibo/clash_vpn