Respuesta corta:
EXPOSE
es una forma de documentar
--publish
(o -p
) es una forma de asignar un puerto host a un puerto contenedor en ejecución
Observe a continuación que:
EXPOSE
está relacionado con Dockerfiles
( documentación )
--publish
está relacionado con docker run ...
( ejecución / tiempo de ejecución )
Puertos de exposición y publicación
En la red Docker, hay dos mecanismos diferentes que involucran directamente los puertos de red: exponer y publicar puertos. Esto se aplica a la red puente predeterminada y a las redes puente definidas por el usuario.
EXPOSE
Expone los puertos utilizando la palabra clave en el Dockerfile o el --expose
indicador para ejecutar Docker . Exponer puertos es una forma de documentar qué puertos se usan, pero en realidad no asigna ni abre ningún puerto . La exposición de los puertos es opcional.
Publica puertos utilizando el --publish
o--publish-all
indicadordocker run
. Esto le dice a Docker qué puertos abrir en la interfaz de red del contenedor. Cuando se publica un puerto, se asigna a un puerto de orden superior disponible (más alto que 30000
) en la máquina host, a menos que especifique el puerto para asignar en la máquina host en tiempo de ejecución. No puede especificar el puerto para asignar en la máquina host cuando construye la imagen (en el Dockerfile), porque no hay forma de garantizar que el puerto estará disponible en la máquina host donde ejecuta la imagen .
de: redes de contenedores Docker
Actualización de octubre de 2019 : el texto anterior ya no está en los documentos, pero hay una versión archivada aquí: docs.docker.com/v17.09/engine/userguide/networking/#exposing-and-publishing-ports
Quizás la documentación actual es la siguiente:
Puertos publicados
De manera predeterminada, cuando crea un contenedor, no publica ninguno de sus puertos en el mundo exterior. Para hacer que un puerto esté disponible para servicios fuera de Docker, o para contenedores Docker que no están conectados a la red del contenedor, use el indicador --publish
o -p
. Esto crea una regla de firewall que asigna un puerto de contenedor a un puerto en el host Docker.
y se puede encontrar aquí: docs.docker.com/config/containers/container-networking/#published-ports
También,
EXPONER
... La EXPOSE
instrucció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.
de: referencia de Dockerfile
Acceso al servicio cuando EXPOSE
/--publish
no están definidos:
En la respuesta de @Golo Roden se afirma que ::
"Si no especifica ninguno de esos, el servicio en el contenedor no será accesible desde cualquier lugar, excepto desde el interior del contenedor".
Tal vez ese era el caso en el momento en que se estaba escribiendo la respuesta, pero ahora parece que incluso si no usa EXPOSE
o --publish
, el host
y otroscontainers
red de la misma podrá acceder a un servicio que puede iniciar dentro de ese contenedor.
Cómo probar esto:
He usado lo siguiente Dockerfile
. Básicamente, comienzo con ubuntu e instalo un pequeño servidor web:
FROM ubuntu
RUN apt-get update && apt-get install -y mini-httpd
I build
la imagen como "testexpose" y run
un nuevo contenedor con:
docker run --rm -it testexpose bash
Dentro del contenedor, lanzo algunas instancias de mini-httpd
:
root@fb8f7dd1322d:/# mini_httpd -p 80
root@fb8f7dd1322d:/# mini_httpd -p 8080
root@fb8f7dd1322d:/# mini_httpd -p 8090
Entonces puedo usar curl
desde el host u otros contenedores para buscar la página de inicio de mini-httpd
.