Why use EXPOSE in Dockerfile — since you can bind to all ports anyways










19















I can docker run -p 3000:3000 image without EXPOSEing that port in the container (see below). If that's true, then why bother putting EXPOSE in the Dockerfile? Is it just for communication to image users? Because I don't know of a functional reason to EXPOSE ports if they are all bindable anyways.




Here are the steps showing me binding to a port in a container despite the fact it is not EXPOSEd



$ cat Dockerfile
FROM alpine
RUN apk add nodejs npm vim
COPY webserver /webserver
CMD [ "node", "/webserver/index.js" ]


$ docker build .
Sending build context to Docker daemon 1.931MB
Step 1/4 : FROM alpine
---> 11cd0b38bc3c
Step 2/4 : RUN apk add nodejs npm vim
---> Using cache
---> 4270f8bdb201
Step 3/4 : COPY webserver /webserver
---> Using cache
---> 67f4cda61ff0
Step 4/4 : CMD [ "node", "/webserver/index.js" ]
---> Using cache
---> 1df8f9024b85
Successfully built 1df8f9024b85


$ curl localhost:4400
curl: (7) Failed to connect to localhost port 4400: Connection refused


$ docker run -d -p 4400:3000 1df8f9024b85
7d0e6c56f8ad8827fe72830a30c1aac96821104b8ea111291ca39e6536aad8fd


$ curl localhost:4400
Hello World!


$









share|improve this question


























    19















    I can docker run -p 3000:3000 image without EXPOSEing that port in the container (see below). If that's true, then why bother putting EXPOSE in the Dockerfile? Is it just for communication to image users? Because I don't know of a functional reason to EXPOSE ports if they are all bindable anyways.




    Here are the steps showing me binding to a port in a container despite the fact it is not EXPOSEd



    $ cat Dockerfile
    FROM alpine
    RUN apk add nodejs npm vim
    COPY webserver /webserver
    CMD [ "node", "/webserver/index.js" ]


    $ docker build .
    Sending build context to Docker daemon 1.931MB
    Step 1/4 : FROM alpine
    ---> 11cd0b38bc3c
    Step 2/4 : RUN apk add nodejs npm vim
    ---> Using cache
    ---> 4270f8bdb201
    Step 3/4 : COPY webserver /webserver
    ---> Using cache
    ---> 67f4cda61ff0
    Step 4/4 : CMD [ "node", "/webserver/index.js" ]
    ---> Using cache
    ---> 1df8f9024b85
    Successfully built 1df8f9024b85


    $ curl localhost:4400
    curl: (7) Failed to connect to localhost port 4400: Connection refused


    $ docker run -d -p 4400:3000 1df8f9024b85
    7d0e6c56f8ad8827fe72830a30c1aac96821104b8ea111291ca39e6536aad8fd


    $ curl localhost:4400
    Hello World!


    $









    share|improve this question
























      19












      19








      19


      2






      I can docker run -p 3000:3000 image without EXPOSEing that port in the container (see below). If that's true, then why bother putting EXPOSE in the Dockerfile? Is it just for communication to image users? Because I don't know of a functional reason to EXPOSE ports if they are all bindable anyways.




      Here are the steps showing me binding to a port in a container despite the fact it is not EXPOSEd



      $ cat Dockerfile
      FROM alpine
      RUN apk add nodejs npm vim
      COPY webserver /webserver
      CMD [ "node", "/webserver/index.js" ]


      $ docker build .
      Sending build context to Docker daemon 1.931MB
      Step 1/4 : FROM alpine
      ---> 11cd0b38bc3c
      Step 2/4 : RUN apk add nodejs npm vim
      ---> Using cache
      ---> 4270f8bdb201
      Step 3/4 : COPY webserver /webserver
      ---> Using cache
      ---> 67f4cda61ff0
      Step 4/4 : CMD [ "node", "/webserver/index.js" ]
      ---> Using cache
      ---> 1df8f9024b85
      Successfully built 1df8f9024b85


      $ curl localhost:4400
      curl: (7) Failed to connect to localhost port 4400: Connection refused


      $ docker run -d -p 4400:3000 1df8f9024b85
      7d0e6c56f8ad8827fe72830a30c1aac96821104b8ea111291ca39e6536aad8fd


      $ curl localhost:4400
      Hello World!


      $









      share|improve this question














      I can docker run -p 3000:3000 image without EXPOSEing that port in the container (see below). If that's true, then why bother putting EXPOSE in the Dockerfile? Is it just for communication to image users? Because I don't know of a functional reason to EXPOSE ports if they are all bindable anyways.




      Here are the steps showing me binding to a port in a container despite the fact it is not EXPOSEd



      $ cat Dockerfile
      FROM alpine
      RUN apk add nodejs npm vim
      COPY webserver /webserver
      CMD [ "node", "/webserver/index.js" ]


      $ docker build .
      Sending build context to Docker daemon 1.931MB
      Step 1/4 : FROM alpine
      ---> 11cd0b38bc3c
      Step 2/4 : RUN apk add nodejs npm vim
      ---> Using cache
      ---> 4270f8bdb201
      Step 3/4 : COPY webserver /webserver
      ---> Using cache
      ---> 67f4cda61ff0
      Step 4/4 : CMD [ "node", "/webserver/index.js" ]
      ---> Using cache
      ---> 1df8f9024b85
      Successfully built 1df8f9024b85


      $ curl localhost:4400
      curl: (7) Failed to connect to localhost port 4400: Connection refused


      $ docker run -d -p 4400:3000 1df8f9024b85
      7d0e6c56f8ad8827fe72830a30c1aac96821104b8ea111291ca39e6536aad8fd


      $ curl localhost:4400
      Hello World!


      $






      docker dockerfile ports






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Aug 29 '18 at 15:06









      Alexander BirdAlexander Bird

      20516




      20516




















          2 Answers
          2






          active

          oldest

          votes


















          25














          Docker's EXPOSE documentation addresses this specific point:




          The EXPOSE instruction does not actually publish the port. It
          functions as a type of documentation between the person who builds the
          image and the person who runs the container, about which ports are
          intended to be published. To actually publish the port when running
          the container, use the -p flag on docker run to publish and map
          one or more ports, or the -P flag to publish all exposed ports and
          map them to high-order ports.




          Pay attention to the last sentence, if you expose multiple ports then -P becomes useful to avoid setting multiple -p on the command line.






          share|improve this answer

























          • The "documentation" is in the form of image metadata. In addition to being useful to the -P flag, other utilities can query the running containers for this metadata, which is useful in proxies that dynamically update their forwarding rules using these exposed ports as their defaults.

            – BMitch
            Sep 2 '18 at 0:21











          • @BMitch absolutely, I felt it was an extraneous information not yet useful for the OP, but feel free to edit it in.

            – Tensibai
            Sep 2 '18 at 7:18











          • EXPOSE is documentation

            – 井上智文
            Oct 26 '18 at 13:51


















          4














          This is done for automation sake. You can have a universal command that runs docker run -P to start a container and the Dockerfile itself is used to specify which container exposes which port. In case you are dealing with dozens or hundreds of containers being built through a pipeline, this is quite useful. Passing external details not contained in Dockerfile together with the container through pipeline from stage to stage is quite difficult at scale.






          share|improve this answer























            Your Answer








            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "674"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdevops.stackexchange.com%2fquestions%2f4864%2fwhy-use-expose-in-dockerfile-since-you-can-bind-to-all-ports-anyways%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            25














            Docker's EXPOSE documentation addresses this specific point:




            The EXPOSE instruction does not actually publish the port. It
            functions as a type of documentation between the person who builds the
            image and the person who runs the container, about which ports are
            intended to be published. To actually publish the port when running
            the container, use the -p flag on docker run to publish and map
            one or more ports, or the -P flag to publish all exposed ports and
            map them to high-order ports.




            Pay attention to the last sentence, if you expose multiple ports then -P becomes useful to avoid setting multiple -p on the command line.






            share|improve this answer

























            • The "documentation" is in the form of image metadata. In addition to being useful to the -P flag, other utilities can query the running containers for this metadata, which is useful in proxies that dynamically update their forwarding rules using these exposed ports as their defaults.

              – BMitch
              Sep 2 '18 at 0:21











            • @BMitch absolutely, I felt it was an extraneous information not yet useful for the OP, but feel free to edit it in.

              – Tensibai
              Sep 2 '18 at 7:18











            • EXPOSE is documentation

              – 井上智文
              Oct 26 '18 at 13:51















            25














            Docker's EXPOSE documentation addresses this specific point:




            The EXPOSE instruction does not actually publish the port. It
            functions as a type of documentation between the person who builds the
            image and the person who runs the container, about which ports are
            intended to be published. To actually publish the port when running
            the container, use the -p flag on docker run to publish and map
            one or more ports, or the -P flag to publish all exposed ports and
            map them to high-order ports.




            Pay attention to the last sentence, if you expose multiple ports then -P becomes useful to avoid setting multiple -p on the command line.






            share|improve this answer

























            • The "documentation" is in the form of image metadata. In addition to being useful to the -P flag, other utilities can query the running containers for this metadata, which is useful in proxies that dynamically update their forwarding rules using these exposed ports as their defaults.

              – BMitch
              Sep 2 '18 at 0:21











            • @BMitch absolutely, I felt it was an extraneous information not yet useful for the OP, but feel free to edit it in.

              – Tensibai
              Sep 2 '18 at 7:18











            • EXPOSE is documentation

              – 井上智文
              Oct 26 '18 at 13:51













            25












            25








            25







            Docker's EXPOSE documentation addresses this specific point:




            The EXPOSE instruction does not actually publish the port. It
            functions as a type of documentation between the person who builds the
            image and the person who runs the container, about which ports are
            intended to be published. To actually publish the port when running
            the container, use the -p flag on docker run to publish and map
            one or more ports, or the -P flag to publish all exposed ports and
            map them to high-order ports.




            Pay attention to the last sentence, if you expose multiple ports then -P becomes useful to avoid setting multiple -p on the command line.






            share|improve this answer















            Docker's EXPOSE documentation addresses this specific point:




            The EXPOSE instruction does not actually publish the port. It
            functions as a type of documentation between the person who builds the
            image and the person who runs the container, about which ports are
            intended to be published. To actually publish the port when running
            the container, use the -p flag on docker run to publish and map
            one or more ports, or the -P flag to publish all exposed ports and
            map them to high-order ports.




            Pay attention to the last sentence, if you expose multiple ports then -P becomes useful to avoid setting multiple -p on the command line.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Sep 1 '18 at 17:28









            chicks

            1,1391523




            1,1391523










            answered Aug 29 '18 at 15:09









            TensibaiTensibai

            8,94922151




            8,94922151












            • The "documentation" is in the form of image metadata. In addition to being useful to the -P flag, other utilities can query the running containers for this metadata, which is useful in proxies that dynamically update their forwarding rules using these exposed ports as their defaults.

              – BMitch
              Sep 2 '18 at 0:21











            • @BMitch absolutely, I felt it was an extraneous information not yet useful for the OP, but feel free to edit it in.

              – Tensibai
              Sep 2 '18 at 7:18











            • EXPOSE is documentation

              – 井上智文
              Oct 26 '18 at 13:51

















            • The "documentation" is in the form of image metadata. In addition to being useful to the -P flag, other utilities can query the running containers for this metadata, which is useful in proxies that dynamically update their forwarding rules using these exposed ports as their defaults.

              – BMitch
              Sep 2 '18 at 0:21











            • @BMitch absolutely, I felt it was an extraneous information not yet useful for the OP, but feel free to edit it in.

              – Tensibai
              Sep 2 '18 at 7:18











            • EXPOSE is documentation

              – 井上智文
              Oct 26 '18 at 13:51
















            The "documentation" is in the form of image metadata. In addition to being useful to the -P flag, other utilities can query the running containers for this metadata, which is useful in proxies that dynamically update their forwarding rules using these exposed ports as their defaults.

            – BMitch
            Sep 2 '18 at 0:21





            The "documentation" is in the form of image metadata. In addition to being useful to the -P flag, other utilities can query the running containers for this metadata, which is useful in proxies that dynamically update their forwarding rules using these exposed ports as their defaults.

            – BMitch
            Sep 2 '18 at 0:21













            @BMitch absolutely, I felt it was an extraneous information not yet useful for the OP, but feel free to edit it in.

            – Tensibai
            Sep 2 '18 at 7:18





            @BMitch absolutely, I felt it was an extraneous information not yet useful for the OP, but feel free to edit it in.

            – Tensibai
            Sep 2 '18 at 7:18













            EXPOSE is documentation

            – 井上智文
            Oct 26 '18 at 13:51





            EXPOSE is documentation

            – 井上智文
            Oct 26 '18 at 13:51











            4














            This is done for automation sake. You can have a universal command that runs docker run -P to start a container and the Dockerfile itself is used to specify which container exposes which port. In case you are dealing with dozens or hundreds of containers being built through a pipeline, this is quite useful. Passing external details not contained in Dockerfile together with the container through pipeline from stage to stage is quite difficult at scale.






            share|improve this answer



























              4














              This is done for automation sake. You can have a universal command that runs docker run -P to start a container and the Dockerfile itself is used to specify which container exposes which port. In case you are dealing with dozens or hundreds of containers being built through a pipeline, this is quite useful. Passing external details not contained in Dockerfile together with the container through pipeline from stage to stage is quite difficult at scale.






              share|improve this answer

























                4












                4








                4







                This is done for automation sake. You can have a universal command that runs docker run -P to start a container and the Dockerfile itself is used to specify which container exposes which port. In case you are dealing with dozens or hundreds of containers being built through a pipeline, this is quite useful. Passing external details not contained in Dockerfile together with the container through pipeline from stage to stage is quite difficult at scale.






                share|improve this answer













                This is done for automation sake. You can have a universal command that runs docker run -P to start a container and the Dockerfile itself is used to specify which container exposes which port. In case you are dealing with dozens or hundreds of containers being built through a pipeline, this is quite useful. Passing external details not contained in Dockerfile together with the container through pipeline from stage to stage is quite difficult at scale.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Aug 29 '18 at 15:18









                Jiri KloudaJiri Klouda

                4,2201943




                4,2201943



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to DevOps Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdevops.stackexchange.com%2fquestions%2f4864%2fwhy-use-expose-in-dockerfile-since-you-can-bind-to-all-ports-anyways%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

                    Edmonton

                    Crossroads (UK TV series)