基于python:3.9的Docker镜像构建失败,报exec format error错误
问题描述
基于python:3.9构建Flask应用基础镜像,2022年9月12日的构建版本可正常运行,但近期重新构建时,最后一条ONBUILD RUN命令执行失败,报错fork/exec /bin/sh: exec format error,怀疑是python:3.9镜像更新导致该问题。
基础镜像Dockerfile
######################## # Base Image Section # ######################## # # Creates an image with the common requirements for a flask app pre-installed # Start with a smol OS FROM python:3.9 # Install basic requirements RUN apt-get -q update -o Acquire::Languages=none && apt-get -yq install --no-install-recommends \ apt-transport-https \ ca-certificates && \ apt-get autoremove -yq && apt-get clean && rm -rf "/var/lib/apt/lists"/* # Install CA certs # Prefer the mirror for package downloads COPY ["ca_certs/*.crt", "/usr/local/share/ca-certificates/"] RUN update-ca-certificates && \ mv /etc/apt/sources.list /etc/apt/sources.list.old && \ printf 'deb https://mirror.company.com/debian/ buster main contrib non-free\n' > /etc/apt/sources.list && \ cat /etc/apt/sources.list.old >> /etc/apt/sources.list # Equivalent to `cd /app` WORKDIR /app # Fixes a host of encoding-related bugs ENV LC_ALL=C.UTF-8 # Tells `apt` and others that no one is sitting at the keyboard ENV DEBIAN_FRONTEND=noninteractive # Set a more helpful shell prompt ENV PS1='[\u@\h \W]\$ ' ##################### # ONBUILD Section # ##################### # # ONBUILD commands take effect when another image is built using this one as a base. # Ref: https://docs.docker.com/engine/reference/builder/#onbuild # # # And that's it! The base container should have all your dependencies and ssl certs pre-installed, # and will copy your code over when used as a base with the "FROM" directive. ONBUILD ARG BUILD_VERSION ONBUILD ARG BUILD_DATE # Copy our files into the container ONBUILD ADD . . # pre_deps: packages that need to be installed before code installation and remain in the final image ONBUILD ARG pre_deps # build_deps: packages that need to be installed before code installation, then uninstalled after ONBUILD ARG build_deps # COMPILE_DEPS: common packages needed for building/installing Python packages. Most users won't need to adjust this, # but you could specify a shorter list if you didn't need all of these. ONBUILD ARG COMPILE_DEPS="build-essential python3-dev libffi-dev libssl-dev python3-pip libxml2-dev libxslt1-dev zlib1g-dev g++ unixodbc-dev" # ssh_key: If provided, writes the given string to ~/.ssh/id_rsa just before Python package installation, # and deletes it before the layer is written. ONBUILD ARG ssh_key # If our python package is installable, install system packages that are needed by some python libraries to compile # successfully, then install our python package. Finally, delete the temporary system packages. ONBUILD RUN \ if [ -f setup.py ] || [ -f requirements.txt ]; then \ install_deps="$pre_deps $build_deps $COMPILE_DEPS" && \ uninstall_deps=$(python3 -c 'all_deps=set("'"$install_deps"'".split()); to_keep=set("'"$pre_deps"'".split()); print(" ".join(sorted(all_deps-to_keep)), end="")') && \ apt-get -q update -o Acquire::Languages=none && apt-get -yq install --no-install-recommends $install_deps && \ if [ -n "${ssh_key}" ]; then \ mkdir -p ~/.ssh && chmod 700 ~/.ssh && printf "%s\n" "${ssh_key}" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa && \ printf "%s\n" "StrictHostKeyChecking=no" > ~/.ssh/config && chmod 600 ~/.ssh/config || exit 1 ; \ fi ; \ if [ -f requirements.txt ]; then \ pip3 install --no-cache-dir --compile -r requirements.txt || exit 1 ; \ elif [ -f setup.py ]; then \ pip3 install --no-cache-dir --compile --editable . || exit 1 ; \ fi ; \ if [ -n "${ssh_key}" ]; then \ rm -rf ~/.ssh || exit 1 ; \ fi ; \ fi
错误日志
DEBU[0280] Deleting in layer: map[] INFO[0281] Cmd: /bin/sh INFO[0281] Args: [-c if [ -f setup.py ] || [ -f requirements.txt ]; then install_deps="$pre_deps $build_deps $COMPILE_DEPS" && uninstall_deps=$(python3 -c 'all_deps=set("'"$install_deps"'".split()); to_keep=set("'"$pre_deps"'".split()); print(" ".join(sorted(all_deps-to_keep)), end="")') && apt-get -q update -o Acquire::Languages=none && apt-get -yq install --no-install-recommends $install_deps && if [ -n "${ssh_key}" ]; then mkdir -p ~/.ssh && chmod 700 ~/.ssh && printf "%s\n" "${ssh_key}" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa && printf "%s\n" "StrictHostKeyChecking=no" > ~/.ssh/config && chmod 600 ~/.ssh/config || exit 1 ; fi ; if [ -f requirements.txt ]; then pip3 install --no-cache-dir --compile -r requirements.txt || exit 1 ; elif [ -f setup.py ]; then pip3 install --no-cache-dir --compile --editable . || exit 1 ; fi ; if [ -n "${ssh_key}" ]; then rm -rf ~/.ssh || exit 1 ; fi ; fi] INFO[0281] Running: [/bin/sh -c if [ -f setup.py ] || [ -f requirements.txt ]; then install_deps="$pre_deps $build_deps $COMPILE_DEPS" && uninstall_deps=$(python3 -c 'all_deps=set("'"$install_deps"'".split()); to_keep=set("'"$pre_deps"'".split()); print(" ".join(sorted(all_deps-to_keep)), end="")') && apt-get -q update -o Acquire::Languages=none && apt-get -yq install --no-install-recommends $install_deps && if [ -n "${ssh_key}" ]; then mkdir -p ~/.ssh && chmod 700 ~/.ssh && printf "%s\n" "${ssh_key}" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa && printf "%s\n" "StrictHostKeyChecking=no" > ~/.ssh/config && chmod 600 ~/.ssh/config || exit 1 ; fi ; if [ -f requirements.txt ]; then pip3 install --no-cache-dir --compile -r requirements.txt || exit 1 ; elif [ -f setup.py ]; then pip3 install --no-cache-dir --compile --editable . || exit 1 ; fi ; if [ -n "${ssh_key}" ]; then rm -rf ~/.ssh || exit 1 ; fi ; fi] error building image: error building stage: failed to execute command: starting command: fork/exec /bin/sh: exec format error
解决方案
这个错误核心原因是CPU架构不兼容:python:3.9镜像的滚动tag会自动拉取最新版本,而新版镜像可能默认使用了与当前构建机器不同的CPU架构(比如Apple Silicon M系列机器上默认拉取arm64架构镜像,而之前的构建基于amd64;或者反之)。
具体修复方法
锁定镜像架构
在基础镜像的FROM指令中明确指定架构,比如需要amd64架构:FROM --platform=linux/amd64 python:3.9若构建机器是arm64架构,则指定
linux/arm64。构建时指定架构
执行构建命令时通过--platform参数强制指定架构:docker build --platform=linux/amd64 -t your-image-name .锁定具体镜像版本
使用2022年9月前后发布的python:3.9具体版本tag,避免滚动tag自动更新,比如python:3.9.16(该版本发布于2022年9月):FROM python:3.9.16开启跨架构模拟
若使用Docker Desktop,在设置中开启"Rosetta for x86/amd64 emulation on Apple Silicon"(针对M系列芯片),确保Docker支持跨架构镜像的运行和构建。
内容的提问来源于stack exchange,提问作者NPatel
相关产品推荐
相关产品推荐

