在AWS EC2上通过docker-compose构建Python Wheel时卡住
问题分析与解决方案
首先,你遇到的这个情况确实有点反直觉——理论上Docker应该提供一致的构建环境,但实际还是会受宿主机环境的影响,我来拆解可能的原因和对应的解决思路:
可能的卡住原因
1. EC2实例的网络/资源限制
- 网络层面:虽然Docker容器内有自己的网络栈,但如果EC2实例的安全组/VPC配置限制了对外访问(比如没有开放80/443端口到PyPI源或编译依赖的下载地址),pip在尝试下载lxml的编译依赖(比如libxml2、libxslt的源码包)时会卡住,没有报错只是一直等待连接。另外,有些地区的EC2实例访问PyPI的速度极慢,甚至出现连接超时但没有抛出明显错误的情况。
- 资源层面:你提到排除了性能问题,但如果是使用t2.micro这类低配实例,CPU/内存资源不足会导致编译过程极慢——lxml的源码编译需要大量CPU运算,低配实例可能需要十几到几十分钟,但2小时肯定是异常的。另外,EBS卷的IO性能不足也会拖慢编译时的磁盘读写步骤。
2. 基础镜像与宿主机发行版的适配问题
虽然Docker版本一致,但你在本地用的基础镜像(比如ubuntu:20.04)和EC2上的可能隐含差异?或者Ubuntu18.04宿主机上的Docker在拉取基础镜像时,默认用的是适配18.04的镜像变体?lxml的编译依赖于系统级的libxml2和libxslt库,Ubuntu18.04的库版本比20.04旧,pip无法使用预编译的binary wheel,只能从源码从头编译,这个过程比直接安装二进制包慢很多,甚至可能因为依赖版本不兼容出现隐性卡住的情况。
3. pip版本或依赖源的问题
如果你的Dockerfile里没有指定pip的版本,不同环境下的pip版本可能存在差异。旧版本的pip在处理某些依赖的编译时可能存在bug,导致无限等待。另外,默认的PyPI源在EC2上可能不稳定,换成国内镜像源(比如阿里云、清华)可能解决下载卡住的问题。
合理等待时长
正常情况下,哪怕是在低配EC2实例上编译lxml,也不应该超过30分钟。你已经等待了2小时,基本可以确定是卡住而非单纯的慢,建议终止构建排查问题。
为什么Docker版本一致仍受宿主机影响?
Docker的“一致性”是指容器运行时的环境一致,但构建过程还是会依赖宿主机的几个关键因素:
- 资源分配:容器能使用的CPU、内存、磁盘IO都是宿主机分配的,低配宿主机直接限制了容器的构建速度。
- 网络环境:容器的网络依赖宿主机的网络配置,安全组、NAT网关、DNS解析等都是宿主机层面控制的,这些配置异常会导致容器内的网络请求卡住。
- 内核与系统库兼容:虽然容器有自己的用户空间,但内核是共享宿主机的,不同版本的内核可能影响编译过程中的系统调用;另外,如果使用了
--privileged这类特权模式,宿主机的系统库也可能渗透到容器内,影响依赖编译。
快速排查建议
- 先检查EC2实例的安全组是否允许对外访问80/443端口,测试容器内能否正常访问PyPI:
docker run --rm python:3.9 pip install lxml -v,看输出是否卡在下载步骤。 - 在Dockerfile中提前安装系统级依赖,避免源码编译:
RUN apt-get update && apt-get install -y libxml2-dev libxslt1-dev - 更换pip源,比如在Dockerfile中添加:
RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple - 尝试升级pip到最新版本:
RUN pip install --upgrade pip后再安装requirements.txt
内容的提问来源于stack exchange,提问作者blitz
相关产品推荐
相关产品推荐

