多阶段构建期间的每个RUN命令是否创建一个正在运行的容器?

40次阅读
没有评论

问题描述

是Docker的新手,对于多阶段构建期间的每个RUN命令是否创建一个正在运行的容器有疑问。他在一本教材中看到了以下Dockerfile的示例:

FROM diamol/base AS build-stage
RUN echo 'Building...' > /build.txt              #line 2
FROM diamol/base AS test-stage
COPY --from=build-stage /build.txt /build.txt
RUN echo 'Testing...' >> /build.txt              #line 6
FROM diamol/base
COPY --from=test-stage /build.txt /build.txt
CMD cat /build.txt

作者解释说:

RUN指令在构建期间在容器内部执行命令,并将该命令的任何输出保存在镜像层中。

用户的问题是:

由于作者提到RUN指令在构建期间在容器内部执行命令,这是否意味着在第2行的第一个RUN命令中,基于diamol/base镜像创建了一个容器,并且该容器修改了文件的内容,然后将更改提交回diamol/base镜像,然后容器被终止?在第6行也是同样的情况,创建容器运行然后终止,镜像得到更新,我的理解正确吗?

解决方案

请注意以下操作注意版本差异及修改前做好备份。

解决方案

是的,你的理解是正确的。Dockerfile中的RUN <commands>命令在某种程度上相当于以下操作:

container = $(docker run base-image) #1
docker exec base-image commands #2
docker commit $container #3

由于镜像是静态的,我们需要一个正在运行的实例/进程来执行我们的命令。这就是为什么会从基础镜像创建一个容器。在#2中执行命令后,更改会被提交回#3,这意味着在之前的层之上创建了一个新的层。这个层将包含容器在#2中引入的更改。

请注意,diamol:base镜像并没有被修改。新的中间镜像是由该命令创建的。

评论:要明确的是,diamol:base镜像并没有被修改。新的中间镜像是由该命令创建的。

参考资料

正文完