最小 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 图片。
- 使用
python:3-slim
Docker 图像作为基础。 -slim
图像不包括编译软件所需的包。
- 固定 Python 版本,比如说 3.8。有些软件包还没有 python 3.9 的 wheel 文件,因此您可能需要编译它们。通常,使用更具体的标签是一种很好的做法,因为
python:3-slim
标签会在不同的时间点指向不同版本的 python。
- 也可以省略
gfortran
、libopenblas-dev
、liblapack-dev
的安装。这些包是构建 numpy/scipy 所必需的,但是如果您安装 pre-compiled 的 wheel 文件,则不需要编译任何代码。
- 在
pip install
中使用--no-cache-dir
禁用缓存。如果您不包括它,那么 pip 的缓存将计入 Docker 图像大小。
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.
我有一个如下所示的 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 图片。
- 使用
python:3-slim
Docker 图像作为基础。-slim
图像不包括编译软件所需的包。- 固定 Python 版本,比如说 3.8。有些软件包还没有 python 3.9 的 wheel 文件,因此您可能需要编译它们。通常,使用更具体的标签是一种很好的做法,因为
python:3-slim
标签会在不同的时间点指向不同版本的 python。
- 固定 Python 版本,比如说 3.8。有些软件包还没有 python 3.9 的 wheel 文件,因此您可能需要编译它们。通常,使用更具体的标签是一种很好的做法,因为
- 也可以省略
gfortran
、libopenblas-dev
、liblapack-dev
的安装。这些包是构建 numpy/scipy 所必需的,但是如果您安装 pre-compiled 的 wheel 文件,则不需要编译任何代码。 - 在
pip install
中使用--no-cache-dir
禁用缓存。如果您不包括它,那么 pip 的缓存将计入 Docker 图像大小。 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.