制作足够小的容器镜像是一项复杂的工作,尤其是 Python。我们可以使用多阶段构建过程和virtualenv来减少构建和 pip 安装的开销。然而,一些Python库使用运行时C库,我们必须克服这个问题;否则Package将无法运作。

因为之前写过《python Ta-lib的安装》,这里以TA-Lib为例来展示如何正确完成所有事情。

 1FROM python:3.7-slim AS compile-image
 2RUN apt-get update
 3RUN apt-get install -y --no-install-recommends build-essential gcc wget
 4
 5# Make sure we use the virtualenv:
 6RUN python -m venv /opt/venv
 7ENV PATH="/opt/venv/bin:$PATH"
 8
 9RUN pip install numpy
10
11# TA-Lib
12RUN wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz && \
13  tar -xvzf ta-lib-0.4.0-src.tar.gz && \
14  cd ta-lib/ && \
15  ./configure --prefix=/opt/venv && \
16  make && \
17  make install
18
19RUN pip install --global-option=build_ext --global-option="-L/opt/venv/lib" TA-Lib==0.4.16
20RUN rm -R ta-lib ta-lib-0.4.0-src.tar.gz
21
22COPY requirements.txt .
23RUN pip install -r requirements.txt
24
25FROM python:3.7-slim AS build-image
26COPY --from=compile-image /opt/venv /opt/venv
27
28# Make sure we use the virtualenv:
29ENV PATH="/opt/venv/bin:$PATH"
30ENV LD_LIBRARY_PATH="/opt/venv/lib"

有5点需要注意:

  1. 选择足够小的基础镜像;尽管如此,还是要避免使用alpine。原因由这篇文章解释:https ://pythonspeed.com/articles/alpine-docker-python/
  2. 多阶段是减少构建流程开销的好主意。此外,应用virtualenv让事情变得更容易。因此,将所有 Python 包安装到/opt/venv.
  3. 现在,我们可以尝试从源代码构建 TA-Lib。/opt/venv您还必须在配置时指定安装路径。
  4. 因为我们将默认库路径移到了/opt/venv,所以我们需要将全局选项或构建选项分配给 pip 以让它知道库路径。
  5. 最后,记得提供LD_LIRARY_PATH让 python 知道共享库在哪里的信息。

按照上述步骤,图像大小约为 250MB。这很小。

后记:

当然如果仅仅出于测试目的,也可以选择使用alpine镜像(比如在wdinwos下的wsl下运行Linux子系统跑docker),具体Dockerfile 内容类似如下:

 1FROM python:3.11.4-alpine3.17
 2
 3ENV PYTHON_TA_LIB_VERSION "0.4.26"
 4
 5USER "root"
 6WORKDIR "/tmp"
 7
 8RUN apk add --no-cache --virtual .build-deps \
 9        musl-dev \
10        linux-headers \
11        gcc \
12        g++ \
13        make \
14        curl \
15    && cd /tmp \
16    && curl -L -O http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz \
17    && tar -zxf ta-lib-0.4.0-src.tar.gz \
18    && cd ta-lib/ \
19    && ./configure --prefix=/usr \
20    && make \
21    && make install \
22    && pip3 install setuptools numpy \
23    && pip3 install ta-lib==${PYTHON_TA_LIB_VERSION} \
24    && apk del .build-deps \
25    && rm -rf /root/.cache \
26              /tmp/* \
27              /var/cache/apk/* \
28              /var/lib/apk/lists/*
29
30WORKDIR "/root"
31
32CMD ["python3"]