Docker构建时配置代理后:升级pip成功但安装requirements.txt依赖报SSL网络错误
问题根因定位
- SSL 错误触发的核心原因:代理协议配置不匹配。绝大多数企业内部代理是明文 HTTP 协议服务,不需要 TLS 加密。你当前传入的
--proxy https://myproxy:port强制 pip 按 HTTPS 协议和代理端口建立连接,会导致 TLS 握手时收到代理返回的明文 HTTP 报文,直接触发WRONG_VERSION_NUMBER报错。 - 为什么第一条 pip 升级命令能正常执行:基础镜像内置的低版本 pip 对代理链路的兼容逻辑存在缺陷,会跳过部分协议校验流程完成升级操作;但升级完成后的高版本 pip 会严格按照传入的代理参数发起请求,此时协议不匹配的问题会完全暴露。
- 为什么报错只指向 aiocontextvars 包:pip 会按 requirements.txt 的顺序依次拉取包索引,aiocontextvars 是列表里的第一个包,所有重试请求都因为 SSL 错误失败后,pip 直接抛出「找不到对应版本」的报错,后续的依赖包根本不会进入安装流程。
- 附带的配置疏漏:当前
--trusted-host仅配置了已废弃的pypi.python.org域名,而现在 PyPI 的实际包索引、文件下载域名是pypi.org、files.pythonhosted.org,所有请求都会从老域名重定向到这两个新域名,原有的可信主机配置完全覆盖不到实际请求链路。
可落地的解决方案
- 修正代理协议写法
将所有 pip 命令里的--proxy https://myproxy:port替换为--proxy http://myproxy:port。如果代理需要账号密码认证,格式调整为--proxy http://[账号]:[密码]@myproxy:port。 - 补全可信主机配置
将原有仅针对老域名的trusted-host参数扩展为覆盖所有实际请求链路的域名:--trusted-host pypi.org --trusted-host files.pythonhosted.org --trusted-host pypi.python.org - 优化代理配置的传递方式(推荐)
避免在每条 pip 命令里硬编码代理参数,直接在 docker-compose 的 build 段通过构建参数传递代理配置,减少硬编码带来的配置错误:
调整后的 docker-compose build 段:
对应的 Dockerfile 开头增加构建参数声明,让 pip 自动读取代理配置,不用在命令里重复传参:build: context: . dockerfile: ./Dockerfile network: host args: HTTP_PROXY: http://myproxy:port HTTPS_PROXY: http://myproxy:portARG HTTP_PROXY ARG HTTPS_PROXY ENV HTTP_PROXY=$HTTP_PROXY ENV HTTPS_PROXY=$HTTPS_PROXY - 修正 requirements.txt 的平台兼容问题
原文件里的win32-setctime是 Windows 平台专属包,在 Linux 容器下安装会直接报错,需要加上平台标记限制安装范围:win32-setctime==1.0.3; sys_platform == 'win32'
验证方式
修改完成后执行docker-compose build --no-cache无缓存重建镜像,观察 pip 安装阶段日志:如果不再出现 SSL 重试报错,能正常拉取所有依赖的索引文件,即说明配置生效。
内容的提问来源于stack exchange,提问作者Marco Fumagalli
相关产品推荐
相关产品推荐

