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?
Fondamentalement, vous avez trois options:
EXPOSE
ni -p
EXPOSE
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:
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.
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
surdocker 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
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.
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
.
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é.
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
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.
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
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