Python 为什么多级码头工人形象比单级码头工人形象大?

Python 为什么多级码头工人形象比单级码头工人形象大?,python,docker,docker-multi-stage-build,Python,Docker,Docker Multi Stage Build,我创建了一个microservice(),它需要克隆一个git存储库来创建docker映像,带有一个单阶段docker文件最终映像有759MB: FROM python:3.7.6-slim-stretch # set the working directory to /app WORKDIR /app # copy the current directory contents into the container at /app COPY . /app RUN apt-get updat

我创建了一个microservice(),它需要克隆一个git存储库来创建docker映像,带有一个单阶段docker文件最终映像有759MB:

FROM python:3.7.6-slim-stretch

# set the working directory to /app
WORKDIR /app

# copy the current directory contents into the container at /app
COPY . /app

RUN apt-get update && apt-get install -y git \
 && pip install -r requirements.txt \
 && git clone https://github.com/tfcbertaglia/enelvo.git enelvo-src \
 && cd enelvo-src \
 && python setup.py install \
 && cd .. \
 && mv enelvo-src/enelvo enelvo \
 && rm -fr enelvo-src

EXPOSE 50051

# run app.py when the container launches
CMD ["python", "app.py"]
我尝试过使用多级构建()的方法来减少图像大小,而不使用git和apt get列表(来自更新):


问题是,在这样做之后,最终的大小变得更大(815MB)。你知道在这种情况下会出现什么问题吗?

在你运行的第一个示例中

RUN git clone https://github.com/tfcbertaglia/enelvo.git enelvo-src \
    ... \
 && rm -fr enelvo-src
COPY --from=cloner /enelvo-src /app/enelvo-src
RUN rm -fr enelvo-src
因此
enelvo src
树永远不存在于这个特定的
RUN
指令之外;在Docker可以用它构建一个层之前,它就被删除了

在第二个示例中,您正在运行

RUN git clone https://github.com/tfcbertaglia/enelvo.git enelvo-src \
    ... \
 && rm -fr enelvo-src
COPY --from=cloner /enelvo-src /app/enelvo-src
RUN rm -fr enelvo-src
Docker在第一步之后内部创建一个包含源树内容的图像层。后续的
运行rm
实际上并没有使图像变小,它只是记录了从技术上讲,从早期层存在的内容不再是文件系统的一部分

通常,使用多阶段构建的标准方法是在早期阶段尽可能多地构建,并且只
将最终结果复制到运行时映像中。对于Python包,一种可以很好地工作的方法是在包外构建一个:

来自python:3.7.6-slim-stretch-as-build
WORKDIR/构建
运行apt-get-update&&apt-get-install-y git\
&&git克隆https://github.com/tfcbertaglia/enelvo.git enelvo src
&& ...
&&python setup.py bdist#u wheel#(不是“安装”)
来自python:3.7.6-slim-stretch
WORKDIR/app
复制--from=build/build/dist/wheel/enelvo*.whl。
运行pip安装enelvo*.whl
...

能否在
apt get
语句的末尾添加
&&rm-rf/var/lib/apt/lists/*
以清除apt缓存,这将减小图像的大小。此外,还应将操作逻辑地分组到层中。运行
apt get
命令并在一个命令中安装python库没有意义您应该尝试buildkit,这将大大减少您的构建量:
export DOCKER\u buildkit=1
感谢@gold\u cy abd@jean-jacques moiroux的建议!你能解释一下第二个dockerfile如何生成更大的图像吗?我仍然无法想象为什么。这与Git无关,所以我删除了那个标签。docker映像大小取决于docker必须保存的数据量。请注意,对于从每个步骤重新启动,Docker会在运行每个命令行后保存所有修改的文件系统文件。非常感谢您的回答。这解释了很多。不幸的是,
COPY--from=build/build/dist/wheel/enelvo*.whl.
,从日志中我看到它使用的是
build/bdist.linux-x86_64/wheel
,但这也不起作用。我收到错误:
复制失败:未指定任何源文件。
。更新:实际上,RUN命令之后没有/build文件夹。通过Buildkit,我可以看到消息
无法用前端dockerfile解决。v0:无法构建LLB:lstat/var/lib/docker/overlay2/wb6jb8vrrhowlaarlj0p2aawx/merged/build/dist/wheel:没有这样的文件或目录
。它进行了一些更改:WORKDIR/app COPY--from=build/enelvo src/dist/enelvo*.whl/app和enelvo(大写E)