web-dev-qa-db-fra.com

Les ports Docker ne sont pas exposés

J'ai mis en place un serveur de nœud simple dans Docker.

Dockerfile

FROM node:latest
RUN apt-get -y update
ADD example.js .
EXPOSE 1337   
CMD node example.js

example.js

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n'+new Date);
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');

Maintenant, construis l'image

$ docker build -t node_server .

Maintenant, courez dans un conteneur

$ docker run -p 1337:1337 -d node_server  
$ 5909e87302ab7520884060437e19ef543ffafc568419c04630abffe6ff731f70

Vérifiez que le conteneur est en cours d'exécution et que les ports sont mappés:

$ docker ps  

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
5909e87302ab        node_server         "/bin/sh -c 'node exa"   7 seconds ago       Up 6 seconds        0.0.0.0:1337->1337/tcp   Grave_goldberg

Maintenant attachons au conteneur et vérifions que le serveur fonctionne à l'intérieur:

$ docker exec -it 5909e87302ab7520884060437e19ef543ffafc568419c04630abffe6ff731f70 /bin/bash 

Et dans la ligne de commande du conteneur, tapez:

root@5909e87302ab:/# curl http://localhost:1337
Hello World
Mon Feb 15 2016 16:28:38 GMT+0000 (UTC)

Ça a l'air bien non?

Le problème

Lorsque j'exécute la même commande curl sur l'hôte (ou que je navigue avec mon navigateur jusqu'à http: // localhost: 1337 ), je ne vois rien.

Une idée de pourquoi le mappage de port entre conteneur et hôte ne fonctionne pas?

Choses que j'ai déjà essayées:

  • Courir avec le --expose 1337 drapeau
46
Assaf Shomer

Vos ports sont correctement exposés, mais votre serveur écoute les connexions sur 127.0.0.1 à l'intérieur de votre conteneur:

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n'+new Date);
}).listen(1337, '127.0.0.1');

Vous devez exécuter votre serveur comme ceci:

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n'+new Date);
}).listen(1337, '0.0.0.0');

Notez le 0.0.0.0 au lieu de 127.0.0.1.

66
Chris McKinnel

Ajout de EXPOSE 1337 au fichier de menu fixe

EXPOSE est obligatoire si vous voulez "exposer" ce port à d'autres conteneurs.

Comme BMitch commentaires:

Expose n'est pas nécessaire pour publier un port ou pour connecter un conteneur à un autre via un réseau de dockers partagé.
Ce sont des métadonnées pour la publication de tous les ports avec -P et inspecter l'image/le conteneur.

Alors:

Courir avec le --expose 1337 drapeau

Pas exactement: vous devez docker run le avec -p 1337:1337

Vous avez besoin soit:

  • construit une image contenant la directive EXPOSE (utilisée par -P)
  • ou exécutez-le avec le port publié sur l'hôte -p 1337:1337

Le test curl http://localhost:1337 a été effectué à partir du conteneur (pas de EXPOSE ni une publication nécessaire).
Si vous voulez que cela fonctionne à partir de l'hôte Linux, vous avez besoin de EXPOSE+-P ou vous avez besoin de -p 1337:1337.
Non plus.

La déclaration seule expose est utile pour documenter l'intention, mais ne fait rien seul.

Par exemple:

https://i.stack.imgur.com/wmKgd.png

Dans cette figure, 8080 correspond à EXPOSE, publié sur l’hôte Linux 8888.
Et si cet hôte Linux n’est pas l’hôte réel, le même port doit être transféré rapidement vers l’hôte réel. Voir " Comment accéder à Tomcat s'exécutant dans un conteneur de menu fixe à partir du navigateur? ".

Si localhost ne fonctionne pas à partir de l'hôte Linux, essayez son adresse IP:

CID=$(docker run -p 1337:1337 -d node_server)
CIP=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' ${CID})
curl http://${CIP}:1337

Ou, comme mentionné ci-dessus, faites écouter votre serveur à partir de connexions provenant de n’importe quelle adresse IP: 0.0.0.0 qui est l'adresse de diffusion ou le réseau zéro .

24
VonC