Does Docker EXPOSE make a new layer?

后端 未结 4 1705
时光说笑
时光说笑 2021-02-14 17:07

I have been playing around with creating docker files and reading the documentation and I was wondering this question: Does adding an EXPOSE command to my Doc

相关标签:
4条回答
  • 2021-02-14 17:28

    Yes, every instruction in a Dockerfile generates a new layer for the resulting image.

    However, layers created via EXPOSE are empty layers. That is, their size is 0 bytes.

    While they don't impact you storage-wise, they do count for leveraging layer cache while building or pulling/pushing images from a registry.

    A good way to understand an image's layers is to use the docker history command. For instance, given the following Dockerfile:

    FROM scratch
    
    EXPOSE 4000
    EXPOSE 3000
    

    do

    docker build -t test/image .

    If you then docker history test/image you'll see:

    IMAGE               CREATED             CREATED BY                           SIZE                COMMENT
    ab9f435de7bc        4 seconds ago       /bin/sh -c #(nop)  EXPOSE 4000/tcp   0 B                 
    15e09691c313        5 seconds ago       /bin/sh -c #(nop)  EXPOSE 3000/tcp   0 B     
    

    If you switch the order of the EXPOSE statements and build again, you'll see the layer cache being ignored.

    0 讨论(0)
  • 2021-02-14 17:32

    No, directive EXPOSE does not add a new layer. This information will be stored permanently in the image and container config and could be retrieved via:

    docker inspect --format '{{.Config.ExposedPorts}}' <image_id>
    

    But you may still be wondering why there is a line in the output that says that the new image was created for this command. Consider this Dockerfile:

    FROM alpine
    EXPOSE 8000
    

    In the end, Docker produces such output:

    
    Step 1/2 : FROM alpine
     ---> 965ea09ff2eb
    Step 2/2 : EXPOSE 8000
     ---> Running in 6c8fae4f3499
    Removing intermediate container 6c8fae4f3499
     ---> 067aa2abe94f
    Successfully built 067aa2abe94f
    Successfully tagged envtest:latest
    

    In the same time docker history outlines:

    
    IMAGE               CREATED              CREATED BY                                      SIZE                COMMENT
    067aa2abe94f        About a minute ago   /bin/sh -c #(nop)  EXPOSE 8000                  0B                  
    965ea09ff2eb        7 weeks ago          /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B
    

    Every line in the Dockerfile causes image creation on the top of the current image, thus image has a link to the parent image. Afterward, the immediate container will be initialized based on this new image then your command will be executed within and result committed to the image.

    As a general rule, if the command does not lead to changes in the filesystem the new layer won't be created. I would recommend using dive for exploring each layer in a docker image.

    0 讨论(0)
  • 2021-02-14 17:43

    I realised i could test this myself. and I've found that adding EXPOSE does not add a new file system layer, but it does add a layer none the less, also it does matter which order you make your docker files for your cache layers.

    basically: every command creates a new layer, every command that changes the file system creates a filesystem layer.

    FROM ...
    EXPOSE 80
    COPY smthing .
    

    is different from:

    FROM ...
    COPY smthing .
    EXPOSE 80
    

    When executed multiple times (say in a development environment).

    in the first example the EXPOSE command is cached and is not executed even if the smthing file changes. If the something file changes, docker build will only re-executed this command (rest is taken from cache).

    In the second example. if the smthing file changes, the EXPOSE command will also be rebuild. (since everything after the copy command is invalidated and re executed on docker build).

    Would i change the EXPOSE port the first case would have to re-execute the copy command, where the second example wouldn't.

    But both would lead to the exact same end result file-system layer wise.

    docker inspect imageName #shows the file system layer
    docker history imageName #shows all the layers
    
    0 讨论(0)
  • 2021-02-14 17:43

    All instructions create new layers, but instructions that do not change the filesystem will create a layer that is empty.

    It's worth looking into how Docker's filesystem layering works which you can read about here or here for AUFS.

    Essentially new layers on the file system are made of those files that have changed from the layer below them, it's like a stack of diffs. As such, if there is no change, there is no layer to make. Mostly...

    Every instruction in a Dockerfile will create an image layer, but for AUFS (in the case of EXPOSE) that layer will be empty (no difference between it and the one below it).

    0 讨论(0)
提交回复
热议问题