web-dev-qa-db-fra.com

Publication de port lors de l'exécution avec Docker Compose

Je n'arrive pas à trouver un moyen de faire fonctionner la publication de port avec docker-compose run de la même manière que je peux avec docker run.

Utilisation de Docker Compose (et donc du mappage de port dans docker-compose.yml) donne une erreur "Échec de connexion" de curl:

$ docker-compose run flask
 * Running on http://0.0.0.0:2048/ (Press CTRL+C to quit)

$ curl http://localhost:2048/
curl: (7) Failed connect to localhost:2048; Connection refused

Cependant, les choses vont bien lorsque vous passez manuellement les ports à docker run:

$ docker run -p 2048:2048 --name flask -t flask_image
 * Running on http://0.0.0.0:2048/ (Press CTRL+C to quit)

$ curl http://localhost:2048
Hello World!

Qu'est-ce que je rate?


Dockerfile

FROM centos:7

# Install EPEL repo.
RUN rpm -iUvh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm

# Install Python and Pip.
RUN yum -y update && yum -y install \
    python \
    python-pip

# Flask is necessary to run the app.
RUN pip install flask

EXPOSE 2048

ADD hello_world_flask_app.py /src/hello_world_flask_app.py
CMD ["python", "/src/hello_world_flask_app.py"]

hello_world_flask_app.py

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run(Host='0.0.0.0', port=2048)

docker-compose.yml

version: '2'
services:
  flask:
    build: .
    ports:
      - "2048:2048"
23
JimmidyJoo

Par défaut, docker-compose run ne publie pas les ports du service. Vous pouvez soit passer le --service-ports option pour publier les ports tels qu'ils sont définis dans le docker-compose.yml, ou utilisez le -p option pour publier tous les ports.

Voir la documentation de docker-compose run

23
thaJeztah

MODIFIER

Essayé avec --service-ports (cela ne fonctionne pas avec la commande up et nous devrions en quelque sorte stop et run à nouveau) aussi cela ne change pas ce comportement, les ports sont exposés mais peuvent 't curl et inaccessible pour les raisons mentionnées de 127.0.0.1


Cela est dû au fait que vous utilisez la syntaxe docker-compose 2.

Par défaut, il crée un réseau interne (ou réseau de superposition dans certains cas) entre chaque conteneur de projet de composition.

Vous pouvez utiliser docker inspect <container_name> pour obtenir l'état du réseau de conteneurs.

Utilisant également netstat Cela donne un comportement étrange de docker qui semble écouter uniquement sur tcp6 interfaces:

$ Sudo netstat -lt|grep 2048

  tcp6       0      0 [::]:2048           [::]:*         LISTEN      501/docker

Solutions possibles :

1- Curl de l'extérieur de l'hôte! Ça marche :)

C:\Users\pooya>curl Host:2048
Hello World!

2- Spécifiez IP Localhost (127.0.0.1) dans la section ports:

$ cat docker-compose.yml
version: '2'
services:
  flask:
      build: .
      ports:
        - "127.0.0.1:2048:2048"

Et vous pouvez simplement boucler en utilisant curl localhost:2048

3 - Changer le pilote réseau (mode_résea) en pont

** Cette méthode ne fonctionne plus sur les nouvelles versions de docker **

4- Curl à partir de l'IP de l'hôte au lieu de 127.0.0.1


Alors, quel était le problème ?

Il semble que le problème racine provienne de la méthode du pont docker. docker utilise iptables pour nat INCOMING connexions au port du conteneur correct

$ Sudo iptables -L|grep 2048
ACCEPT     tcp  --  anywhere             10.0.0.12            tcp dpt:2048

Comme vous pouvez le voir, seules les connexions entrantes dports vers 10.0.0.12:2048


Attendez, qu'en est-il de ne pas utiliser docker-compose ??

Étrange! mais juste écouter correctement 0.0.0.0 et tout va bien :)

$ docker run -it -d  -p 2048:2048 test
$ netstat -ltn|grep 2048
tcp        0      0 0.0.0.0:2048   0.0.0.0:*               LISTEN
10
Pooya