最小 SciPy Dockerfile

Minimal SciPy Dockerfile

我有一个如下所示的 Dockerfile,省略了应用程序代码:

FROM python:3
# Binary dependencies
RUN apt update && apt install -y gfortran libopenblas-dev liblapack-dev
# Wanted Python packages
RUN python3 -m pip install mysqlclient numpy scipy pandas matplotlib

它工作正常,但生成的图像大小为 1.75 GB(而代码约为 50 MB)。我怎样才能减少这么大的体积??

我也尝试过使用 Alpine Linux,像这样:

FROM python:3-alpine
# Binary dependencies for numpy & scipy; though second one doesn't work anyway
RUN apk add --no-cache --virtual build-dependencies \
    gfortran gcc g++ libstdc++ \
    musl-dev lapack-dev freetype-dev python3-dev
# For mysqlclient
RUN apk --no-cache add mariadb-dev
# Wanted Python packages
RUN python3 -m pip install mysqlclient numpy scipy pandas matplotlib

但是Alpine会导致许多不同的奇怪错误。上层代码错误:

File "scipy/odr/setup.py", line 28, in configuration
    blas_info['define_macros'].extend(numpy_nodepr_api['define_macros'])
KeyError: 'define_macros'

那么,如何获得包含上述软件包的 Python 3 的最小可能(或至少更小)图像?

您可以采取多种措施来缩小 Docker 图片。

  1. 使用 python:3-slim Docker 图像作为基础。 -slim 图像不包括编译软件所需的包。
    • 固定 Python 版本,比如说 3.8。有些软件包还没有 python 3.9 的 wheel 文件,因此您可能需要编译它们。通常,使用更具体的标签是一种很好的做法,因为 python:3-slim 标签会在不同的时间点指向不同版本的 python。
  2. 也可以省略gfortranlibopenblas-devliblapack-dev的安装。这些包是构建 numpy/scipy 所必需的,但是如果您安装 pre-compiled 的 wheel 文件,则不需要编译任何代码。
  3. pip install中使用--no-cache-dir禁用缓存。如果您不包括它,那么 pip 的缓存将计入 Docker 图像大小。
  4. mysqlclient 没有 linux 个轮子,因此您必须编译它。您可以安装构建依赖项、安装包,然后在单个 RUN 指令中删除构建依赖项。请记住,libmariadb3 是此包的运行时依赖项。

这是一个 Docker 文件,它实现了上述建议。它使 Docker 图像大 354 MB。

FROM python:3.8-slim

# Install mysqlclient (must be compiled).
RUN apt-get update -qq \
    && apt-get install --no-install-recommends --yes \
        build-essential \
        default-libmysqlclient-dev \
        # Necessary for mysqlclient runtime. Do not remove.
        libmariadb3 \
    && rm -rf /var/lib/apt/lists/* \
    && python3 -m pip install --no-cache-dir mysqlclient \
    && apt-get autoremove --purge --yes \
        build-essential \
        default-libmysqlclient-dev

# Install packages that do not require compilation.
RUN python3 -m pip install --no-cache-dir \
      numpy scipy pandas matplotlib

使用 alpine linux 是个好主意,但 alpine 使用 muslc 而不是 glibc,因此它与大多数 pip wheels 不兼容。结果是您必须编译 numpy/scipy.