web-dev-qa-db-fra.com

Quelle est la difference entre "expose" et "publish" dans Docker?

J'expérimente avec Dockerfiles et je pense comprendre la majeure partie de la logique. Cependant, je ne vois pas la différence entre "exposer" et "publier" un port dans ce contexte.

Tous les tutoriels que j'ai vus en premier incluent la commande EXPOSE dans le fichier de docker:

...
EXPOSE 8080
...

Ils construisent ensuite une image à partir de ce fichier Dockerfile:

$ docker build -t an_image - < Dockerfile

Et puis publie le même port que ci-dessus lors de l'exécution de l'image:

$ docker run -d -p 8080 an_image

ou publier tous les ports en utilisant

$ docker run -d -P an_image

Quel est l’intérêt d’exposer un port dans le fichier Docker, s’il sera publié de toute façon? Serait-il jamais nécessaire d'exposer un port en premier et de le publier {pas plus tard? En effet, je voudrais spécifier tous les ports que je vais utiliser dans le fichier Docker lors de la création de l'image, puis ne plus m'en soucier, les exécuter simplement avec:

$ docker run -d an_image

Est-ce possible?

373
user1496984

Fondamentalement, vous avez trois options:

  1. Ni spécifier EXPOSE ni -p
  2. Spécifiez uniquement EXPOSE
  3. Spécifiez EXPOSE et -p

1) Si vous ne spécifiez ni EXPOSE ni -p, le service dans le conteneur ne sera accessible qu'à partir de inside du conteneur lui-même.

2) Si vous EXPOSE un port, le service dans le conteneur n'est pas accessible de l'extérieur de Docker, mais de l'intérieur d'autres conteneurs de Docker. C'est donc bon pour la communication entre conteneurs.

3) Si vous EXPOSE et -p un port, le service dans le conteneur est accessible de n’importe où, même hors de Docker.

La raison pour laquelle les deux sont séparés est IMHO parce que:

  • le choix d'un port hôte dépend de l'hôte et n'appartient donc pas au fichier Dockerfile (sinon, cela dépend de l'hôte),
  • et souvent, cela suffit si un service dans un conteneur est accessible à partir d'autres conteneurs.

La documentation indique explicitement:

L'instruction EXPOSE expose les ports à utiliser dans les liens.

Il vous indique également comment lier les conteneurs , qui correspond à la communication inter-conteneurs dont j'ai parlé.

PS: Si vous faites -p, mais que vous n’avez pas EXPOSE, Docker effectue une implicite EXPOSE. En effet, si un port est ouvert au public, il est automatiquement ouvert aux autres conteneurs Docker. Par conséquent, -p inclut EXPOSE. C'est pourquoi je ne l'ai pas cité ci-dessus comme quatrième cas.

550
Golo Roden

Réponse courte:

  • EXPOSE est un moyen de documenter
  • --publish (ou -p) est un moyen de mapper un port hôte sur un port conteneur} _

Notez ci-dessous que:

  • EXPOSE est lié à Dockerfiles (documenting)
  • --publish est lié à docker run ... (execution/run-time)

Exposer et publier des ports

Dans la mise en réseau Docker, il existe deux mécanismes différents qui impliquent directement les ports réseau: l'exposition et la publication des ports. Cela s'applique au réseau de pont par défaut et aux réseaux de pont définis par l'utilisateur.

  • Vous exposez les ports à l'aide du mot clé EXPOSE dans le fichier Dockerfile ou de l'indicateur --expose pour l'exécution du menu fixe. Exposing ports est un moyen de documenter les ports utilisés, mais ne mappe ni n'ouvre aucun port. L'exposition des ports est facultative.

  • Vous publiez des ports à l'aide de l'indicateur --publish ou --publish-all sur docker run. Cela indique à Docker les ports à ouvrir sur l’interface réseau du conteneur. Lorsqu'un port est publié, il est mappé sur un port disponible élevé (supérieur à 30000) sur la machine hôte, sauf si vous spécifiez le port sur lequel mapper sur la machine hôte lors de l'exécution. Vous ne pouvez pas spécifier le port à mapper sur la machine hôte lorsque vous créez l'image (dans le fichier Docker), car il n'existe aucun moyen de garantir que le port sera disponible sur la machine hôte sur laquelle vous exécutez l'image.

à partir de: Mise en réseau de conteneurs Docker

Également,

EXPOSER

... L'instruction EXPOSE ne publie pas le port. Il fonctionne comme un type de documentation entre la personne qui construit l'image et celle qui gère le conteneur, à propos des ports destinés à être publiés.

à partir de: Référence Dockerfile






Accès au service lorsque EXPOSE--publish n'est pas défini:

Chez @Golo Roden answer, il est indiqué que:

"Si vous n'en spécifiez aucune, _/le service dans le conteneur ne sera accessible de nulle part, sauf de l'intérieur du conteneur lui-même."

C'était peut-être le cas au moment de la rédaction de la réponse, mais il semble maintenant que même si vous n'utilisez pas EXPOSE ou --publish, the Host et d'autres containers du même réseau, vous pourrez accéder à l'intérieur de ce conteneur.

Comment tester ceci:

J'ai utilisé le Dockerfile suivant. En gros, je commence par Ubuntu et installe un petit serveur Web:

FROM ubuntu
RUN apt-get update && apt-get install -y mini-httpd

J'ai build l'image en tant que "testexpose" et run un nouveau conteneur avec:

docker run --rm -it testexpose bash

Dans le conteneur, je lance quelques instances de mini-httpd:

root@fb8f7dd1322d:/# mini_httpd -p 80
root@fb8f7dd1322d:/# mini_httpd -p 8080
root@fb8f7dd1322d:/# mini_httpd -p 8090

Je peux ensuite utiliser curl à partir de l'hôte ou d'autres conteneurs pour récupérer la page d'accueil de mini-httpd.

73
tgogos

La variable EXPOSE vous permet de définir des ports privés (conteneur) et publics (hôte) à exposer au moment de la création de l'image lorsque le conteneur est en cours d'exécution. Le port public est facultatif. Si ce n'est pas le cas, un port public est spécifié. être sélectionné sur hôte par menu fixe pour exposer le port de conteneur spécifié sur fichier Docker.

Une bonne pratique est de ne pas spécifier le port public, car il ne limite qu'un conteneur par hôte (un second conteneur jettera un port déjà utilisé).

Vous pouvez utiliser -p dans docker run pour contrôler le port public auquel les ports de conteneur exposés seront connectables.

Quoi qu'il en soit, si vous n'utilisez pas EXPOSE ni -p, aucun port ne sera exposé.

Si vous utilisez toujours -p à docker run vous n'avez pas besoin de EXPOSE mais si vous utilisez EXPOSE, votre commande docker run peut être plus simple, EXPOSE peut être utile si vous ne vous souciez pas du port qui sera exposé sur Host, ou si vous êtes sûr de ne un conteneur sera chargé.

7
ton

Vous exposez des ports à l'aide du mot clé EXPOSE dans le fichier Dockerfile ou dans l'indicateur d'exposition ___-- à l'exécution du menu fixe. Exposer les ports est un moyen de documenter quels ports Sont utilisés, mais ne mappe ni n'ouvre aucun port. Les ports exposés sont facultatifs.

Source: github commit

3
mzalazar

La plupart des gens utilisent docker composer avec des réseaux. La documentation indique:

La fonctionnalité réseau de Docker prend en charge la création de réseaux sans avoir à exposer les ports du réseau. Pour plus d'informations, voir la présentation de cette fonctionnalité.

Cela signifie que si vous utilisez des réseaux pour la communication entre les conteneurs, vous n'avez pas à vous soucier de l'exposition des ports.

3
herm

Dockerfile EXPOSE vs publish

EXPOSER

Lors de l'écriture de vos fichiers Docker, l'instruction EXPOSE indique à Docker que le conteneur en cours d'écoute écoute sur des ports réseau spécifiques. Cela agit comme une sorte de documentation de mappage de ports qui peut ensuite être utilisée lors de la publication des ports.

EXPOSER [/...]

Vous pouvez également spécifier cela dans une commande d'exécution de docker, telle que:

docker run --expose = 1234 my_app

Mais EXPOSE n'autorisera pas la communication via les ports définis vers des conteneurs situés à l'extérieur du même réseau ou vers la machine hôte. Pour que cela se produise, vous devez publier les ports.

Publier des ports et les mapper à l'hôte

Vous pouvez utiliser plusieurs indicateurs lors de l’utilisation de la commande docker run pour publier les ports d’un conteneur en dehors du réseau du conteneur et les mapper avec les ports de la machine hôte. Ce sont les indicateurs -p et -P, et ils diffèrent selon que vous souhaitiez publier un ou tous les ports.

Pour réellement publier le port lors de l'exécution du conteneur, utilisez l'indicateur -p sur l'exécution du menu fixe pour publier et mapper un ou plusieurs ports, ou bien l'indicateur -P pour publier tous les ports exposés et les mapper sur des ports de niveau élevé. - Docker docs: EXPOSE

docker run -p 80: 80/tcp -p 80: 80/udp my_app

Dans l'exemple ci-dessus, le premier numéro après l'indicateur -p est le port de l'hôte et le second est le port du conteneur.

Pour publier tous les ports que vous avez définis dans votre fichier Docker avec EXPOSE et les lier à la machine hôte, vous pouvez utiliser l'indicateur -P.

docker run -P my_app

0
Prakash

EXPOSE est utilisé pour mapper un port de conteneur de port local, c.-à-d.: Si vous spécifiez exposer dans un fichier de docker comme

EXPOSE 8090

Que fera-t-il mappera le port localhost 8090 au port conteneur 8090

0
Mansur Ali