Pourquoi utiliser EXPOSE dans Dockerfile - puisque vous pouvez de toute façon vous lier à tous les ports

23

Je peux docker run -p 3000:3000 image sans EXPOSE ing ce port dans le conteneur (voir ci-dessous). Si c'est vrai, alors pourquoi s'embêter à mettre EXPOSE dans le Dockerfile? Est-ce juste pour la communication avec les utilisateurs d'images? Parce que je ne connais pas de raison fonctionnelle pour EXPOSER les ports s'ils sont tous liés de toute façon.


Voici les étapes qui me montrent la liaison à un port dans un conteneur malgré le fait qu'il n'est pas EXPOSÉ

$ 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!


$
Alexander Bird
la source

Réponses:

29

La documentation EXPOSE de Docker aborde ce point spécifique:

L' EXPOSEinstruction ne publie pas réellement le port. Il fonctionne comme un type de documentation entre la personne qui construit l'image et la personne qui exécute le conteneur, sur les ports qui doivent être publiés. Pour publier réellement le port lors de l'exécution du conteneur, utilisez l' -pindicateur sur docker runpour publier et mapper un ou plusieurs ports, ou l' -Pindicateur pour publier tous les ports exposés et les mapper sur des ports de niveau supérieur.

Faites attention à la dernière phrase, si vous exposez plusieurs ports, cela -Pdevient utile pour éviter d'en définir plusieurs -psur la ligne de commande.

Tensibai
la source
La "documentation" se présente sous la forme de métadonnées d'image. En plus d'être utiles à l' -Pindicateur, d'autres utilitaires peuvent interroger les conteneurs en cours d'exécution pour ces métadonnées, ce qui est utile dans les mandataires qui mettent à jour dynamiquement leurs règles de transfert en utilisant ces ports exposés comme valeurs par défaut.
BMitch
@BMitch absolument, je sentais que c'était une information superflue pas encore utile pour l'OP, mais n'hésitez pas à la modifier.
Tensibai
EXPOSE est la documentation
井上 智 文
4

Ceci est fait pour des raisons d'automatisation. Vous pouvez avoir une commande universelle qui s'exécute docker run -Ppour démarrer un conteneur et le Dockerfile lui-même est utilisé pour spécifier quel conteneur expose quel port. Dans le cas où vous avez affaire à des dizaines ou des centaines de conteneurs en cours de construction via un pipeline, cela est très utile. Il est assez difficile à l'échelle de transmettre des détails externes non contenus dans Dockerfile avec le conteneur à travers le pipeline d'une étape à l'autre.

Jiri Klouda
la source