如何使用 pipenv 为 python 应用制作轻量级 docker 图像
How to make lightweight docker image for python app with pipenv
我可以使用以下简单的 Dockerfile
:
为我的 python 应用生成工作图像
FROM python:3.7
WORKDIR /myapp
COPY Pipfile* ./
RUN pip install pipenv
RUN pipenv install --system --deploy
COPY src .
CMD ["python3", "app.py"]
但是,它会生成约 1 GB 的映像,其中可能包含临时文件,并且部署起来很繁重。而且我只需要完整的 python 图像用于构建目的。我的应用程序可以在 alpine 变体上成功 运行,所以我可以进行两次 Dockerfile
:
FROM python:3.7 as builder
COPY Pipfile* ./
RUN pipenv lock --requirements > requirements.txt
RUN python3 -m venv /venv
RUN /venv/bin/pip install --upgrade pip
RUN /venv/bin/pip install -r requirements.txt
FROM python:3.7-alpine
COPY --from=builder /venv /venv
WORKDIR /myapp
COPY src .
CMD ["/venv/bin/python3", "app.py"]
到目前为止一切顺利,它也可以工作,缩小了 6 倍。但是这个方案被认为是一些"stub",有一些缺点:
- 它有不必要的额外
COPY --from=builder
步骤
- 它不使用
pipenv
但还需要 pip
来安装(+1 额外步骤,pipenv lock
+pip install
总是比 pipenv install
)
- 它不会在系统范围内安装,而是安装到
/venv
中,这应该避免在容器中安装
- 次要:构建会更多地污染中间图像缓存,并且需要下载两个图像变体..
如何结合这两种方法,获得具有 pipenv
的基于 alpine 的轻量级图像,而没有提到的缺点?
或者您可以提供您的制作 Dockerfile
想法吗?
怎么样,
FROM python:3.7-alpine
WORKDIR /myapp
COPY Pipfile* ./
RUN pip install --no-cache-dir pipenv && \
pipenv install --system --deploy --clear
COPY src .
CMD ["python3", "app.py"]
- 它使用较小的 Alpine 版本。
- 使用
--no-cache-dir
选项 pip
和 --clear
选项 pipenv
,您不会留下任何不必要的缓存文件。
- 您还部署在 venv 之外。
您还可以在同一 RUN
命令中的 pipenv install --system --deploy --clear
之后添加 && pip uninstall pipenv -y
以消除 pipenv
拍摄的 space 如果额外的图像尺寸困扰您.
当您需要 ciso8601
或某些需要构建过程的库时,问题就来了。构建工具未 "incorporated" 到 slim
和 alpine
变体中,以实现较小的占用空间。
因此,要安装 deps,您必须:
- 安装构建工具
- 从Pipfile.lock系统范围部署依赖项
- 卸载构建工具并清理缓存
并在单个 RUN
层中执行这 3 个操作,如下所示:
FROM python:3.7-slim
WORKDIR /app
# both files are explicitly required!
COPY Pipfile Pipfile.lock ./
RUN pip install pipenv && \
apt-get update && \
apt-get install -y --no-install-recommends gcc python3-dev libssl-dev && \
pipenv install --deploy --system && \
apt-get remove -y gcc python3-dev libssl-dev && \
apt-get autoremove -y && \
pip uninstall pipenv -y
COPY app ./
CMD ["python", "app.py"]
- 操纵构建系统将花费您大约 300MiB 和一些额外的时间
- 卸载 pipenv 可以再节省 20MiB(占最终大小的 10%)。
- 分隔
RUN
命令不会从图层中删除数据,并且会生成约 500MiB 的图像。这是 docker 细节。
所以这将导致完美工作 ~200MiB 大小的图像,即
- 比原始
python:3.7
少 5 倍,(即 >1.0GiB)
- 没有 alpine 不兼容(这些通常与 glibc 替换有关)
当时,我们可以接受 slim
(debian buster
) 构建变体,更喜欢 slim
而不是 alpine
(为了大多数兼容性)。如果你真的想进一步优化尺寸,我建议你看看这些家伙的一些优秀构建:
我正在使用 micropipenv 进行作业,它自称是
A lightweight wrapper for pip to support requirements.txt, Pipenv and Poetry lock files or converting them to pip-tools compatible output. Designed for containerized Python applications but not limited to them.
从中创建的图像如下所示。
由于 alpine 基础图像缺少 toml 解析器,我们必须使用包含 toml 附加功能的 micropipenv 版本(micropipenv[toml]
而不是 micropipenv
)。
FROM python:3.9-alpine
WORKDIR /myapp
COPY Pipfile Pipfile.lock ./
RUN \
# Install dependencies
&& pip install --no-cache-dir micropipenv[toml] \
&& micropipenv install --deploy \
&& pip uninstall -y micropipenv[toml]
COPY src .
CMD ["python3", "app.py"]
我可以使用以下简单的 Dockerfile
:
FROM python:3.7
WORKDIR /myapp
COPY Pipfile* ./
RUN pip install pipenv
RUN pipenv install --system --deploy
COPY src .
CMD ["python3", "app.py"]
但是,它会生成约 1 GB 的映像,其中可能包含临时文件,并且部署起来很繁重。而且我只需要完整的 python 图像用于构建目的。我的应用程序可以在 alpine 变体上成功 运行,所以我可以进行两次 Dockerfile
:
FROM python:3.7 as builder
COPY Pipfile* ./
RUN pipenv lock --requirements > requirements.txt
RUN python3 -m venv /venv
RUN /venv/bin/pip install --upgrade pip
RUN /venv/bin/pip install -r requirements.txt
FROM python:3.7-alpine
COPY --from=builder /venv /venv
WORKDIR /myapp
COPY src .
CMD ["/venv/bin/python3", "app.py"]
到目前为止一切顺利,它也可以工作,缩小了 6 倍。但是这个方案被认为是一些"stub",有一些缺点:
- 它有不必要的额外
COPY --from=builder
步骤 - 它不使用
pipenv
但还需要pip
来安装(+1 额外步骤,pipenv lock
+pip install
总是比pipenv install
) - 它不会在系统范围内安装,而是安装到
/venv
中,这应该避免在容器中安装 - 次要:构建会更多地污染中间图像缓存,并且需要下载两个图像变体..
如何结合这两种方法,获得具有 pipenv
的基于 alpine 的轻量级图像,而没有提到的缺点?
或者您可以提供您的制作 Dockerfile
想法吗?
怎么样,
FROM python:3.7-alpine
WORKDIR /myapp
COPY Pipfile* ./
RUN pip install --no-cache-dir pipenv && \
pipenv install --system --deploy --clear
COPY src .
CMD ["python3", "app.py"]
- 它使用较小的 Alpine 版本。
- 使用
--no-cache-dir
选项pip
和--clear
选项pipenv
,您不会留下任何不必要的缓存文件。 - 您还部署在 venv 之外。
您还可以在同一 RUN
命令中的 pipenv install --system --deploy --clear
之后添加 && pip uninstall pipenv -y
以消除 pipenv
拍摄的 space 如果额外的图像尺寸困扰您.
当您需要 ciso8601
或某些需要构建过程的库时,问题就来了。构建工具未 "incorporated" 到 slim
和 alpine
变体中,以实现较小的占用空间。
因此,要安装 deps,您必须:
- 安装构建工具
- 从Pipfile.lock系统范围部署依赖项
- 卸载构建工具并清理缓存
并在单个 RUN
层中执行这 3 个操作,如下所示:
FROM python:3.7-slim
WORKDIR /app
# both files are explicitly required!
COPY Pipfile Pipfile.lock ./
RUN pip install pipenv && \
apt-get update && \
apt-get install -y --no-install-recommends gcc python3-dev libssl-dev && \
pipenv install --deploy --system && \
apt-get remove -y gcc python3-dev libssl-dev && \
apt-get autoremove -y && \
pip uninstall pipenv -y
COPY app ./
CMD ["python", "app.py"]
- 操纵构建系统将花费您大约 300MiB 和一些额外的时间
- 卸载 pipenv 可以再节省 20MiB(占最终大小的 10%)。
- 分隔
RUN
命令不会从图层中删除数据,并且会生成约 500MiB 的图像。这是 docker 细节。
所以这将导致完美工作 ~200MiB 大小的图像,即
- 比原始
python:3.7
少 5 倍,(即 >1.0GiB) - 没有 alpine 不兼容(这些通常与 glibc 替换有关)
当时,我们可以接受 slim
(debian buster
) 构建变体,更喜欢 slim
而不是 alpine
(为了大多数兼容性)。如果你真的想进一步优化尺寸,我建议你看看这些家伙的一些优秀构建:
我正在使用 micropipenv 进行作业,它自称是
A lightweight wrapper for pip to support requirements.txt, Pipenv and Poetry lock files or converting them to pip-tools compatible output. Designed for containerized Python applications but not limited to them.
从中创建的图像如下所示。
由于 alpine 基础图像缺少 toml 解析器,我们必须使用包含 toml 附加功能的 micropipenv 版本(micropipenv[toml]
而不是 micropipenv
)。
FROM python:3.9-alpine
WORKDIR /myapp
COPY Pipfile Pipfile.lock ./
RUN \
# Install dependencies
&& pip install --no-cache-dir micropipenv[toml] \
&& micropipenv install --deploy \
&& pip uninstall -y micropipenv[toml]
COPY src .
CMD ["python3", "app.py"]