web-dev-qa-db-fra.com

Déploiement d'une application de flacon minimale dans Docker - Problèmes de connexion au serveur

J'ai une application dont la seule dépendance est flask, qui fonctionne bien en dehors du menu fixe et se lie au port par défaut 5000. Voici la source complète:

from flask import Flask

app = Flask(__name__)
app.debug = True

@app.route('/')
def main():
    return 'hi'

if __== '__main__':
    app.run()

Le problème est que lorsque je déploie cela dans docker, le serveur est en cours d'exécution mais est inaccessible de l'extérieur du conteneur.

Ci-dessous, mon fichier Docker. L'image est Ubuntu avec ballon installé. Le fichier tar contient uniquement le index.py répertorié ci-dessus;

# Dockerfile
FROM dreen/flask
MAINTAINER dreen
WORKDIR /srv

# Get source
RUN mkdir -p /srv
COPY perfektimprezy.tar.gz /srv/perfektimprezy.tar.gz
RUN tar x -f perfektimprezy.tar.gz
RUN rm perfektimprezy.tar.gz

# Run server
EXPOSE 5000
CMD ["python", "index.py"]

Voici les étapes que je suis en train de faire pour déployer

$> Sudo docker build -t perfektimprezy .

Autant que je sache, ce qui précède fonctionne bien, l'image contient le contenu de la goudron dans /srv. Maintenant, démarrons le serveur dans un conteneur:

$> Sudo docker run -i -p 5000:5000 -d perfektimprezy
1c50b67d45b1a4feade72276394811c8399b1b95692e0914ee72b103ff54c769

Est-il réellement en cours d'exécution?

$> Sudo docker ps
CONTAINER ID        IMAGE                   COMMAND             CREATED             STATUS              PORTS                    NAMES
1c50b67d45b1        perfektimprezy:latest   "python index.py"   5 seconds ago       Up 5 seconds        0.0.0.0:5000->5000/tcp   loving_wozniak

$> Sudo docker logs 1c50b67d45b1
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat

Oui, on dirait que le serveur flask est en cours d'exécution. C'est ici que ça devient bizarre. Permet de faire une demande au serveur:

 $> curl 127.0.0.1:5000 -v
 * Rebuilt URL to: 127.0.0.1:5000/
 * Hostname was NOT found in DNS cache
 *   Trying 127.0.0.1...
 * Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0)
 > GET / HTTP/1.1
 > User-Agent: curl/7.35.0
 > Host: 127.0.0.1:5000
 > Accept: */*
 >
 * Empty reply from server
 * Connection #0 to Host 127.0.0.1 left intact
 curl: (52) Empty reply from server

Réponse vide ... Mais le processus est-il en cours d'exécution?

$> Sudo docker top 1c50b67d45b1
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                2084                812                 0                   10:26               ?                   00:00:00            python index.py
root                2117                2084                0                   10:26               ?                   00:00:00            /usr/bin/python index.py

Maintenant, ssh dans le serveur et vérifier ...

$> Sudo docker exec -it 1c50b67d45b1 bash
root@1c50b67d45b1:/srv# netstat -an
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 127.0.0.1:5000          0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:47677         127.0.0.1:5000          TIME_WAIT
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node   Path
root@1c50b67d45b1:/srv# curl -I 127.0.0.1:5000
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 5447
Server: Werkzeug/0.10.4 Python/2.7.6
Date: Tue, 19 May 2015 12:18:14 GMT

C'est bon ... mais pas de l'extérieur :( Qu'est-ce que je fais mal?

57
Dreen

Le problème est que vous ne vous connectez qu'à l'interface localhost, vous devriez être lié à 0.0.0.0 si vous voulez que le conteneur soit accessible de l'extérieur. Si vous changez:

if __== '__main__':
    app.run()

à

if __== '__main__':
    app.run(Host='0.0.0.0')

Ça devrait marcher.

94
Adrian Mouat

Lorsque vous utilisez la commande flask au lieu de app.run, vous pouvez passer l'option --Host pour modifier l'hôte. La ligne dans Docker serait:

CMD ["flask", "run", "--Host", "0.0.0.0"]

ou

CMD flask run --Host 0.0.0.0
13
Marku