Apple Silicon M1芯片Docker构建Python应用报错排查方案
在搭载Apple Silicon M1芯片的设备上对集成了第三方CLI工具plastimatch的Flask应用做容器化时,选用ubuntu:18.04作为基础镜像——若使用更高版本的Ubuntu镜像构建,会提示“no installation candidate was found”错误,且完全一致的构建流程在x86架构Linux服务器上可正常执行。
本地venv虚拟环境完成应用开发后,启动容器构建流程时出现如下报错:
#16 22.37 note: This error originates from a subprocess, and is likely not a problem with pip.
#16 22.37 ERROR: Failed building wheel for pylibjpeg-libjpeg
#16 22.37 Failed to build pylibjpeg-openjpeg pylibjpeg-libjpeg
#16 22.37 ERROR: Could not build wheels for pylibjpeg-openjpeg, pylibjpeg-libjpeg, which is required to install pyproject.toml-based projects
上述报错涉及的pylibjpeg-openjpeg、pylibjpeg-libjpeg是封装了不同C++图像处理库的Python依赖,仅在本地M1设备构建时失败,相同构建流程在Linux服务器运行无异常。
本次构建使用的Dockerfile与requirements.txt内容如下(依赖暂未指定具体版本):
Dockerfile
FROM ubuntu:18.04 as base RUN apt-get update -y && apt-get install -y && apt-get upgrade -y RUN apt-get install -y software-properties-common RUN add-apt-repository ppa:deadsnakes/ppa RUN apt-get install -y python3.8 python3-pip RUN rm /usr/bin/python3 && ln -s /usr/bin/python3.8 /usr/bin/python3 RUN apt-get install -y \ plastimatch \ zlib1g \ cmake WORKDIR /app COPY requirements.txt requirements.txt RUN python3 -m pip install -U --force-reinstall pip RUN pip3 install --upgrade pip setuptools wheel RUN pip3 install -r requirements.txt ENV LC_ALL=C.UTF-8 ENV LANG=C.UTF-8 FROM base as upload-dev RUN echo "Building dev version" COPY requirements_dev.txt requirements_dev.txt RUN pip3 install -r requirements_dev.txt COPY . .
requirements.txt
python-dotenv cython pynrrd flask-cors Flask Werkzeug httplib2 numpy pydicom highdicom dicomweb-client
根因定位
该问题属于Apple Silicon设备容器化的典型架构兼容问题:
- 部分第三方Python依赖没有提供适配ARM64(M1系列芯片对应架构)的预编译wheel包,当pip找不到对应架构的预编译包时,会自动拉取源码在本地通过编译器编译安装
- 这类核心逻辑为C++实现的依赖,在M1设备的容器编译环境中会出现编译崩溃,最终导致构建流程中断
简易修复方案
直接在Dockerfile的基础镜像声明中,强制指定使用linux/amd64架构镜像即可解决问题,修改后的基础镜像行如下:
FROM --platform=linux/amd64 ubuntu:18.04 as base
该方案通过系统内置的Rosetta 2转译层运行x86架构镜像,构建和容器运行速度会略低于原生ARM架构镜像,但性能表现足以覆盖绝大多数本地开发场景的使用需求。
内容的提问来源于stack exchange,提问作者PaulE818

