Answers: <p>This is done for automation sake. You can have a universal command that runs <code>docker run -P</code> 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.</p>
  
Answers: CC BY-SA 4.0
Answers: 2018-08-29T15:18:15.830Z
Answers: 2018-08-29T15:18:15.830Z
Answers: Jiri Klouda
Answers: <p>Docker's <a href="https://docs.docker.com/engine/reference/builder/#expose" rel="noreferrer">EXPOSE documentation</a> addresses this specific point:</p>
  
  <blockquote>
    <p>The <code>EXPOSE</code> 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 <code>-p</code> flag on <code>docker run</code> to publish and map
    one or more ports, or the <code>-P</code> flag to publish all exposed ports and
    map them to high-order ports.</p>
  </blockquote>
  
  <p>Pay attention to the last sentence, if you expose multiple ports then <code>-P</code> becomes useful to avoid setting multiple <code>-p</code> on the command line.</p>
  
Answers: CC BY-SA 4.0
Answers: 2018-09-02T00:21:32.313Z
Answers: 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.
Answers: BMitch
Answers: CC BY-SA 4.0
Answers: 2018-09-02T07:18:06.280Z
Answers: @BMitch absolutely, I felt it was an extraneous information not yet useful for the OP, but feel free to edit it in.
Answers: Tensibai
Answers: CC BY-SA 4.0
Answers: 2018-10-26T13:51:24.930Z
Answers: EXPOSE is documentation
Answers: 井上智文
Answers: CC BY-SA 4.0
Answers: 2018-08-29T15:09:20.053Z
Answers: 2018-09-01T17:28:54.593Z
Answers: 2018-09-01T17:28:54.593Z
Answers: Tensibai
Body: <p>I can <code>docker run -p 3000:3000 image</code> <em>without</em> <code>EXPOSE</code>ing 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.</p>
  
  <hr>
  
  <p>Here are the steps showing me binding to a port in a container despite the fact it is not EXPOSEd</p>
  
  <pre><code>$ 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
   ---&gt; 11cd0b38bc3c
  Step 2/4 : RUN apk add nodejs npm vim
   ---&gt; Using cache
   ---&gt; 4270f8bdb201
  Step 3/4 : COPY webserver /webserver
   ---&gt; Using cache
   ---&gt; 67f4cda61ff0
  Step 4/4 : CMD [ "node", "/webserver/index.js" ]
   ---&gt; Using cache
   ---&gt; 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!
  
  
  $
  </code></pre>
  
Tags: <docker><dockerfile><ports>
Title: Why use EXPOSE in Dockerfile -- since you can bind to all ports anyways
UserDisplayName: Alexander Bird
ThreadText: # Why use EXPOSE in Dockerfile -- since you can bind to all ports anyways
  
  (Asked by: username_0 on 2018-08-29)
  
  I can `docker run -p 3000:3000 image` *without* `EXPOSE`ing 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!
  
  $
  
  ```
  
  **Tags:** docker, dockerfile, ports
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_2 on 2018-08-29. Score: 32 | Accepted answer
  
  Docker's [EXPOSE documentation](https://docs.docker.com/engine/reference/builder/#expose) 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.
  
  > **Comments:**
  > **username_3**: 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.  
  > **username_2**: @username_3 absolutely, I felt it was an extraneous information not yet useful for the OP, but feel free to edit it in.  
  > **username_4**: EXPOSE is documentation  
  
  ---
  
  ### Answer by username_1 on 2018-08-29. Score: 5
  
  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.
  
  
  ---
  
  