容器里跑内核时,最大的差异在于网络命名空间: 容器默认使用自己的网络栈,因此 TUN 与局域网共享的行为和宿主机上并不完全相同。
镜像与架构选择
# 确认宿主机架构,选择匹配的镜像
uname -m
# 拉取镜像
docker pull example/clash-meta:latest
# 查看镜像支持的架构
docker manifest inspect example/clash-meta:latest | grep architecture
多架构镜像会在 docker pull 时自动匹配,但如果镜像只提供了单一架构,需要显式指定或使用 QEMU 模拟(性能会明显下降)。
最小可用配置
services:
clash:
image: example/clash-meta:latest
container_name: clash
restart: unless-stopped
network_mode: host
volumes:
- ./config:/etc/clash
cap_add:
- NET_ADMIN
- NET_RAW
devices:
- /dev/net/tun
environment:
- TZ=Asia/Shanghai
command: ["-d", "/etc/clash"]
三个关键点:network_mode: host 让容器直接使用宿主机网络栈;cap_add 授予创建 TUN 所需的能力;/dev/net/tun 必须从宿主机映射进来,否则 TUN 模式无法启动。
网络模式怎么选
| 模式 | 特点 | 适用场景 |
|---|---|---|
host | 与宿主机共用网络,端口直接对外 | TUN / 透明代理,推荐 |
bridge | 独立网络,需手动映射端口 | 仅作 HTTP 代理供其他容器使用 |
macvlan | 容器获得独立 IP,像一台独立设备 | 需要被局域网设备直接访问 |
需要注意的是,bridge 模式下即使开启了 TUN,也只能接管容器自身的流量,宿主机上的程序不受影响。
持久化与权限
# 目录结构
./config/
├── config.yaml
├── Country.mmdb # 容器会自动下载
└── ruleset/ # 自定义规则集
# 确保容器内进程有读写权限
chmod 700 ./config
chmod 600 ./config/config.yaml
容器通常以非 root 用户运行内核,如果挂载目录权限不对, 会表现为「配置读取失败」或「无法写入缓存」,日志中能看到 permission denied。
健康检查与升级
services:
clash:
# ...省略其他配置
healthcheck:
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:9090/version"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
# 更新流程:拉取新镜像并重建容器
docker compose pull
docker compose up -d
# 查看日志
docker compose logs -f --tail 100
# 校验配置是否合法
docker compose exec clash clash-meta -d /etc/clash -t
常见问题
容器启动后立即退出
先看日志。最常见的原因是配置文件语法错误,或挂载路径写错导致找不到 config.yaml。
宿主机程序不生效
使用了 bridge 网络模式。切到 host 模式,或在宿主机上把代理指向容器的映射端口。
无法创建 TUN 设备
缺少 NET_ADMIN 能力或没有映射 /dev/net/tun,两者都需要。
控制接口无法访问
检查配置中 external-controller 的监听地址。在 host 模式下应绑定 127.0.0.1,不要用 0.0.0.0。
容器部署同样需要注意安全加固,见 安全加固与隐私保护指南。