Python Flask app on Docker en ISPConfig3 avec Nginx - Partie 1 : Application minimale
ISPConfig est un excellent panneau de contrôle d'hébergement, mais il ne prend pas en charge les Python applications prêtes à l'emploi. Cet article montre comment vous pouvez le faire en utilisant Doc
Ceci est un post montrant comment exécuter une Flask application sur ISPConfig3. Pourquoi ? J'ai un VPS sur Internet en cours Debian d'exécution et ISPConfig3. Il gère des sites statiques et PHP des sites. Mais maintenant je veux aussi exécuter mes applications Flask python ici. De cette façon, je peux utiliser la gestion de domaine à laquelle je suis habitué et n'ai pas besoin d'un serveur supplémentaire pour les Python applications.
Cette solution permet Docker d'exécuter l' Flask application, en imprimant'Hello world', et est une première preuve de concept montrant qu'il est possible de déployer une application Flasp sur ISPConfig3.
Ma machine locale :
- Ubuntu desktop 18.04.1
- Python3.6.7
- nginx 1.14.0
- Docker 18.09.0
- Docker-composer 1.23.2.2
Mon VPS :
- Debian 9 (Étirer)
- ISPConfig3 3.1.13
- Nginx 1.10.3
- docker 18.09.0
- Docker-composer 1.23.2.2
Essayez de garder les versions Docker et et Docker-compose identiques sur les deux machines. Les Docker développeurs ne parviennent pas toujours à conserver une compatibilité rétroactive.
Contenu :
- Etape 1 : Créer et exécuter une Flask application helloworld sur la machine locale, en utilisant le serveur de développement
- Etape 2 : Exécuter helloworld sur la machine locale, en utilisant le serveur de production Gunicorn
- Etape 3 : Exécuter helloworld sur la machine locale, en utilisant Docker
- Etape 4 : Sur la machine locale desservir dockarized helloworld avec un serveur nginx inverse proxy
- Etape 5 : Sur la machine ISPConfig3, déployez le logiciel dockarized helloworld
- Résumé
- Notes
Etape 1 : Créer et exécuter une Flask application helloworld sur la machine locale, en utilisant le serveur de développement
1.1. Créer un environnement virtuel et activer
Voir les instructions sur Internet. Faites quelque chose comme :
> mkdir flask_docker
> cd flask_docker
> mkdir python3
> cd python3
> mkdir venvs
> python3 -m venv venvs/helloworld
> source venvs/helloworld/bin/activate
> cd venvs/helloworld
> pwd
.../flask_docker/python3/venvs/helloworld
1.2. Consultez l'annuaire helloworld
Vous devriez voir quelque chose comme :
.
|-- bin
|-- include
|-- lib
|-- lib64 -> lib
|-- __pycache__
|-- share
`-- pyvenv.cfg
All commands below are from this directory.
1.3. Installer Flask
Type :
flacon d'installation de pip > flacon d'installation de pip
1.4. Créer une application simple Flask hello.py
Avec votre éditeur créez une Flask application helloworld.py :
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return "<h1>Hello world!</h1>"
if __name__ == '__main__':
app.run()
1.5. Exécutez-le à l'aide du serveur de développement
> python3 helloworld.py Dans
votre navigateur, tapez : localhost:5000 Vous
devriez voir : Hello World
Arrêtez le serveur de développement en utilisant Ctrl-C.
Etape 2 : Exécuter helloworld sur la machine locale, en utilisant le serveur de production Gunicorn
2.1. Installer le serveur de production gunicorn
pip install gunicorn
2.2. Créez le fichier objet d'application wsgi.py pour gunicorn :
Créez le fichier wsgi.py comme suit :
from helloworld import app
if __name__ == "__main__":
app.run()
Nous importons simplement l'application de helloworld.py.
2.3. Exécutez-le à l'aide du serveur gunicorn
> gunicorn --bind 0.0.0.0.0.0:8000 wsgi:app Dans
votre type de navigateur : localhost:80000 Vous
devriez voir : Hello World
Arrêtez le serveur gunicorn en utilisant Ctrl-C.
Etape 3 : Exécuter helloworld sur la machine locale, en utilisant Docker
3.1. Installer Docker et Docker-composer
Voir les instructions sur docker.com, digitalocean.com, etc.
Si vous ne pouvez pas lancer Docker de commandes sans sudo, ajoutez-vous au Docker groupe :
Étapes post-installation pour Linux
https://docs.docker.com/install/linux/linux-postinstall/
3.2. Stockez le logiciel requis dans requirements.txt.
> Si
une ligne'pkg-resources===0.0.0' est présente dans le fichier requirements.txt, supprimez-la.
C'est un bogue sur certains systèmes.
Mon fichier requirements.txt ressemble à ceci :
Click==7.0
Flask==1.0.2
gunicorn==19.9.0
itsdangerous==1.1.0
Jinja2==2.10
MarkupSafe==1.1.0
Werkzeug==0.14.1
3.3. Créer un Dockerfichier
Le Dockerfichier ressemble à ceci :
FROM python:3.6-alpine
RUN adduser -D helloworlduser
RUN mkdir -p /home/flask_app/helloworld
WORKDIR /home/flask_app/helloworld
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY helloworld.py wsgi.py boot.sh ./
RUN chmod +x boot.sh
ENV FLASK_APP helloworld.py
RUN chown -R helloworlduser:helloworlduser ./
USER helloworlduser
EXPOSE 5000
ENTRYPOINT ["./boot.sh"]
Le script de démarrage boot.sh :
#!/bin/sh
# called by Dockerfile
# go to directory where wsgi.py is
cd /home/flask_app/helloworld
# start gunicorn
exec gunicorn -b :5000 --access-logfile - --error-logfile - wsgi:app
Le répertoire ressemble maintenant à ceci :
.
|-- bin
|-- include
|-- lib
|-- lib64 -> lib
|-- __pycache__
|-- share
|-- boot.sh
|-- docker-compose.yml
|-- Dockerfile
|-- Dockerfile_web
|-- helloworld.py
|-- image_helloworld.tar
|-- pyvenv.cfg
|-- requirements.txt
`-- wsgi.py
3.4. Construire l'image du conteneur
> docker build -t helloworld:latest .
La sortie se termine par quelque chose comme :
...
Successfully built d3e8bc220161
Successfully tagged helloworld:latest
Vous pouvez vérifier si le conteneur a été créé :
> images du docker
REPOSITORY TAG IMAGE ID CREATED SIZE
helloworld latest d3e8bc220161 2 minutes ago 84.8MB
python 3.6-alpine 1837080c5e87 5 weeks ago 74.4MB
3.5. Exécuter l'image du conteneur
Exécutez d'abord le conteneur en premier plan, c'est-à-dire sans l'option -d :
> run docker --name helloworld -p 8001:5000 --rm helloworld:latest
Si quelque chose ne va pas, par exemple dans boot.sh, vous pouvez le corriger et reconstruire le conteneur :
> docker build -t helloworld:latest .
Vous pouvez également entrer dans le conteneur pour voir ce qui se passe, par exemple si les fichiers sont vraiment là :
> docker run -it --entrypoint /bin/sh --rm helloworld:latest
Si tout va bien, vous pouvez exécuter le conteneur dans le backgrounf en utilisant l'option -d :
> run docker --name helloworld -d -p 8001:5000 --rm helloworld:latest
Dans votre navigateur, tapez : localhost:80001
Vous devriez voir : Hello World
Vérifier que le conteneur fonctionne :
> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
37f06d44cd30 helloworld:latest "./boot.sh" 4 seconds ago Up 4 seconds 0.0.0.0:8001->5000/tcp helloworld
Vérifiez les registres :
> docker logs helloworld
[2019-02-02 14:52:57 +0000] [1] [INFO] Starting gunicorn 19.9.0
[2019-02-02 14:52:57 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)
[2019-02-02 14:52:57 +0000] [1] [INFO] Using worker: sync
[2019-02-02 14:52:57 +0000] [9] [INFO] Booting worker with pid: 9
Pour arrêter le conteneur :
> docker tuer helloworld
Vérifier que le conteneur s'est arrêté de fonctionner :
> docker ps
Etape 4 : Sur la machine locale desservir dockarized helloworld avec un serveur inversé
4.1. Installer Nginx sur la machine locale
S'il n'est pas encore installé :
sudo apt install nginx > sudo apt install nginx
4.2. Configurer Nginx
Nous allons servir le site helloworld.net au port 8080, configuré à l' Nginx envers, c'est-à-dire proxyqu'il dirige les requêtes des clients vers notre Gunicorn serveur fonctionnant sur .
Créez un fichier /etc/nginx/sites-available/helloworld.conf :
server {
listen 8080;
server_name helloworld.net;
location / {
proxy_pass http://127.0.0.1:8001;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 1M;
}
}
Créez un lien symbolique dans /etc/nginx/sites activé :
> sudo ln -s /etc/nginx/sites-available/helloworld.conf /etc/nginx/sites-enabled/helloworld.conf
Redémarrer Nginx:
> sudo systemctl redémarrer nginx
Si quelque chose ne va pas, regardez l'état :
> sudo systemctl status nginx.service
4.3. Ajouter helloworld.net au fichier hosts
sudo nano /etc/hosts > sudo nano /etc/hosts
Ajoutez une ligne :
127.0.0.0.1 helloworld.net
Vérifiez qu'il fonctionne, il devrait répondre 127.0.0.0.1 sur ping :
> ping helloworld.net
PING helloworld.net (127.0.0.1) 56(84) bytes of data.
64 bytes from helloworld.net (127.0.0.1): icmp_seq=1 ttl=64 time=0.023 ms
64 bytes from helloworld.net (127.0.0.1): icmp_seq=2 ttl=64 time=0.042 ms
En chrome (chrome), vous pouvez vérifier et effacer les dns en tapant dans la barre d'adresse :
chrome:///net-internes/#dns
4.4. Démarrez le conteneur et accédez à votre site Web
Dans votre navigateur, tapez : helloworld.net:8080
Si vous n'avez pas encore démarré l'image du conteneur helloworld docker, le navigateur s'affiche :
502 Bad Gateway
Démarrez votre conteneur :
> run docker --name helloworld -d -p 8001:5000 --rm helloworld:latest
Dans votre navigateur, vous devriez voir : Hello World
Etape 5 : Sur les ISPConfig3 VPS, déployez le dockarized Helloworld
Nous avons maintenant une image de Docker conteneur qui fonctionne sur notre machine locale. Pour l'exécuter sur nos ISPConfig3 machines, nous avons plusieurs options. Ici nous utilisons : copier l' Docker image sur un autre hôte.
5.1. Installer Docker et Docker-composer sur le VPS
Suivez les procédures d'installation.
5.2. Copier Dockerle fichier et l'image du docker sur ISPConfig3 machines
Localisez notre image :
> images du docker
REPOSITORY TAG IMAGE ID CREATED SIZE
helloworld latest bee00f1c8607 21 hours ago 84.8MB
Enregistrez l'image du docker dans un fichier tar :
> docker save -o./image_helloworld.tar helloworld
Utilisez un programme de transfert de fichiers pour copier Dockerle fichier et l'image sur la ISPConfigmachine.
Sur les ISPConfig3 machines allez dans le répertoire où se trouvent les fichiers et ajoutez notre image à Docker:
> docker load -i image_helloworld.tar
Cela peut prendre un certain temps. Vérifiez que l'image est disponible :
> images du docker
REPOSITORY TAG IMAGE ID CREATED SIZE
helloworld latest bee00f1c8607 21 hours ago 84.8MB
5.3. Configurez votre site en ISPConfig3
En supposant que vous avez déjà un nom de domaine pointant vers votre ISPConfigmachine, vous avez ajouté le domaine, et ajouté le site. Dans ce cas, lorsque vous tapez dans votre navigateur :
<domaine>>domaine
vous devriez voir quelque chose comme :
Welcome to your website!
Connectez-vous à ISPConfig3.
Aller à : Sites->Votre site
Dans l'onglet Domaine :
- CGI décocher la case
- Désactivé : PHPdésactivé
Cliquez sur Enregistrer.
Dans l'onglet Options
Ajouter ce qui suit aux Directives nginx :
location / {
proxy_pass http://127.0.0.1:8001;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 1M;
}
Cliquez sur Enregistrer.
Si votre site fonctionnait avant, il devrait maintenant s'afficher :
ERREUR 502 - Mauvaise passerelle !
5.4. Démarrer le conteneur
> run docker --name helloworld -p 8001:5000 --rm helloworld:latest
Maintenant, après avoir tapé dans votre navigateur :
<domaine>>domaine
vous devriez voir : Hello World
Super !
Arrêtez l' Docker Flask application :
> docker tuer helloworld
Vérifiez qu'il n'est plus là :
> docker ps
Résumé
Nous avons créé une application simple Flask et l'avons déployée sur nos ISPConfig3 machines.
Dans un prochain article, nous utiliserons un exemple plus avancé :
- Servez plusieurs pages
- Servez des fichiers statiques
- Connectez-vous à la base de données ISPConfig3
Notes
1. Vous pouvez Gunicorn toujours l'utiliser pour le développement
Activer le débogueur Flask interactif dans le développement avec Gunicorn
https://nickjanetakis.com/blog/enabling-the-flask-interactive-debugger-in-development-with-gunicorn
Liens / crédits
Deploy flask app with nginx using gunicorn and supervisor
https://medium.com/ymedialabs-innovation/deploy-flask-app-with-nginx-using-gunicorn-and-supervisor-d7a93aa07c18
Embedding Python In Apache2 With mod_python (Debian/Ubuntu, Fedora/CentOS, Mandriva, OpenSUSE)
https://www.howtoforge.com/embedding-python-in-apache2-with-mod_python-debian-ubuntu-fedora-centos-mandriva-opensuse
How to Configure NGINX for a Flask Web Application
https://www.patricksoftwareblog.com/how-to-configure-nginx-for-a-flask-web-application/" target="_blank">How to Configure NGINX for a Flask
How to copy Docker images from one host to another without using a repository
https://stackoverflow.com/questions/23935141/how-to-copy-docker-images-from-one-host-to-another-without-using-a-repository
How to deploy a django application on a linux (Debian/Ubuntu) production server running ISPConfig 3
http://blog.yawd.eu/2011/how-to-deploy-django-app-linux-server-ispconfig/
How To Serve Flask Applications with Gunicorn and Nginx on Ubuntu 18.04
https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-gunicorn-and-nginx-on-ubuntu-18-04
The Flask Mega-Tutorial Part XIX: Deployment on Docker Containers
https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xix-deployment-on-docker-containers
Récent
- Masquer les clés primaires de la base de données UUID de votre application web
- Don't Repeat Yourself (DRY) avec Jinja2
- SQLAlchemy, PostgreSQL, nombre maximal de lignes par user
- Afficher les valeurs des filtres dynamiques SQLAlchemy
- Transfert de données sécurisé grâce au cryptage à Public Key et à pyNaCl
- rqlite : une alternative à haute disponibilité et dist distribuée SQLite
Les plus consultés
- Utilisation des Python's pyOpenSSL pour vérifier les certificats SSL téléchargés d'un hôte
- Utiliser UUIDs au lieu de Integer Autoincrement Primary Keys avec SQLAlchemy et MariaDb
- Connexion à un service sur un hôte Docker à partir d'un conteneur Docker
- Utiliser PyInstaller et Cython pour créer un exécutable Python
- SQLAlchemy : Utilisation de Cascade Deletes pour supprimer des objets connexes
- Flask RESTful API validation des paramètres de la requête avec les schémas Marshmallow