¿Por qué usar EXPOSE en Dockerfile? De todos modos, puede enlazar a todos los puertos

23

Puedo docker run -p 3000:3000 image sin EXPOSE ese puerto en el contenedor (ver más abajo). Si eso es cierto, ¿por qué molestarse en poner EXPOSE en el Dockerfile? ¿Es solo para la comunicación con los usuarios de imágenes? Porque no conozco una razón funcional para EXPONER los puertos si todos son vinculables de todos modos.


Estos son los pasos que me muestran vinculados a un puerto en un contenedor a pesar de que no está EXPONIDO

$ 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!


$
Alexander Bird
fuente

Respuestas:

29

La documentación EXPOSE de Docker aborda este punto específico:

La EXPOSEinstrucción en realidad no publica el puerto. Funciona como un tipo de documentación entre la persona que construye la imagen y la persona que ejecuta el contenedor, sobre qué puertos están destinados a ser publicados. Para publicar realmente el puerto cuando se ejecuta el contenedor, use el -pindicador docker runpara publicar y asignar uno o más puertos, o el -Pindicador para publicar todos los puertos expuestos y asignarlos a puertos de orden superior.

Preste atención a la última oración, si expone varios puertos, entonces se -Pvuelve útil para evitar establecer múltiples -pen la línea de comando.

Tensibai
fuente
La "documentación" está en forma de metadatos de imagen. Además de ser útiles para el -Pindicador, otras utilidades pueden consultar los contenedores en ejecución para estos metadatos, lo cual es útil en servidores proxy que actualizan dinámicamente sus reglas de reenvío utilizando estos puertos expuestos como sus valores predeterminados.
BMitch
@BMitch absolutamente, sentí que era una información extraña que aún no era útil para el OP, pero siéntase libre de editarla.
Tensibai
EXPOSE es documentación
井上 智 文
4

Esto se hace por motivos de automatización. Puede tener un comando universal que se ejecute docker run -Ppara iniciar un contenedor y el propio Dockerfile se usa para especificar qué contenedor expone qué puerto. En caso de que se trate de docenas o cientos de contenedores que se construyen a través de una tubería, esto es bastante útil. Pasar detalles externos no contenidos en Dockerfile junto con el contenedor a través de la tubería de etapa en etapa es bastante difícil a escala.

Jiri Klouda
fuente