Docker 拉取镜像总超时?Windows 与 macOS 上让 Docker Desktop 走 Clash 的步骤
典型现象:Clash 开着,浏览器能翻墙,Docker 却「装死」
很多人已经用 Clash(或基于 Mihomo 内核的图形客户端)把系统代理或 TUN 跑通:Chrome 能打开境外站点,终端里用对了环境变量也能 curl 外网。可是一回到 Docker Desktop,docker pull 仍然长时间停在 Pulling,构建镜像时 apt-get、npm install 频繁超时。这类问题往往不是「节点坏了」,而是流量根本没有经过你以为的那条链路:桌面浏览器跟随系统代理,而 Docker 引擎、WSL2 里的 Linux 后端、以及容器内进程各自有一套网络语义,需要分开配置。
本文目标是把「宿主机已代理」翻译成「镜像仓库访问也稳定」:先建立四层心智模型,再分别说明在 Windows 与 macOS 上如何把 HTTP/HTTPS 代理接到 Docker 官方客户端,并提示 容器网络里常见遗漏。若你尚未完成订阅导入与基础模式,可先读 Clash 全平台订阅导入教程;需要图形客户端总览可对照 Clash Verge Rev 使用教程。
先分清四层:谁在发起请求,就改谁的代理
可以把它想成四条叠在一起的管道:第一层是你在 Windows 或 macOS 上开的 Clash,它监听本机某个端口(常见如 7890 混合端口),并可能改写系统代理或接管路由。第二层是 Docker Desktop 自带的 Linux 虚拟机或 WSL2 集成后端——真正执行 docker pull 的是这里的 Docker 引擎,它不会自动继承你在 Windows 浏览器里看到的「系统代理」的全部语义,尤其是当引擎跑在独立网络命名空间里时。第三层是你在图形界面或 daemon.json 里为引擎配置的 http-proxy / https-proxy,它解决的是「拉镜像、登录 Registry」这类宿主机侧守护进程的流量。第四层才是容器内部:镜像构建步骤或运行中的进程若需要访问外网,要在 Dockerfile、docker run 或 Compose 里注入 HTTP_PROXY 等变量,否则它们仍可能直连失败。
一句话:给 Clash 配好规则 ≠ 给 Docker 引擎配好代理 ≠ 给容器内 apt 配好代理。下面按顺序做,避免改了一处却在另一层仍走直连。
第零步:把 Clash 的入站地址说清楚(127.0.0.1 还是宿主机)
在填 Docker 的代理地址前,先确认 Clash 实际监听在哪:打开客户端,记下 HTTP 或 mixed-port 端口。Docker 引擎与大多数 Registry 交互走 HTTP CONNECT 或 HTTPS,一般填 http:// 前缀即可(除非你的客户端单独拆出 SOCKS,而 Docker 只配了 HTTP 代理字段,此时应优先对齐文档推荐的 HTTP 代理端口)。若代理仅监听 127.0.0.1,从宿主机本机发起的 Docker 有时可以直接写 http://127.0.0.1:端口;但一旦请求发自 Docker 内置 Linux 环境或容器网络命名空间,127.0.0.1 指的是那一侧的回环地址,而不是你 Windows 上的 Clash。
因此更稳妥的写法是使用 Docker 提供的宿主机解析名:Windows 与 macOS 上的 Docker Desktop均支持 host.docker.internal(具体行为以当前版本文档为准),把代理写成 http://host.docker.internal:7890 一类,让流量从引擎或容器走到真实宿主上的 Clash。与此同时,在 Clash 中开启 Allow LAN 或等价选项,并确认防火墙未拦截来自虚拟网卡或 host.docker.internal 对应网段的入站,否则会出现「配置填对了但仍连接被拒绝」的假超时。
Windows:Docker Desktop 图形界面与引擎级代理
在 Windows 上安装 Docker Desktop 并启用 WSL2 后端时,推荐优先使用图形界面里的代理设置:打开 Settings → Resources → Proxies(不同版本菜单位置可能略有调整),开启 Manual proxy configuration,在 HTTP/HTTPS 中填入指向 Clash 的地址。若你使用 host.docker.internal,请与上节一致;若仅在引擎与 WSL 互通场景下验证通过,也可在测试阶段改用 Windows 主机的局域网 IP,但长期仍建议用稳定的主机名以免 DHCP 变化。
图形界面保存后,重启 Docker 或执行一次 docker info,观察输出里是否出现 HTTP Proxy / HTTPS Proxy 字段(不同版本展示方式不同)。若你更习惯配置文件,也可以在 Docker 的 daemon.json 中使用官方文档中的 proxies 结构声明 http-proxy、https-proxy 与 no-proxy:no-proxy 务必包含私有网段、localhost、以及内网 Registry 主机名,避免把访问公司 Harbor 的流量误送进 Clash。
这里与「纯 WSL2 里自己装的 Docker Engine」不同:Docker Desktop 管理的引擎会由官方客户端统一更新网络栈;若你只修了 WSL 发行版里的环境变量,却未在 Desktop 里配置,仍会出现 pull 不走代理的割裂。若你还遇到「宿主能上、WSL 全挂」一类路由问题,请与 Windows 11 上 Clash 与 WSL2 路由与 MTU 排障 一文对照,本篇侧重 Docker 官方客户端与镜像拉取代理,不重复展开 MTU 细节。
macOS:Docker Desktop 与本地回环的差异
在 macOS 上,Docker Desktop 同样运行在轻量 Linux 虚拟机之上,因此「浏览器走 Clash」与「引擎拉镜像」仍然是两件事。路径与 Windows 类似:进入 Settings → Resources → Proxies,启用手动代理并指向 Clash。若使用 127.0.0.1 在引擎侧不生效,优先改用 host.docker.internal 指向宿主机监听端口。macOS 上还需注意安全软件或 Little Snitch 类工具对「来自 Docker 虚拟机」的出站连接单独拦截,表现为偶发超时而非立即失败。
若你同时使用命令行里的代理环境变量与 Docker Desktop,请避免两套配置互相矛盾:以引擎最终生效的 docker info 为准,而不是终端里临时 export 的变量——后者往往只影响 docker CLI 与宿主进程,不必然写入引擎。
WSL2 与 Docker 后端:何时该怀疑「localhost 指错了」
在 Windows 上,大量开发者使用 WSL2 作为开发环境。若 Docker Desktop 集成 WSL2,引擎实际跑在微软与 Docker 协同的那套后端里;此时你在 Ubuntu 里看到的 127.0.0.1:7890 与 Windows 宿主机上的 Clash 端口不是同一个网络接口。症状常表现为:在 PowerShell 里设置 HTTP_PROXY=http://127.0.0.1:7890 能通,而在 WSL 里执行同等命令却连接拒绝,或反过来。处理原则仍是:拉镜像属于 Docker 引擎行为,优先在 Docker Desktop 全局代理里修;WSL 发行版内的环境变量只影响你在该发行版里直接运行的进程,不等价于引擎配置。
若你坚持在 WSL 内部署独立 Docker(非 Desktop 集成),则需要按 Linux 服务器惯例为 docker.service 配置环境或 /etc/docker/daemon.json,并自行处理 systemd 与 DNS——那已超出本文「Docker Desktop」范围,但核心仍是「引擎看到的代理地址必须可达」。
容器内与构建时:镜像里 apt、npm 仍要 HTTP_PROXY
即使 docker pull 已经飞快,构建 Dockerfile 时仍可能在 RUN apt-get update 卡住,因为构建步骤运行在临时容器里,默认不会继承你在宿主机终端 export 的代理。常见做法是在构建时传入参数:docker build --build-arg HTTP_PROXY=... --build-arg HTTPS_PROXY=...,或在 BuildKit 环境下使用对应的环境变量机制;在 Dockerfile 里用 ARG 接收再导出给 RUN。运行时同理:docker run -e HTTP_PROXY=... -e HTTPS_PROXY=... -e NO_PROXY=... 才能让业务进程走 Clash。
NO_PROXY 建议包含 localhost、127.0.0.1、::1、常见内网段以及集群内部服务名,避免本可直连的依赖被强行拖进代理。对于仅需要访问镜像仓库的场景,引擎层代理通常足够;对于需要频繁访问境外 API 的容器,再叠加容器级变量。
Clash 规则侧:别忘了镜像仓库域名
代理链路打通后,若仍出现「TLS 握手慢」或「特定仓库超时」,请在 Clash 日志里确认请求是否命中预期策略组:registry-1.docker.io、*.docker.io、以及你实际使用的第三方 Registry 域名,应落在能访问外网的策略上,而不是被误分到直连或失效节点。与浏览器不同,Docker 客户端会长时间保持连接,更容易暴露节点不稳定或 DNS 污染问题。若使用 fake-ip 模式,也要核对 Docker 侧解析是否与 Clash DNS 一致,避免出现「解析到假 IP、引擎却按另一套逻辑建连」的错位。
国内网络环境下,不少人会配置 Registry 镜像加速;这与「走 Clash」是两条路线,可并行存在:镜像站解决的是到公网 Registry 的连通性,Clash 解决的是跨境链路。若你只配了镜像加速而未处理公司防火墙对 Docker 流量的拦截,仍可能失败,需结合具体环境判断。
排查清单(建议按顺序勾)
- Clash 混合端口或 HTTP 端口是否对局域网 / 非本机接口开放(Allow LAN),防火墙是否放行来自 Docker 虚拟网段的入站。
- Docker Desktop 是否在引擎层配置了 HTTP/HTTPS 代理,
docker info是否与预期一致;是否误用引擎内部的127.0.0.1指代。 - 代理地址是否优先使用
host.docker.internal或确认的宿主机 IP,并与 Clash 监听端口一致。 no-proxy/NO_PROXY是否覆盖内网 Registry 与 loopback,避免该直连的流量被送进代理。- 构建与运行阶段是否单独为容器传入
HTTP_PROXY/HTTPS_PROXY。 - Clash 规则是否将 Docker 相关域名纳入正确策略组,DNS 模式与日志是否与现象相符。
合规与安全提示:请在你所在地法律与公司政策允许的前提下使用代理与访问外部镜像仓库;本文仅讨论客户端网络配置与排障思路,不构成对任何受限网络或资源的访问建议。生产环境请优先使用经批准的 Registry 与镜像源。
小结
Docker Desktop 与 Clash 同时使用时,「系统能翻墙」只说明宿主机侧链路大致可用;docker pull 是否仍超时,取决于 Docker 引擎是否把 HTTP/HTTPS 代理指到可达的宿主机端口、是否正确处理 WSL2 或虚拟机下的回环语义,以及容器内构建与运行是否单独继承了代理环境变量。按本文四层拆开配置后,多数镜像仓库访问问题可以从「链路上根本没走 Clash」缩小到「规则或节点」层面。若你希望在一套图形客户端里统一管理订阅、规则与 TUN,可从本站 下载页面 获取适合你系统的版本,再按上文对接 Docker。→ 立即免费下载 Clash,开启流畅上网新体验
与 WSL2 虚拟网卡、默认路由、MTU 相关的「宿主与 WSL 同时断网」类问题,请优先阅读 Windows 11 上 Clash 与 WSL2 路由与 MTU 排障;本文聚焦 Docker 引擎与镜像拉取代理,与之互补。