gCo*_*Coh 11 python docker dockerfile docker-multi-stage-build
我正在寻找一种使用python和Dockerfile创建多级构建的方法
即我正在尝试做的是使用几个图像创建一个Dockerfile:
第1张图片:安装所有编译时要求,并安装所有需要的python模块
第二个图像:将所有编译/构建的包从第一个图像复制到第二个图像,没有编译器本身(gcc,postgers-dev,python-dev等...)
最终的objcetive是一个较小的图像,运行python
所以问题是 - 如何'包装'在第一张图像中创建的所有已编译模块(site-packages/external libs),并以"干净"的方式将它们复制到第二张图像
gCo*_*Coh 12
好吧所以我的解决方案是使用wheel,它允许我们在第一张图像上编译,为所有依赖项创建wheel文件并在第二张图像中安装它们,而无需安装编译器
FROM python:2.7-alpine as base
RUN mkdir /svc
COPY . /svc
WORKDIR /svc
RUN apk add --update \
postgresql-dev \
gcc \
musl-dev \
linux-headers
RUN pip install wheel && pip wheel . --wheel-dir=/svc/wheels
FROM python:2.7-alpine
COPY --from=base /svc /svc
WORKDIR /svc
RUN pip install --no-index --find-links=/svc/wheels -r requirements.txt
Run Code Online (Sandbox Code Playgroud)
您可以在以下博文中看到我对此的回答
https://galnevis.wixsite.com/website/single-post/2018/02/10/Python-and-Docker-multistage-build
我推荐本文(第 2 节)中详述的方法。他使用 virtualenv,因此 pip install 将所有 python 代码、二进制文件等存储在一个文件夹下,而不是分散在整个文件系统中。然后很容易将那个文件夹复制到最终的“生产”图像。总之:
编译镜像
pip install xyz像往常一样安装系统开发包。生产图片
这是在 Docker 中使用 Python 虚拟环境的有用之处。复制虚拟环境通常很棘手,因为它需要在完全相同的 Python 构建上具有完全相同的文件系统路径,但在 Docker 中你可以保证这一点。
(这与 @mpoisot 在他们的答案中描述的基本配方相同,并且也出现在其他 SO 答案中。)
假设您正在安装psycopg PostgreSQL 客户端库。其扩展形式需要 Python C 开发库加上 PostgreSQL C 客户端库标头;但要运行它,您只需要 PostgreSQL C 运行时库。因此,在这里您可以使用多阶段构建:第一阶段使用完整的 C 工具链安装虚拟环境,最后阶段复制构建的虚拟环境,但仅包含所需的最少库。
典型的 Dockerfile 可能如下所示:
# Name the single Python image we're using everywhere.
ARG python=python:3.10-slim
# Build stage:
FROM ${python} AS build
# Install a full C toolchain and C build-time dependencies for
# everything we're going to need.
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install --no-install-recommends --assume-yes \
build-essential \
libpq-dev
# Create the virtual environment.
RUN python3 -m venv /venv
ENV PATH=/venv/bin:$PATH
# Install the Python library dependencies, including those with
# C extensions. They'll get installed into the virtual environment.
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
# Final stage:
FROM ${python}
# Install the runtime-only C library dependencies we need.
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install --no-install-recommends --assume-yes \
libpq5
# Copy the virtual environment from the first stage.
COPY --from=build /venv /venv
ENV PATH=/venv/bin:$PATH
# Copy the application in.
COPY . .
CMD ["./main.py"]
Run Code Online (Sandbox Code Playgroud)
如果您的应用程序使用Python 入口点脚本,那么您可以在第一阶段执行所有操作:RUN pip install .将应用程序复制到虚拟环境中并/venv/bin为您创建一个包装器脚本。在最后阶段您无需COPY再次申请。设置CMD以在虚拟环境之外运行包装器脚本,该环境已经位于$PATH.
再次注意,这种方法之所以有效,是因为它在两个阶段都是相同的 Python 基础映像,并且虚拟环境位于完全相同的路径上。如果是不同的Python或者不同的容器路径,移植的虚拟环境可能无法正常工作。
| 归档时间: |
|
| 查看次数: |
4883 次 |
| 最近记录: |