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!
$
fuente
-P
indicador, 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.Esto se hace por motivos de automatización. Puede tener un comando universal que se ejecute
docker run -P
para 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.fuente