user9623401
user9623401

Reputation:

is a running container created by each RUN command during multistage build?

I'm new to Docker, sorry if my question sounds dumb. below is a dockerfile from a textbook:

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

and the author says:

The RUN instruction executes a command inside a container during the build, and any output from that command is saved in the image layer.

My questions are:

Q1-Since the author mentioned RUN instruction executes a command inside a container during the build, does it mean that in the first RUN command in line 2, a contianer is created based on the diamol/base image, and this container modify the content of the files then commit the change back to diamol/base image? and same thing happen in line 6, is my understanding correct?

Q2-If my understanding is correct, isn't that we have three different diamol/base images- the original one and two modified in build-stage and test-stage, isn't it very inefficient because it just a small file(let's say its size is 3kb) inside is differnt, while the image could be as large as 500MB and we have 3 copies which is 500MB*3 = 1.5G?

Upvotes: 0

Views: 280

Answers (2)

David Maze
David Maze

Reputation: 159545

docker build does in fact act like a series of docker run and then docker commit steps: it launches a new container for each RUN line and creates a new image from the result of each. But:

Q1. Images don't necessarily have names, and a name won't be pointed at a new image unless you explicitly tell Docker to (docker tag, docker build -t). If you docker build the image you show and then run docker images, you should see the diamol/base image unmodified, two <none> images for the intermediate build stages, and the final image you built.

Q2. When you see reference to an image layer, it is a piece that only contains the changes from the previous image. The build-stage image, for example, is represented as a reference to the diamol/base image (not a copy, just its image ID), plus a filesystem that contains only the 12-byte /build.txt file. docker history can show some of these details. Even if the base image is fairly large, you'll only have one copy of it shared between the final images.

Upvotes: 0

Cyril G.
Cyril G.

Reputation: 2017

Q1-The base image is unchanged with FROM diamol/base, you restart from the original image each time. The previous image is used by --from=build-stage. For each step in your build, there is a layer created which can be reused to speed up later build.

Q2-Images are composed of layers, the layers are reused between images. There is maybe a bit of overhead but the space is not duplicated. Images are immutable, the container based on the image contains the changes.

Explanation here

A Docker image is built up from a series of layers. Each layer represents an instruction in the image’s Dockerfile. Each layer except the very last one is read-only.

Upvotes: 0

Related Questions