为什么我的Docker图像与单级版本相比具有多阶段构建?
我得到了具有多阶段构建的292 MB的图像,而单级版本为235 MB。谁能帮我理解为什么?
这是Dockerfiles。
一阶段构建:
# syntax=docker/dockerfile:1
FROM python:3.9.13-alpine3.16
WORKDIR /project
ENV FLASK_APP=run.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
多阶段构建:
# syntax=docker/dockerfile:1
FROM python:3.9.13-alpine3.16 AS compile-image
RUN apk add --no-cache gcc musl-dev linux-headers
ENV VIRTUAL_ENV=/opt/venv
RUN python -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
COPY requirements.txt .
RUN pip install -r requirements.txt
WORKDIR /project
COPY . .
RUN pip install .
FROM python:3.9.13-alpine3.16
COPY --from=compile-image $VIRTUAL_ENV $VIRTUAL_ENV
ENV FLASK_APP=run.py
ENV FLASK_RUN_HOST=0.0.0.0
EXPOSE 5000
CMD ["flask", "run"]
注意:我使用了以下文章中建议的方法的改编版本: https://pythonspeed.com/articles/multi-stage-docker-python/ 。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当您在Dockerfile中有一秒钟的语句时,直到该语句不再是图像的一部分,包括ENV语句。
因此,在您的第二部分中,
virtual_env
没有值。这会导致您的复制语句为复制-from = compile-image
没有路径。我尝试查看文档,这是一个有效的说法,但是文档并没有描述您这样做时会发生什么。我对其进行了测试,似乎它将从compile-image
的所有内容复制到您的新图像中。这会导致图像大小两倍。要修复它,您可以用所需的路径在第二部分中替换环境变量,
因为您可能希望在最终图像中具有/opt/venv/bin的路径,我已经移动了通往第二阶段的道路。如果是第一阶段,那么当您从声明中获得第二次命中时,它也会丢失。
我不是Python专家,但是您可能还需要将
python -m Venv
语句移动/复制到第二阶段,如果需要在运行时。When you have a second FROM statement in a Dockerfile, everything up until that statement is no longer part of the image, including ENV statements.
So in your second part,
VIRTUAL_ENV
doesn't have a value. That leads to your COPY statement beingCOPY --from=compile-image
with no paths. I tried looking at the docs and it is a valid statement, but the docs don't describe what happens when you do that. I tested it and it seems that it copies everything from thecompile-image
into your new image. That causes the image to double in size.To fix it, you can replace the environment variable in the second part with the path you want, like this
Since you probably want the PATH to have /opt/venv/bin in it in the final image, I've moved the setting of the PATH to the second stage. If it's in the first stage, it'll also be lost when you hit the second FROM statement.
I'm not a Python expert, but you might also need to move/copy the
python -m venv
statement to the second stage if that's needed at runtime.