tutorial hub community docker

hub - docker ubuntu



¿Cuál es la diferencia entre "exponer" y "publicar" en Docker? (5)

Respuesta corta:

  • EXPOSE es una forma de documentar.
  • --publish (o -p ) es una forma de asignar un puerto de host a un puerto de contenedor en ejecución

Note a continuación que:

  • EXPOSE está relacionado con Dockerfiles ( documentando )
  • --publish está relacionado con la docker run ... --publish docker run ... ( ejecución / tiempo de ejecución )

Exposición y publicación de puertos.

En la red Docker, hay dos mecanismos diferentes que involucran directamente a 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.

  • Expone los puertos utilizando la palabra clave EXPOSE en el Dockerfile o el indicador --expose para ejecutar la --expose acoplable. Exponer puertos es una forma de documentar qué puertos se utilizan, pero en realidad no asigna ni abre ningún puerto. La exposición de puertos es opcional .

  • Usted publica los puertos utilizando el --publish o --publish-all para docker run la --publish docker run . Esto le indica a Docker qué puertos abrir en la interfaz de red del contenedor. Cuando se publica un puerto, se asigna a un puerto de alto orden disponible (superior a 30000 ) en la máquina host, a menos que especifique el puerto al que se asignará en la máquina host en el tiempo de ejecución. No puede especificar el puerto al que se asignará en el equipo host cuando genere la imagen (en el Dockerfile), porque no hay manera de garantizar que el puerto esté disponible en el equipo host donde ejecuta la imagen .

de: Docker contenedor de redes

También,

EXPONER

... La instrucción EXPOSE no publica realmente el puerto. Funciona como un tipo de documentación entre la persona que construye la imagen y la persona que ejecuta el contenedor, acerca de los puertos que deben publicarse .

de: documentation





Acceso al servicio cuando EXPOSE / --publish no está definido:

En respuesta de se afirma que:

"Si no especifica ninguno de ellos, no se podrá acceder al servicio en el contenedor desde cualquier lugar, excepto desde dentro del mismo contenedor ".

Quizás ese fue el caso en el momento en que se escribió la respuesta, pero ahora parece que incluso si no usa EXPOSE o --publish , el host y otros containers de la misma red podrán acceder a un servicio que puede comenzar dentro de ese contenedor .

Cómo probar esto:

He usado el 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

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 el curl del host u otros contenedores para obtener la página de inicio de mini-httpd .

Estoy experimentando con Dockerfiles, y creo que entiendo la mayor parte de la lógica. Sin embargo, no veo la diferencia entre "exponer" y "publicar" un puerto en este contexto.

Todos los tutoriales que he visto primero incluyen el comando EXPOSE en el Dockerfile:

... EXPOSE 8080 ...

Luego construyen una imagen de este Dockerfile:

$ docker build -t an_image - < Dockerfile

Y luego publique el mismo puerto que el anterior cuando ejecute la imagen:

$ docker run -d -p 8080 an_image

o publicar todos los puertos usando

$ docker run -d -P an_image

¿Cuál es el punto de exponer un puerto en el Dockerfile, si se publicará de todos modos? ¿Habría alguna vez la necesidad de exponer un puerto primero y no publicarlo más tarde? Efectivamente, me gustaría especificar todos los puertos que usaré en el Dockerfile al crear la imagen, y luego no volver a molestarme con ellos, simplemente ejecutándolos con:

$ docker run -d an_image

es posible?


Básicamente, tienes tres opciones:

  1. Ni especifique EXPOSE ni -p
  2. Solo especifique EXPOSE
  3. Especifique EXPOSE y -p

1) Si no especifica EXPOSE ni -p , solo se podrá acceder al servicio en el contenedor desde dentro del mismo contenedor.

2) Si EXPOSE un puerto, el servicio en el contenedor no es accesible desde el exterior de Docker, sino desde el interior de otros contenedores de Docker. Así que esto es bueno para la comunicación entre contenedores.

3) Si EXPOSE y -p un puerto, se puede acceder al servicio en el contenedor desde cualquier lugar, incluso fuera de Docker.

La razón por la que ambos están separados es IMHO porque:

  • la elección de un puerto de host depende del host y, por lo tanto, no pertenece al Dockerfile (de lo contrario, dependería del host),
  • ya menudo es suficiente si se puede acceder a un servicio en un contenedor desde otros contenedores.

La documentation establece explícitamente:

La instrucción EXPOSE expone los puertos para su uso dentro de los enlaces.

También le indica cómo vincular los contenedores , que básicamente es la comunicación entre contenedores de la que hablé.

PD: si haces -p , pero NO EXPOSE , Docker hace un EXPOSE implícito. Esto se debe a que si un puerto está abierto al público, también se abre automáticamente a otros contenedores de Docker. Por lo tanto -p incluye EXPOSE . Es por eso que no lo mencioné arriba como un cuarto caso.


Expone los puertos utilizando la palabra clave EXPOSE en el Dockerfile o el indicador --expose para ejecutar la ventana acoplable. Exponer puertos es una forma de documentar qué puertos se utilizan, pero en realidad no asigna ni abre ningún puerto. La exposición de puertos es opcional.

Fuente: github commit


La mayoría de la gente usa red docker para componer con redes. La documentation establece:

La función de red de Docker admite la creación de redes sin la necesidad de exponer puertos dentro de la red; para obtener información detallada, consulte la descripción general de esta función).

Lo que significa que si usa redes para la comunicación entre contenedores, no necesita preocuparse por exponer los puertos.


EXPOSE permite definir puertos privados (contenedor) y públicos (host) para exponer en el momento de creación de la imagen para cuando se ejecuta el contenedor. El puerto público es opcional; si no se especifica un puerto público, la ventana acoplable seleccionará un puerto aleatorio en el host para exponer el puerto de contenedor especificado en Dockerfile.

Una buena práctica es no especificar el puerto público, ya que limita solo un contenedor por host (un segundo contenedor lanzará un puerto que ya está en uso).

Puede usar -p en la docker run para controlar en qué puerto público se podrán conectar los puertos de contenedor expuestos.

De todos modos, si no usa EXPOSE ni -p , no se expondrán puertos.

Si siempre usa -p en la docker run , no necesita EXPOSE pero si usa EXPOSE el comando de docker run EXPOSE docker run puede ser más simple, EXPOSE puede ser útil si no le importa qué puerto se expondrá en el host, o si está Seguro de que solo se cargará un contenedor.