Gitlab Runner CI部署安装pandas时numpy构建报错求解
通过GitLab CI配置调用GitLab Runner自动化部署Python编写的AWS CDK应用,故障触发点为cdk synth CloudFormation模板合成阶段,新增pandas依赖前流水线可无错运行。
cdk-synth: stage: cdk-synth cache: [] variables: CDK_PREFIX: $CDK_PREFIX tags: - aws-cdk image: node:14-alpine before_script: - apk add --no-cache python3 py3-pip - npm install -g aws-cdk@2.15.0 - npm install -g cdk-assume-role-credential-plugin - python3 -m venv .venv - source .venv/bin/activate - pip install --upgrade pip - pip install -r requirements.txt script: - echo $CDK_PREFIX and "$CDK_PREFIX" - cdk synth
aws-cdk-lib==2.15.0 constructs>=10.0.0,<11.0.0 urllib3==1.26.8 requests==2.27.1 boto3==1.20.51 pandas==1.4.0
Collecting pandas==1.4.0 Downloading pandas-1.4.0.tar.gz (4.9 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.9/4.9 MB 93.8 MB/s eta 0:00:00 Installing build dependencies: started Installing build dependencies: finished with status 'error' error: subprocess-exited-with-error ERROR: Could not build wheels for numpy, which is required to install pyproject.toml-based projects
已尝试操作:调整依赖版本、升级pip,检索信息提示故障可能与cryptography包存在依赖关联,但重装pip后问题未解决。
当前CI使用node:14-alpine作为基础镜像,Alpine Linux使用musl libc,pandas 1.4.0依赖的numpy版本没有提供适配musl libc的预编译wheel包,pip只能拉取源码本地编译;但原有配置仅安装了python3和py3-pip,缺少编译Python C扩展所需的编译工具链、系统头文件和数值计算依赖,导致numpy编译失败。所谓和cryptography的关联本质是cryptography同样需要C编译环境,只要缺编译依赖,安装这类带C扩展的包都会报错,并非包之间的依赖冲突。
方案1:补全Alpine镜像下的编译依赖(改动最小)
修改before_script中的apk安装命令,补全编译numpy、pandas、cryptography所需的系统依赖:
# 替换原有apk add行 - apk add --no-cache python3 py3-pip gcc g++ python3-dev musl-dev openblas-dev libffi-dev openssl-dev
依赖说明:
gcc/g++:C/C++编译工具链python3-dev:Python C扩展开发头文件musl-dev:Alpine的musl libc开发头文件openblas-dev:pandas/numpy依赖的线性代数计算库libffi-dev/openssl-dev:cryptography、boto3等包依赖的系统库
补全后pip即可正常完成numpy、pandas的源码编译安装。
方案2:更换基础镜像(编译速度更快,稳定性更高)
放弃Alpine基础镜像,改用Debian系的Python基础镜像,再在镜像内通过apt安装对应版本的Node.js运行CDK。这类镜像下pandas、numpy、cryptography都有现成的manylinux预编译wheel包,无需本地编译,安装速度更快也不会出现编译依赖缺失问题。
修改后的作业配置参考:
cdk-synth: stage: cdk-synth cache: [] variables: CDK_PREFIX: $CDK_PREFIX tags: - aws-cdk image: python:3.9-slim before_script: # 安装Node.js和基础依赖 - apt-get update && apt-get install -y --no-install-recommends ca-certificates nodejs npm - rm -rf /var/lib/apt/lists/* # 原有CDK和Python依赖安装逻辑 - npm install -g aws-cdk@2.15.0 - npm install -g cdk-assume-role-credential-plugin - python3 -m venv .venv - source .venv/bin/activate - pip install --upgrade pip - pip install -r requirements.txt script: - echo $CDK_PREFIX and "$CDK_PREFIX" - cdk synth
如果默认apt源的Node.js版本不符合CDK运行要求,可自行匹配对应版本的Node安装方式即可。
可选优化
执行pip安装时添加--only-binary=:all:参数,强制pip只安装预编译wheel包,找不到对应包时直接报错,避免无意义的长时间源码编译等待,快速定位依赖适配问题:
- pip install -r requirements.txt --only-binary=:all:
内容的提问来源于stack exchange,提问作者RAH

