开发与 AI · Clash 技术博客

Git、npm、Docker 不走 Clash?终端代理设置与超时修复

Git、npm 和 Docker 各自读取不同的代理来源,所以改了终端变量也不一定能修复 docker pull。先确认本地端口,再逐个检查实际配置来源。

  • Git
  • npm
  • Docker
  • WSL2
本文目录

浏览器能用但 Git、npm、Docker 超时,先分清是谁在发请求

浏览器能访问 GitHub,只说明浏览器使用了系统代理。Git 会读取自己的配置和环境变量,npm 还会读取 npmrc,Docker Desktop 与 Docker Engine 则有独立的后台进程。三条命令同时失败,也可能是三种不同的代理入口。

分别运行一个能复现问题的命令:git ls-remote https://github.com/git/git.git HEAD、npm ping、docker pull hello-world,并记下错误文字。

Could not resolve host 指向解析,Connection refused 常见于本地端口没有监听,TLS 或证书错误不能靠增加超时时间解决。

工具实际由谁发起请求

工具常见代理来源先看的结果
Git HTTPSGit 配置或 HTTP(S)_PROXYgit config 与 GIT_CURL_VERBOSE
npm环境变量、npmrc、registry 配置npm config get 与 npm ping
Docker DesktopDesktop 的 Proxies 设置Desktop 日志与 pull 错误
Linux Docker Enginedockerd 的 daemon.json 或 systemd 环境journalctl -u docker

先确认 127.0.0.1 上确实有人接请求

在 Clash 客户端查看 mixed-port 或 HTTP 端口,不能凭习惯假定一定是 7890。Windows 可用 netstat -ano,macOS 或 Linux 可用 lsof、ss 检查端口;端口不存在时,任何工具配置都只会得到 connection refused。

用 curl 显式指定代理访问一个已知 HTTPS 地址,是最小的入口测试。它成功以后,再把同一个端口交给 Git 或 npm。若 curl 也失败,先修客户端、节点或本地防火墙,不要继续修改三个工具的永久配置。

临时验证本地 HTTP 代理
# 将 7890 换成客户端显示的 HTTP 或 mixed 端口
curl -I -x http://127.0.0.1:7890 https://github.com

# Linux 查看监听
ss -lntp | grep 7890

# Windows 查看监听
netstat -ano | findstr :7890

终端先做一次临时测试,不急着写进启动文件

HTTP_PROXY 和 HTTPS_PROXY 只对从当前终端启动、且愿意读取它们的程序生效。先在一个新终端临时设置,完成 git 或 npm 测试,关闭终端后自然失效。结果有效再决定是否写进 PowerShell Profile、.zshrc 或 CI 环境。

NO_PROXY 应保留 localhost、127.0.0.1 和需要直连的内网域名。把所有内网请求也送进 Clash,会让本地开发服务、公司仓库或 Docker 容器互访产生新的问题。

一次终端会话的环境变量
export HTTP_PROXY=http://127.0.0.1:7890
export HTTPS_PROXY=http://127.0.0.1:7890
export NO_PROXY=localhost,127.0.0.1,.local

# PowerShell
$env:HTTP_PROXY="http://127.0.0.1:7890"
$env:HTTPS_PROXY="http://127.0.0.1:7890"

Git 先查配置来源,再决定设还是删

git config --show-origin --get-regexp 可以显示代理来自哪个文件。命令没有输出时,通常只是 Git 没有单独保存代理,并不是新的报错。旧客户端留下的 http.proxy 指向已经关闭的端口时,即使环境变量正确,Git 仍可能继续使用旧值。

需要固定 Git HTTPS 代理时,只写入用户级 http.proxy;不需要时用 --unset-all 清理。SSH remote 不走 Git 的 HTTP 代理,[email protected] 超时要另外检查 SSH、ProxyCommand,或先改用 HTTPS 做对照。

查看、设置和清理 Git 代理
git config --show-origin --get-regexp '(^http\..*proxy$|^remote\..*\.proxy$)'

# 需要固定代理时再写入
git config --global http.proxy http://127.0.0.1:7890
git ls-remote https://github.com/git/git.git HEAD

# 以后改回环境变量或直连时删除
git config --global --unset-all http.proxy

npm 超时还要区分代理与 registry

npm 官方配置会读取 HTTP_PROXY、HTTPS_PROXY,也可能在用户或项目 .npmrc 中保存 proxy、https-proxy 和 registry。registry 指向已经停用的镜像时,换代理节点不会改变请求地址。

运行 npm config get proxy、npm config get https-proxy 和 npm config get registry,再用 npm ping 验证当前 registry。项目目录里的 .npmrc 可以覆盖用户配置,因此同一台电脑不同项目可能表现不同。

临时环境变量已经生效时,不必再写 npm 固定代理。确认 npm 没有读到环境变量后,再设置下面两项。

核对、设置和清理 npm 代理
npm config get proxy
npm config get https-proxy
npm config get registry
npm ping

# 仅在确实需要 npm 固定代理时设置
npm config set proxy http://127.0.0.1:7890
npm config set https-proxy http://127.0.0.1:7890
npm ping

# 改回环境变量或直连时清理
npm config delete proxy
npm config delete https-proxy

docker pull 由后台引擎发起,改当前 shell 未必有用

Docker Desktop 有自己的代理设置。Windows 或 macOS 进入 Docker Desktop 的 Settings → Resources → Proxies,选择 System proxy。

若系统代理没有被识别,再选 Manual configuration 并填写 Clash 的 HTTP 或 mixed 端口。

Docker 官方说明 Desktop 不读取 daemon.json 里的 daemon proxy 配置,因此不要同时在两个位置反复修改。

原生 Linux Docker Engine 由 dockerd 拉取镜像。查看 /etc/docker/daemon.json 是否已经存在,把下面的 proxies 字段合并进原 JSON,不能整文件覆盖。保存后校验 JSON 与 daemon 配置,再重启 Docker。

给容器内应用设置代理是另一项配置,它不会反过来修复 daemon 执行的 docker pull。

Linux Docker Engine 的 daemon 代理
# 把 proxies 合并进现有 /etc/docker/daemon.json,不要覆盖其他字段
{
  "proxies": {
    "http-proxy": "http://127.0.0.1:7890",
    "https-proxy": "http://127.0.0.1:7890",
    "no-proxy": "localhost,127.0.0.1,.local"
  }
}

sudo dockerd --validate --config-file=/etc/docker/daemon.json
sudo systemctl restart docker
docker info | grep -i proxy
docker pull hello-world
Docker Desktop
在 Settings → Resources → Proxies 检查 Docker Desktop proxy 与 Containers proxy,应用设置后用 hello-world 做一次干净拉取。
Linux Docker Engine
先用 dockerd --validate 校验 daemon.json,再重启服务;失败时查看 journalctl -u docker。
运行中的容器
容器需要访问外网时再传入代理变量,并为宿主与内网地址设置 NO_PROXY。

进入 WSL 或容器以后,127.0.0.1 已经换了主人

Windows 上的 Clash 监听 127.0.0.1,但 WSL2 或容器里的 127.0.0.1 指向它们自己。NAT 网络下要使用宿主可达地址,并确认客户端允许局域网连接、Windows 防火墙只向需要的虚拟网段放行。镜像网络模式的行为不同,应按当前 WSL 网络配置验证。

先在 WSL 或容器里 curl 宿主代理端口;连端口都不通时,继续改 Git 或 npm 没有意义。端口可达以后,再决定用环境变量还是让 Clash TUN 接管这类进程。

能下载以后,只保留真正需要的一层

环境变量、Git 全局配置、npmrc 和 Docker 设置同时存在,会让以后换端口或退出客户端变得难以解释。保留日常真正使用的一层,把测试期间写入的固定代理删掉,并记录哪些命令依赖它。

最后在新终端中依次执行 git ls-remote https://github.com/git/git.git HEAD、npm ping 和 docker pull hello-world。三者都应成功,Clash 的连接页也应出现对应请求。

退出 Clash 后,工具不应继续指向已经关闭的本地端口。若还出现 Connection refused,就继续清理残留的固定代理。

参考资料