我可以为我的python应用程序生成工作图像,使用以下简单的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倍小。但这个方案被认为是一些“存根”,有一些缺点:
- 它有不必要的额外
COPY --from=builder
步骤 - 它不使用
pipenv
,但还需要pip
来安装(+1个额外步骤,pipenv lock
+pip install
总是比仅使用pipenv install
慢) - 它不会在系统范围内安装,而是安装到
/venv
中,在容器中应避免这种情况 - 次要:构建会更多地污染中间图像缓存,并且需要下载两个图像变体。
如何将这两种方法结合起来,得到基于pipenv
的轻量阿尔卑斯山图像,而不存在上述缺点?
或者你能提供你的生产Dockerfile
的想法吗?
4条答案
按热度按时间qxgroojn1#
当你需要像
ciso8601
这样的东西,或者一些需要构建过程的库时,问题就来了。构建工具没有“合并”到slim
和alpine
变体中,以减少占用空间。因此,要安装deps,您必须:
在一个
RUN
层中执行这3个操作,如下所示:RUN
命令不会从层中删除数据,并且会产生约500MiB的图像。这是docker的具体要求。因此,这将产生约200 MiB大小的完美图像,
python:3.7
小5倍(即〉1.0GiB)当时,我们对
slim
(debianbuster
)版本变体还满意,更喜欢slim
而不是alpine
(为了大部分的兼容性)。如果你真的想进一步优化大小,我建议你看看这些家伙的一些优秀版本:zfycwa2u2#
不如这样吧
1.它使用了较小的Alpine版本。
1.使用
pip
的--no-cache-dir
选项和pipenv
的--clear
选项,您将不会留下任何不必要的缓存文件。1.您还可以在venv之外部署。
您也可以在同一个
RUN
命令中,在pipenv install --system --deploy --clear
之后添加&& pip uninstall pipenv -y
,以消除pipenv
占用的空间(如果额外的图像大小让您感到困扰)。7vux5j2d3#
我使用micropipenv来完成这项工作,它将自己描述为
pip的轻量级 Package 器,支持requirements.txt、Pipenv和Poetry锁定文件或将它们转换为pip-tools兼容的输出。为容器化Python应用程序设计,但不限于此。
从它创建的映像看起来如下所示:由于alpine基础映像缺少toml解析器,我们必须使用包含toml附加项的micropipenv版本(
micropipenv[toml]
而不是micropipenv
)。5hcedyr04#
它具有不必要的额外COPY --from=builder步骤
该指令是无害的,实际上使您的最终阶段图像更加轻量级:只复制virtualenv,没有构建工具链,也没有缓存的轮子,甚至在最后阶段也没有pipenv!
它不使用pipenv,但也需要pip安装(+1额外步骤,pipenv锁+pip安装总是比只安装pipenv慢)
在构建阶段使用pipenv生成virtualenv!
它不会在系统范围内安装,而是安装到/venv中,在容器中应避免安装
虽然在docker中不使用venv是一种常见的做法,但它们仍然有一些好处。而且绝对没有缺点。不要再听人们说venv不应该在dockers中使用。Pipenv目前的建议是不要在容器https://github.com/pypa/pipenv/pull/2762中发布系统范围的安装
次要:构建会更多地污染中间图像缓存,并且需要下载两个图像变体。
只需在CI系统中优化缓存设置。
但是
“看在上帝的份上”“建造和最后阶段使用同一个平台”
两者皆可
python:3-alpine
,根据需要在构建阶段使用尽可能多的apk
包python:3
作为建筑物,用python:3-slim
作为最后阶段。它并不是那么大高山图像使用
musl
而不是libc
,这意味着python包https://peps.python.org/pep-0656/使用不同的ABI。不要将高山图像与非高山图像混合,就像不要将python:3.A图像与不同的python:3.B混合一样。否则,在构建阶段安装的某些组件将无法在最后阶段使用。