Reputation:
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
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
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.
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