Déployer une application web Python peut sembler intimidant au premier abord, surtout quand on débute. Pourtant, avec les bons outils et une méthodologie claire, c'est un processus qui devient rapidement maîtrisable. Dans cet article, je vais vous montrer comment mettre en production une application Flask sur un serveur Ubuntu 20.04, en utilisant Nginx comme serveur web et CGI pour l'exécution de votre code Python.
Cette approche, bien que moins courante que l'utilisation de Gunicorn ou uWSGI, présente l'avantage d'être simple à comprendre et rapide à mettre en place pour des projets de petite à moyenne envergure.
Ce dont vous aurez besoin
Avant de plonger dans le vif du sujet, assurez-vous d'avoir préparé votre environnement. Vous devez disposer de :
Infrastructure serveur : Un serveur Ubuntu 20.04 configuré avec un utilisateur ayant les privilèges sudo. Si vous utilisez un VPS chez OVH, DigitalOcean ou tout autre hébergeur, vérifiez que vous avez bien accès SSH.
Configuration DNS : Votre nom de domaine doit pointer vers l'adresse IP publique de votre serveur. Pensez à configurer à la fois l'enregistrement A pour votre domaine principal et éventuellement un CNAME pour le sous-domaine www.
Application Flask fonctionnelle : Votre projet Flask doit être développé et testé localement dans un environnement virtuel Python. Transférez-le sur le serveur via Git, SCP ou FTP avant de continuer.
Installation du module CGI pour Nginx
Nginx ne supporte pas nativement l'exécution de scripts CGI. C'est là qu'intervient fcgiwrap, un wrapper léger qui fait le lien entre Nginx et vos programmes CGI. L'installation est simple et ne prend que quelques secondes.
Connectez-vous à votre serveur en SSH et lancez cette commande :
sudo apt update
sudo apt install fcgiwrap -y
Le paquet fcgiwrap va créer automatiquement un socket Unix (/var/run/fcgiwrap.socket) que Nginx utilisera pour communiquer avec votre application Flask. C'est ce socket qui permet de faire passer les requêtes HTTP vers votre code Python.
Une fois installé, le service démarre automatiquement. Vous pouvez vérifier son état avec :
sudo systemctl status fcgiwrap
Si tout s'est bien passé, vous devriez voir que le service est actif (running).
Configuration de Nginx pour votre application Flask
Maintenant que fcgiwrap est en place, il faut dire à Nginx comment l'utiliser pour servir votre application. Pour cela, vous allez créer un fichier de configuration spécifique à votre projet.
Création du fichier de configuration
Placez-vous dans le répertoire des sites disponibles de Nginx :
cd /etc/nginx/sites-available/
Créez un nouveau fichier avec le nom de votre domaine. Par exemple, pour monsite.com :
sudo nano monsite.com
Voici une configuration de base que vous pouvez adapter :
server {
listen 80;
listen [::]:80;
server_name monsite.com www.monsite.com;
# Logs pour le débogage
access_log /var/log/nginx/monsite_access.log;
error_log /var/log/nginx/monsite_error.log;
location / {
# Configuration FastCGI
include fastcgi_params;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
# Chemin vers le point d'entrée de votre application Flask
fastcgi_param SCRIPT_FILENAME /home/utilisateur/monprojet/app.py;
# Variables d'environnement utiles
fastcgi_param PATH_INFO $uri;
fastcgi_param QUERY_STRING $query_string;
}
# Servir les fichiers statiques directement (CSS, JS, images)
location /static/ {
alias /home/utilisateur/monprojet/static/;
expires 30d;
}
}
Points importants à personnaliser :
- Remplacez
monsite.compar votre véritable nom de domaine - Modifiez
/home/utilisateur/monprojet/app.pyavec le chemin absolu vers votre fichier Flask principal - Ajustez le chemin du répertoire
/static/si votre application utilise des fichiers statiques
Activation de la configuration
Une fois votre fichier sauvegardé, créez un lien symbolique vers le répertoire sites-enabled pour activer cette configuration :
sudo ln -s /etc/nginx/sites-available/monsite.com /etc/nginx/sites-enabled/
Avant de redémarrer Nginx, testez toujours votre configuration pour éviter les erreurs de syntaxe qui pourraient planter le serveur :
sudo nginx -t
Si le test indique "syntax is ok" et "test is successful", tout est bon. Vous pouvez maintenant redémarrer Nginx pour appliquer les changements :
sudo systemctl restart nginx
Préparation de votre application Flask
Votre application Flask doit avoir une petite adaptation pour fonctionner correctement en mode CGI. Assurez-vous que votre fichier principal (par exemple app.py) contient bien le shebang et les permissions d'exécution.
Ajoutez en tout début de fichier :
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
Puis rendez le fichier exécutable :
chmod +x /home/utilisateur/monprojet/app.py
Vérifiez également que votre environnement virtuel Python est bien activé dans votre application, ou que les dépendances sont installées globalement (moins recommandé).
Test et vérification du déploiement
C'est le moment de vérité ! Ouvrez votre navigateur et accédez à votre nom de domaine. Si tout a été configuré correctement, vous devriez voir votre application Flask s'afficher.
En cas de problème, voici quelques pistes de débogage :
Erreur 502 Bad Gateway : Vérifiez que fcgiwrap tourne bien (sudo systemctl status fcgiwrap) et que les permissions sur votre fichier Python sont correctes.
Erreur 404 : Le chemin vers votre fichier Flask est probablement incorrect dans la configuration Nginx. Vérifiez le paramètre SCRIPT_FILENAME.
Page blanche : Consultez les logs d'erreur de Nginx : sudo tail -f /var/log/nginx/monsite_error.log
Les CSS/JS ne chargent pas : Assurez-vous que le block location /static/ dans Nginx pointe vers le bon répertoire et que les permissions sont correctes.
Sécurisation avec HTTPS (optionnel mais recommandé)
Une fois que votre site fonctionne en HTTP, je vous recommande vivement d'activer HTTPS avec Let's Encrypt. C'est gratuit, automatisé et essentiel pour la sécurité :
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d monsite.com -d www.monsite.com
Certbot va automatiquement modifier votre configuration Nginx pour rediriger le trafic HTTP vers HTTPS.
Optimisations et bonnes pratiques
Maintenant que votre application tourne, voici quelques améliorations à envisager :
Processus supervisé : Utilisez systemd ou supervisor pour vous assurer que fcgiwrap redémarre automatiquement en cas de crash.
Limitation de débit : Protégez votre application contre les abus avec les directives limit_req de Nginx.
Mise en cache : Pour les pages statiques ou peu changeantes, configurez un cache Nginx pour améliorer les performances.
Monitoring : Mettez en place une surveillance avec des outils comme Netdata ou Prometheus pour détecter les problèmes avant qu'ils n'impactent vos utilisateurs.
Pour aller plus loin
Cette méthode de déploiement convient parfaitement pour des applications légères ou des prototypes. Cependant, pour des projets plus ambitieux qui nécessitent de gérer beaucoup de trafic concurrent, vous devriez envisager des solutions plus robustes comme :
- Gunicorn : Serveur WSGI Python très performant
- uWSGI : Alternative puissante avec beaucoup d'options de configuration
- Docker : Pour une isolation complète et un déploiement reproductible
- Kubernetes : Si vous devez scaler horizontalement sur plusieurs serveurs
Chacune de ces solutions a ses propres avantages, mais elles sont aussi plus complexes à mettre en œuvre.
En résumé
Vous venez de déployer avec succès une application Flask sur Ubuntu 20.04 avec Nginx et CGI. Cette configuration, bien que basique, vous donne une base solide pour héberger vos projets Python en production.
Les points clés à retenir :
- fcgiwrap sert de pont entre Nginx et votre code Python
- La configuration Nginx doit pointer précisément vers votre fichier Flask
- Les permissions d'exécution sont essentielles pour que le script fonctionne
- HTTPS est indispensable pour un site en production
- Cette approche convient surtout aux projets de petite à moyenne envergure
N'hésitez pas à expérimenter avec cette configuration de base et à l'adapter selon vos besoins spécifiques. Le déploiement web est un domaine où la pratique et l'expérimentation sont vos meilleurs professeurs.