宿主机上 Clash 跑得好好的,一进容器就全是超时。原因很简单:容器有自己的网络命名空间,127.0.0.1 指的是容器自己。
核心前提:开 allow-lan
不管哪种方案,第一步都一样——让 Clash 监听的地址从 127.0.0.1 变成 0.0.0.0:
在 Clash Verge 里打开 允许局域网连接,或在配置里写:
allow-lan: true
bind-address: "*"
mixed-port: 7897验证:
netstat -an | findstr 7897看到 0.0.0.0:7897 才算成功。看到 127.0.0.1:7897 说明没开。
Docker:三个不同的场景
很多人踩坑是因为没分清这三件事其实需要分别配置。
场景一:docker pull 拉不动镜像
这是 Docker daemon 在联网,跟容器无关。
Docker Desktop(Windows / macOS): 设置 → Resources → Proxies → 打开 Manual proxy configuration,填:
HTTP: http://127.0.0.1:7897
HTTPS: http://127.0.0.1:7897
Bypass: localhost,127.0.0.1,*.localDocker Desktop 的 daemon 跑在虚拟机里但能访问宿主机 loopback,所以这里填 127.0.0.1 是对的。
Linux 上的 Docker(systemd):
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/proxy.conf > /dev/null <<'EOF'
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7897"
Environment="HTTPS_PROXY=http://127.0.0.1:7897"
Environment="NO_PROXY=localhost,127.0.0.1,::1,*.local,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker验证:
sudo systemctl show --property=Environment docker场景二:docker build 时装依赖超时
构建过程发生在临时容器里,需要显式传入:
docker build \
--build-arg HTTP_PROXY=http://host.docker.internal:7897 \
--build-arg HTTPS_PROXY=http://host.docker.internal:7897 \
--build-arg NO_PROXY=localhost,127.0.0.1 \
-t myimage .Dockerfile 里不需要声明这些 ARG——Docker 对这几个变量名有内置支持。
场景三:容器运行时要联网
docker run -it \
-e HTTP_PROXY=http://host.docker.internal:7897 \
-e HTTPS_PROXY=http://host.docker.internal:7897 \
-e NO_PROXY=localhost,127.0.0.1,::1 \
--add-host=host.docker.internal:host-gateway \
ubuntu bashdocker-compose 的写法:
services:
app:
image: myimage
environment:
- HTTP_PROXY=http://host.docker.internal:7897
- HTTPS_PROXY=http://host.docker.internal:7897
- NO_PROXY=localhost,127.0.0.1,::1,app,db
extra_hosts:
- "host.docker.internal:host-gateway"用宿主机局域网 IP 代替 host.docker.internal
如果 host.docker.internal 不可用,直接用宿主机的局域网 IP:
# Windows 上查
ipconfig
# Linux 上查 docker0 网桥地址(容器视角的宿主机)
ip addr show docker0 # 通常是 172.17.0.1然后把 host.docker.internal 换成那个 IP。
更省事的方案:开 TUN
上面那些配置加起来不少。如果嫌麻烦,开 TUN 模式——所有流量在网络层被接管,Docker daemon 和容器都不需要任何配置。
TUN 下要注意把 Docker 的网段加入直连规则,避免容器间通信被代理:
prepend-rules:
- IP-CIDR,172.17.0.0/16,DIRECT,no-resolve
- IP-CIDR,172.18.0.0/16,DIRECT,no-resolve
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolveWSL2:两种网络模式
WSL2 从某个版本起支持镜像网络模式,两种模式下配置方法完全不同。先确认你用的是哪种。
# 在 WSL2 里执行
cat /etc/resolv.conf
ip route show default模式一:NAT 模式(默认,传统)
WSL2 有独立虚拟网卡,宿主机对它来说是一个网关地址。
# 自动获取宿主机 IP 并设置代理
export HOST_IP=$(ip route show default | awk '{print $3}')
export HTTP_PROXY="http://$HOST_IP:7897"
export HTTPS_PROXY="http://$HOST_IP:7897"
export ALL_PROXY="socks5://$HOST_IP:7897"
export NO_PROXY="localhost,127.0.0.1,::1,*.local"写进 ~/.bashrc 或 ~/.zshrc 做成开关:
proxyon() {
local host_ip=$(ip route show default | awk '{print $3}')
export HTTP_PROXY="http://${host_ip}:7897"
export HTTPS_PROXY="http://${host_ip}:7897"
export ALL_PROXY="socks5://${host_ip}:7897"
export NO_PROXY="localhost,127.0.0.1,::1,*.local"
echo "proxy on → ${host_ip}:7897"
}
proxyoff() {
unset HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY
echo "proxy off"
}为什么要动态获取 IP:WSL2 的虚拟网卡地址每次重启宿主机都可能变,写死会失效。
模式二:镜像网络模式(较新的 Windows)
在 %USERPROFILE%\.wslconfig 里启用:
[wsl2]
networkingMode=mirrored
dnsTunneling=true
autoProxy=true
firewall=true改完执行 wsl --shutdown 重启 WSL。
镜像模式下 WSL2 和宿主机共享网络命名空间,可以直接用 127.0.0.1:
export HTTP_PROXY="http://127.0.0.1:7897"
export HTTPS_PROXY="http://127.0.0.1:7897"autoProxy=true 还会让 WSL 自动继承 Windows 的系统代理设置,很多情况下连环境变量都不用配。
验证代理是否生效
# 看环境变量
env | grep -i proxy
# 实测
curl -I https://www.google.com
# 看出口 IP(应该是节点的 IP)
curl https://api.ipify.org如果 curl 通了但 apt、pip 还是不行,说明那些工具有自己的代理配置,见开发工具代理速查。
排查清单
一条快速验证命令,在容器或 WSL 里执行:
curl -v --connect-timeout 5 http://宿主机IP:7897能连上(哪怕返回 400)说明网络层通了;Connection refused 说明 allow-lan 或防火墙有问题。
小结
- 第一步永远是开 allow-lan + 放行防火墙
- Docker 的三个场景要分别配:daemon、build、run
host.docker.internal在 Linux 上需要--add-host- WSL2 先确认网络模式:NAT 要动态取网关 IP,镜像模式直接用 127.0.0.1
- NO_PROXY 别忘了写内网段和服务名
- 嫌麻烦就开 TUN,但要把 Docker 网段加进直连规则
相关文档
让全家设备零配置接入。讲清楚三种接入方式(旁路由、TProxy、TUN)的取舍、完整的配置与 systemd 服务、防火墙规则,以及不影响家人上网的容错设计。
external-controller 提供的 RESTful API 全表,怎么用它切换节点、查连接、重载配置,怎么部署 Web 面板,以及几个实用的自动化脚本示例。