BuildKit proxy network 下 pip 和 Node.js TLS 证书失败怎么修复

先区分系统证书包与工具独立信任链,再用 BuildKit secret 临时传入受控 CA

BuildKit proxy network 中 curl 正常、pip 或 Node.js 证书校验失败时,判断信任链差异并用 secret 安全传入企业 CA。

BuildKit 开启 --proxy-network 后,如果 curl 能访问 HTTPS,而 pip 报 CERTIFICATE_VERIFY_FAILED、Node.js 报 UNABLE_TO_VERIFY_LEAF_SIGNATURE,不要先关闭 TLS 校验。这通常说明代理根证书只进入了系统证书包,但 Python 的 certifi 或 Node.js 的内置根证书没有使用同一条信任链。先确认错误只发生在 BuildKit 构建步骤,再把受控 CA 显式交给对应工具。

本文适用于企业 HTTPS 检查代理和自建 BuildKit。只读检查不会改数据。把 CA 写入镜像会改变最终镜像信任范围;把证书当普通构建参数可能进入镜像历史。默认选择是用 BuildKit secret 临时挂载 CA,并仅在需要联网的 RUN 步骤设置变量。不要使用 --trusted-host、NODE_TLS_REJECT_UNAUTHORIZED=0 或关闭证书校验。

先证明不是 DNS、代理地址或系统证书包故障

先查看构建器和失败步骤。下面命令只读;把 YOUR_BUILDER 换成真实名称。日志可能含私有仓库域名和代理地址,分享前先脱敏。

docker buildx ls
docker buildx inspect YOUR_BUILDER --bootstrap
docker buildx build --progress=plain --no-cache .

在同一个构建阶段分别测试系统工具、Python 和 Node.js。只有镜像原本已经包含这些工具时才执行,不要为了诊断改动生产镜像。

RUN curl -fsSI https://pypi.org/simple/
RUN python -c "import urllib.request; urllib.request.urlopen('https://pypi.org/simple/', timeout=10)"
RUN node -e "require('https').get('https://registry.npmjs.org/',r=>console.log(r.statusCode)).on('error',e=>{console.error(e);process.exit(1)})"

若 curl、wget 或 git 成功,而 Python/Node.js 单独失败,才符合本问题。若三者都失败,先检查代理地址、DNS、宿主机 CA 和 BuildKit 网络;若只有私有镜像仓库失败,应配置 BuildKit 的 registry CA,而不是修改 pip 或 Node.js。

结果判断下一步
curl 成功,pip/Node 失败工具未使用系统信任链显式指定 CA 文件
所有 HTTPS 都失败代理、DNS 或系统 CA 问题先修构建器基础网络
只有 registry push/pull 失败BuildKit registry CA 范围配置 buildkitd.toml 的 registry 证书
关闭代理后成功企业代理信任链未完整配置向网络管理员索取正式根 CA

用 secret 临时传入 CA

先从企业网络或安全管理员取得正式 PEM 根证书,保存为工作目录外的 company-root-ca.pem。不要从浏览器报错页随意导出未知证书。下面构建命令只把文件作为 secret 交给构建步骤,通常不会把内容写入镜像历史。

docker buildx build --secret id=proxy_ca,src=/SAFE/PATH/company-root-ca.pem --progress=plain --load -t YOUR_IMAGE:test .

Dockerfile 中把 secret 挂载到临时路径,并在同一个 RUN 内为 Python 与 Node.js 指向该文件。不同基础镜像的系统证书路径不同,因此这里不覆盖系统证书包。

# syntax=docker/dockerfile:1
RUN --mount=type=secret,id=proxy_ca,target=/run/secrets/proxy-ca.pem \
    SSL_CERT_FILE=/run/secrets/proxy-ca.pem \
    REQUESTS_CA_BUNDLE=/run/secrets/proxy-ca.pem \
    PIP_CERT=/run/secrets/proxy-ca.pem \
    NODE_EXTRA_CA_CERTS=/run/secrets/proxy-ca.pem \
    pip install --no-cache-dir -r requirements.txt && npm ci

NODE_EXTRA_CA_CERTS 是附加信任;Python 相关变量可能把默认 CA 路径替换为指定文件。如果企业 CA 文件不包含公共根证书链,Python 访问公共站点仍会失败。更稳妥的做法是由安全团队提供合并且受控的 CA bundle,或在构建阶段生成临时合并文件,不能把网上下载的证书直接加入信任。

什么时候应配置 registry CA

如果失败发生在 BuildKit 拉取基础镜像或推送镜像,而不是 Dockerfile 内的 pip/npm,应在 buildkitd.toml 为对应 registry 配置 CA。Docker 官方说明,自定义配置通过 docker buildx create --buildkitd-config 传入,证书会复制进 BuildKit 容器。该配置只解决指定镜像仓库信任,不会自动解决应用工具自己的证书库。

费用、停机和数据风险

证书排查本身通常没有单独云费用,但无缓存重建会消耗构建机 CPU、网络流量和私有仓库存储。重建 builder 会丢失该 builder 的本地缓存,不能在高峰直接删除。改变最终镜像的系统信任库会扩大所有运行时进程的信任范围,因此默认不把企业代理 CA 永久写入运行镜像。

若临时方案失败,删除 Dockerfile 中的变量和 secret 挂载,恢复上一份可构建的 Dockerfile;不要删除现有 builder。若必须新建 builder,先保留旧名称与配置,新 builder 验证通过后再切换 CI。

修复后如何验收

  1. 在启用 proxy network 的同一 builder 上,curl、pip 和 npm 三类请求都通过。
  2. 去掉 secret 后构建按预期失败,证明没有把 CA 意外写进基础镜像或缓存层。
  3. docker history --no-trunc YOUR_IMAGE:test 不出现证书正文、私密路径或代理凭据。
  4. 镜像内不存在 /run/secrets/proxy-ca.pem,运行容器仍使用原有信任策略。
  5. 记录 BuildKit 版本与 Issue 状态;上游正式修复发布后先在测试 builder 复核,再移除临时变量。

相关教程

官方与上游来源

云服务器教程Docker Swarm IPv6 overlay MTU 大 20 字节:怎样确认并安全调整2026-10-01云服务器教程Docker Swarm 29.8.0 升级后同节点宿主机 IP 端口不通:怎样取证与回退2026-09-30云服务器教程Docker 执行 buildx prune 后缓存全失效:怎样判断并恢复 BuildKit 命中2026-09-28

加入开发者交流社区

与全球开发者、运维和工作室一起交流技术、分享经验、配置、账号与最新优惠信息

  • 云平台使用交流
  • 资源优惠信息
  • 最新教程与资讯
  • 开发者经验分享
联系 Telegram 客服
加入开发者交流社区