本文要点
- docker pull 主要由 Docker daemon 访问 registry,给当前终端设置代理不一定能让 daemon 生效。
- ~/.docker/config.json 的 proxies.default 会为新容器和新 build 注入代理变量,但不会改已有容器,也不是 daemon 代理。
- 构建时优先使用预定义代理 build arguments,不要在 Dockerfile 用 ENV 固化带凭据的代理地址。
- NO_PROXY 应按实际内网域名、IP 与端口验证,不能照抄一份模板后假设所有工具语义一致。
- 排错时分别验证 registry 拉取、build 下载和容器运行三条路径,避免改对一层却测试另一层。
先定位:失败发生在哪一层
如果 docker pull 失败,先检查 daemon 到 registry 的路径;如果 Dockerfile 中下载依赖失败,检查 build 代理;如果镜像能构建但程序运行后访问外网失败,检查容器 runtime 环境。Docker CLI、daemon、build 和容器是四个不同的配置边界。
先保存完整命令、错误时间、目标域名、状态码,以及是否出现 DNS、连接超时、TLS 或 407。可结合 <a href="/resources/proxy-connection-troubleshooting-checklist">代理连接失败排查清单</a>判断网络层,不要一开始就同时改四处配置。
docker pull:检查 daemon 代理
docker pull、登录 registry 和镜像清单请求通常由 Docker daemon 发起。在 Linux Engine 上应按 Docker 官方 daemon 代理方式配置并重启 daemon;Docker Desktop 则在应用设置中管理代理。只在 shell 中导出 HTTP_PROXY,可能只影响 CLI 自身或其子进程。
验证时先拉一个允许访问的小镜像,再检查 daemon 日志中的目标域名与错误层级。企业网络还应把私有 registry、内部镜像缓存和本地服务加入经过审核的 NO_PROXY,避免内部流量错误绕远。
docker build:用构建参数,不要写进镜像
Docker 支持在 ~/.docker/config.json 的 proxies.default 中为新 build 自动提供 HTTP_PROXY、HTTPS_PROXY 和 NO_PROXY,也可以临时使用 --build-arg。预定义代理参数不会因为被引用而自动写入最终镜像历史,但仍不应在构建输出里打印真实凭据。
不要在 Dockerfile 使用 ENV HTTP_PROXY=... 固化代理。官方明确警告,代理变量可能包含敏感信息,固化后会进入镜像配置,可能被远程 API、inspect 或后续提交读取。需要下载私有依赖时,优先使用构建秘密或受控 CI 注入。
容器运行:新配置不影响旧容器
Docker CLI 配置中的 proxies.default 会把代理变量加入新容器;修改 config.json 后,已创建的容器不会自动更新。需要重新创建容器,而不是只 restart。Compose 也应检查最终展开配置,确认变量来自预期环境。
用 docker inspect 只核对变量名和是否存在,输出与工单中必须遮盖用户名、密码和 token。然后在容器内分别验证 DNS、TCP、TLS 和目标响应;宿主机成功不代表容器网络命名空间与 CA 信任相同。
NO_PROXY 为什么经常不生效
NO_PROXY 没有跨工具统一的完整标准,不同客户端对前导点、通配符、CIDR、端口和大小写变量的处理可能不同。先列出必须直连的 registry、内部域名、回环地址和服务网段,再用实际镜像内的 HTTP 客户端逐项验证。
不要把过大的域名后缀或全部内网段随意加入绕过列表,这会扩大直连和数据暴露面。也不要把外部 AI API 域名加入 NO_PROXY 后仍期待它经过代理;配置目标必须与流量策略一致。
三条路径的验证清单
依次验证:一,daemon 能否解析并连接 registry;二,build 在不泄露凭据的情况下能否下载依赖;三,新建容器能否读取预期变量并访问允许目标;四,内部域名是否按 NO_PROXY 直连;五,镜像历史、inspect 输出、CI 日志和错误回报中是否出现真实凭据。每次只改变一层。
团队需要稳定访问海外 registry、包仓库和开发文档时,可以 <a href="/" target="_blank" rel="noopener noreferrer">访问 PuppyIP 官网</a>了解固定网络出口。网络服务不替代 registry 权限、许可证、企业安全策略或秘密管理。
资料来源
常见问题
为什么设置 HTTP_PROXY 后 docker pull 仍失败?
docker pull 的 registry 请求通常由 daemon 发出,应检查 daemon 或 Docker Desktop 的代理,而不只是当前 shell。
修改 ~/.docker/config.json 后旧容器会生效吗?
不会。官方说明该配置影响新容器和新 build,已有容器需要重新创建。
可以在 Dockerfile 用 ENV 保存代理吗?
不建议。代理地址常含凭据,ENV 会把它固化进镜像配置,增加泄露风险。
Docker build 临时代理怎么传?
可以使用官方支持的预定义代理 build arguments,或由 CLI 配置为新 build 注入;不要在构建日志输出真实值。
宿主机能联网,为什么容器仍超时?
容器的 DNS、网络命名空间、代理变量和 CA 信任可能不同,应在容器内逐层验证。
NO_PROXY 可以直接复制网上模板吗?
不应直接照抄。不同工具语义可能不同,应按实际内部域名、IP、端口和所用客户端逐项测试。