简体   繁体   中英

what's the docker intermediate layer or image?

The intermediate image is mentioned in docker doc many times,

Only the instructions RUN, COPY, ADD create layers. Other instructions create temporary intermediate images , and do not increase the size of the build.

from ENV section, it mentions intermediate layer ,

Each ENV line creates a new intermediate layer , just like RUN commands. This means that even if you unset the environment variable in a future layer, it still persists in this layer and its value can't be dumped. You can test this by creating a Dockerfile like the following, and then building it.

So I follow the example,

FROM alpine
ENV ADMIN_USER="mark"
RUN echo $ADMIN_USER > ./mark
RUN unset ADMIN_USER

and build the image and run history,

$ docker history 37c8ebdf36fd
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
37c8ebdf36fd        12 seconds ago      /bin/sh -c unset ADMIN_USER                     0B
789dc0df2bb8        13 seconds ago      /bin/sh -c echo $ADMIN_USER > ./mark            5B
8fc06b8bf4a3        15 seconds ago      /bin/sh -c #(nop)  ENV ADMIN_USER=mark          0B
e7d92cdc71fe        2 months ago        /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B
<missing>           2 months ago        /bin/sh -c #(nop) ADD file:e69d441d729412d24…   5.59MB

$ docker run --rm test sh -c 'echo $ADMIN_USER'

mark

I have several questions,

  1. The variable should be unset by later layers (RUN unset), why it's still there?

from docker inspect, I found where ENV is stored,


            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "ADMIN_USER=mark"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "unset ADMIN_USER"
            ],

If the container starts, it first exports ADMIN_USER=mark and then unset it, the env var ADMIN_USER should not exist.

This means that even if you unset the environment variable in a future layer, it still persists in this layer and its value can't be dumped.

The doc explains it, but I'm confused. Since the layer is 0B, I assume there's nothing stored in that layer.

  1. what are those layers with only 0B size? Why it's not removed from the final image?

Per Docker'simage spec via The Moby Project:

Images are composed of layers. Each layer is a set of filesystem changes. Layers do not have configuration metadata such as environment variables or default arguments - these are properties of the image as a whole rather than any particular layer.

layer with 0B should be deleted (because it indicates no fs change), why it's still there?

  1. Since the ENV command layer only defines metadata, why it's represented as a layer in docker history?

  2. what's the difference between the intermediate layer and the image?

  1. Each RUN command is a new process. When you unset the env variable, it unsets it within that process—it doesn't change the Docker image. So next RUN gets the environment variable again.

  2. (and 3 and 4) The Docker image format is a series of layers. There is no "final image" that is different than the layers, the image is the layers. Or rather, an image is just a pointer to a specific layer.

When you tag an image, what you're really doing is giving a specific layer a name.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM