Retour au blog

Construire et déployer une application Flask avec Docker sur Ubuntu 20.04

Construire et déployer une application Flask avec Docker sur Ubuntu 20.04

Introduction

Docker est une plateforme de conteneurs open-source. Il s'agit d'un environnement standardisé, léger, virtualisé, portable et défini par logiciel qui permet au logiciel de s'exécuter de manière isolée des autres logiciels s'exécutant sur la machine hôte physique. Docker offre une alternative légère aux machines virtuelles. En même temps, il offre la portabilité, la performance, l'agilité et l'évolutivité des applications. Pour un guide complet sur l'écosystème Docker, jetez un œil à notre aperçu détaillé de la conteneurisation avec Docker.

Flask est un framework web minimaliste open-source construit avec Python. Parmi les excellentes fonctionnalités de Flask, on peut citer sa légèreté, sa flexibilité et sa structure hautement organisée. De plus, il ne nécessite aucun outil ou plug-in spécifique pour fonctionner.

Combiner Flask and Docker vous offre une application légère, flexible et évolutive. Vous pouvez la déployer sur de nombreux serveurs et infrastructures, grâce à la nature portable des conteneurs Dockerisés. L'objectif de ce tutoriel est de vous montrer comment déployer une application Flask avec Docker. Nous allons également vous montrer comment vous assurer que les futures mises à jour de votre application prennent effet.

Prérequis

Ce tutoriel sera pratique, et vous devriez créer un environnement qui vous permettra de le suivre :

Maintenant, commençons !

Étape 1 : Préparer l'application Flask

Nous allons commencer par créer un répertoire qui contiendra notre application Flask. Vous pouvez choisir le nom de répertoire de votre choix. Cependant, pour ce tutoriel, nous le nommerons flask_demo. Nous enregistrerons les fichiers du projet dans le répertoire /var/www , qui est généralement le répertoire auquel Ubuntu autorise l'accès à l'internet public par défaut. Tout d'abord, exécutez les commandes suivantes pour créer le répertoire et y naviguer :

À l'intérieur de ce répertoire racine de notre projet, nous allons créer la structure de dossiers de base d'une application Flask. Ensuite, exécutez la commande suivante pour créer la structure de base, en ajoutant l'option -p pour créer tous les dossiers parents en cours de route :

Le dossier app contient tous les fichiers liés à une application Flask, y compris les views et les blueprints. Les vues (views) contiennent le code que vous écrivez pour répondre aux requêtes qui parviennent à votre application. Les blueprints aident à créer des composants d'application et prennent en charge les modèles courants dans les applications Flask.

Le dossier judicieusement nommé static contient des ressources statiques telles que des images, des fichiers CSS et JavaScript. Le répertoire templates contient tous les modèles HTML du projet.

Nous pouvons maintenant commencer à écrire les fichiers nécessaires pour initialiser une application Flask. Commencez par créer un fichier nommé __init__.py à l'intérieur du répertoire app pour indiquer à l'interpréteur Python interpreter que le répertoire app doit être traité comme un package. Exécutez la commande suivante sur votre terminal pour ouvrir le fichier avec l'éditeur nano :

Nous utilisons des packages en Python pour regrouper des modules dans des espaces de noms ou des hiérarchies logiques. La modularisation permet de diviser le code en blocs individuels et gérables qui effectuent des fonctions définies.

Après cela, à l'intérieur du fichier __init__.py ouvert dans votre éditeur, ajoutez l'extrait de code suivant pour démarrer l'instance Flask, et importez la logique depuis le fichier views.py que vous créerez dans les étapes suivantes :

Lorsque vous avez terminé, appuyez sur Ctrl + O et ENTER pour enregistrer le fichier, puis fermez-le avec Ctrl + X. Ensuite, créons le views.py à l'intérieur du répertoire app . Le fichier views.py contiendra la majeure partie de la logique de l'application :

Dans le fichier, ajoutez l'extrait de code suivant. Ce code affichera une simple chaîne de caractères pour montrer que votre application fonctionne lorsque les utilisateurs visitent votre site web :

Dans ce fichier, nous commençons par importer l'instance de l'application Flask. Ensuite, nous devons ajouter une ligne pour définir la route : @app.route(/). La ligne @app.route(/) est appelée un décorateur dans Flask. Vous pouvez utiliser des décorateurs pour injecter des fonctionnalités supplémentaires dans une ou plusieurs fonctions. Dans ce cas, nous transmettons un appel à la route / à la fonction home. Lorsqu'un utilisateur visite cette route, il verra le texte : "Notre application Flask fonctionne !".

Ensuite, vous créerez le fichier uwsgi.ini pour contenir les configurations uWSGI de l'application. uWSGI est une option de déploiement pour Nginx qui sert de protocole et de serveur d'application. Exécutez la commande suivante pour créer le fichier dans le répertoire racine du projet avec l'éditeur nano :

Dans le fichier ouvert, ajoutez l'extrait de code suivant :

Ce fichier contient quelques directives. Nous définissons leur but ci-dessous :

  • module – définit le module à partir duquel l'application Flask sera servie. Nous avons défini le module comme main, faisant référence au fichier main.py dans le répertoire racine. Nous créerons ce fichier à l'étape suivante.
  • callable – indique à uWSGI d'utiliser l'instance app exportée de l'application.
  • master – garantit que l'application continue de fonctionner pour minimiser les temps d'arrêt lors du rechargement de l'ensemble de l'application.

Enregistrez et fermez le fichier lorsque vous avez terminé.

Vous pouvez maintenant créer le fichier main.py pour déterminer le point d'entrée de votre application. uWSGI lira ce fichier pour savoir comment interagir avec l'application. Exécutez la commande suivante pour créer le fichier main.py avec nano à l'intérieur du répertoire racine de votre projet :

Dans le fichier, ajoutez la ligne suivante qui importera l'instance Flask créée dans le package de l'application :

La dernière chose que vous ferez dans cette étape est de définir les dépendances nécessaires au fonctionnement de l'application. Nous définirons ces dépendances dans un fichier appelé dependencies.txt. Lorsque Docker construit l'image de votre application, il exécutera une commande du pip (package manager) pour installer les dépendances. Ouvrez le fichier dans le répertoire racine avec la commande suivante :

À ce stade de notre projet, nous ne voulons qu'une seule dépendance : Flask. Par conséquent, nous pouvons ajouter la ligne suivante pour référencer la version de Flask que nous voulons pour notre projet :

Nous choisissons la Flask version 2.0.1 comme dépendance. C'est la dernière version au moment de la rédaction de ce tutoriel. Vous pouvez en savoir plus sur les différentes versions sur la page Flask Changes. Cela termine la configuration de l'application Flask. Préparons maintenant les configurations Docker pour le déploiement.

Step 2: Configure Docker

Pour configurer un déploiement Docker, nous allons créer deux fichiers, Dockerfile et start.sh. Le Dockerfile contient des lignes déclaratives qui composent une image Docker. Le fichier start.sh est un script shell de base pour construire l'image et démarrer le conteneur à partir du Dockerfile. Tout en étant dans le répertoire racine du projet, exécutez la commande suivante pour créer le Dockerfile:

Ce fichier contient les configurations nécessaires pour une image Docker. Ensuite, ajoutez l'extrait de code suivant pour spécifier les dépendances et comment construire l'image :

La première ligne d'un Dockerfile définit l'image de base à partir de laquelle nous construisons notre image. Dans ce cas, nous allons construire sur la base de tiangolo/uwsgi-nginx-flask, disponible sur DockerHub. Nous avons choisi cette image particulière car elle prend en charge de nombreuses versions de Python.

Nous spécifions également que nous voulons mettre à jour l'image. Ensuite, nous devons ajouter le bash commande processus , l'éditeur de texte nano text editor, et le git client pour récupérer et pousser le code source depuis des dépôts de contrôle de version tels que GitHub, Bitbucket, ou Gitlab. Les lignes avec ENV spécifient les variables d'environnement à utiliser dans le conteneur.

La commande COPY copie les dépendances dans le conteneur. La commande RUN appelle le pip gestionnaire de paquets pour analyser le fichier dependencies.txt et installer les dépendances. Enregistrez et fermez le fichier lorsque vous avez terminé l'édition.

Ensuite, vous allez créer le script start.sh. Ce script inclura des commandes Docker pour construire et exécuter l'image. Bien que vous puissiez exécuter ces commandes progressivement dans le terminal, nous avons pensé qu'il était plus propre de les ajouter à un script shell et de l'appeler simplement depuis le terminal avec une seule commande.

Avant de pouvoir définir le contenu de ce fichier, nous devons d'abord établir un port libre que d'autres services n'utilisent pas. Nous utiliserons le port 45644. Cependant, vous pouvez choisir un port différent. Exécutez la ligne suivante pour vérifier si le port est libre :

Selon le port que vous avez choisi, si la sortie de la commande ci-dessus est 1, alors il est libre. Sinon, vous devrez peut-être choisir un autre port et réessayer la commande :

Flask application Port Check

Puisque nous avons établi un port libre, nous pouvons maintenant créer le fichier avec nano dans le répertoire racine du projet en exécutant la commande suivante :

Dans ce fichier, ajoutez l'extrait de code suivant :

La première ligne, appelée shebang, spécifie qu'il s'agit d'un fichier bash et qu'il doit être exécuté sous forme de commandes. La deuxième ligne déclare une variable appelée app_name. Nous utilisons cette variable pour définir les noms de l'image et du conteneur. La troisième ligne indique à Docker de construire l'image basée sur le Dockerfile dans le répertoire actuel. L'image s'appellera docker-flask-demo selon la variable.

La dernière ligne crée un conteneur appelé docker-flask-demo selon la variable que nous avons définie. L'option -d maintient le conteneur en cours d'exécution en arrière-plan dans un état détaché après la fin de l'exécution de la commande. L'option -p lie un port du serveur à un port particulier du conteneur. Dans ce cas, nous mappons le port 45644 de la machine hôte au port 80 que Docker va exposer dans le conteneur.

Nous utilisons l'option -v pour spécifier un volume Docker à monter sur le conteneur. La variable $PWD est une variable Linux par défaut qui contient le chemin vers le répertoire actuel dans lequel vous vous trouvez à un moment donné :

Flask application pwd

Dans notre cas, nous montons l'intégralité du répertoire du projet dans le répertoire /var/www du conteneur. La configuration Docker est maintenant prête. Vous pouvez construire l'image et démarrer le conteneur basé sur l'image construite en exécutant la commande suivante :

Wait for the script to finish running, then execute the following Docker command to list all running containers:

The output will display running containers:

Demo Docker

You should see our container with the name docker-flask-demo in the list of running containers. Find your server’s public IP and access it in your browser at the specified port: http://your-server-public-ip:45644.

You should see a similar output:

Flask App Running

If you see the above in your browser, then you have successfully deployed a Flask application. Next, we will be modifying files and serving content to users via templates.

Step 3: Serve Content via Template Files

In Flask, Templates are used to display static and dynamic content to website visitors. We will show you how to create an HTML template and serve it to your users when they visit a certain route. For example, this can be a Home page or an About page.

Execute the following command on your terminal to create an index.html file in the app/templates directory:

Then, add the following code snippet to the file:

Save and close the file when you are done. Also, create another page, let’s call it the About page, with the following command:

Add the following code snippet to the file:

Save and close the file when you are done. Next, modify the app/views.py file to reference the templates as well as the routes for the actual pages:

Modify the file so that it looks like this:

Enregistrez et fermez le fichier lorsque vous avez terminé. Les modifications que vous avez apportées ne prendront pas effet tant que vous n'aurez pas arrêté et redémarré le conteneur. Exécutez les commandes Docker suivantes pour arrêter et démarrer le conteneur. Prenez note du nom du conteneur tel que nous l'avons défini précédemment :

Une fois que le conteneur est opérationnel, visitez la page d'accueil (Home) et la page À propos (About) pour voir une partie du nouveau contenu :

Flask application Index

 Flask application 1

Jusqu'à présent, vous avez créé une application Flask capable de diffuser du contenu aux visiteurs de votre site Web. Voici la structure des fichiers du projet :

File Structure

Vous avez probablement remarqué que nous avons dû redémarrer le conteneur Docker pour qu'il prenne en compte les nouvelles modifications. Dans l'étape suivante, nous allons automatiser cela pour garantir moins de temps d'arrêt.

Étape 4 : Configurer les mises à jour des fichiers de l'application pour un rechargement automatique

Régulièrement, nous apportons des modifications à une application, pour améliorer la logique, les interfaces utilisateur ou ajouter des dépendances. Pour que ces modifications prennent effet, il peut être nécessaire de redémarrer le conteneur Docker. Heureusement, uWSGI dispose d'une fonctionnalité appelée touch-reload pour recharger un script Python sans redémarrer le conteneur.

Par défaut, Python dispose d'une fonctionnalité de auto-rechargement qui surveille l'ensemble du système de fichiers pour détecter les modifications et actualise l'application lorsqu'un changement survient. Bien que le rechargement automatique soit utile pour minimiser les temps d'arrêt, il peut être gourmand en ressources. Par conséquent, il n'est pas recommandé pour les environnements de production.

Voyons comment vous pouvez utiliser touch-reload pour surveiller les modifications d'un fichier particulier et recharger l'application en cas de changement. Modifiez le fichier uwsgi.ini avec l'éditeur nano :

Ajoutez la ligne en surbrillance pour qu'elle ressemble à ceci :

Enregistrez et fermez le fichier lorsque vous avez terminé. La ligne ajoutée a spécifié un fichier qui sera modifié pour déclencher le rechargement de l'application. Cependant, pour que cette condition soit activée pour les modifications futures, vous devez d'abord redémarrer le conteneur :

Vous pouvez maintenant modifier le fichier app/views.py pour démontrer le fonctionnement du rechargement automatique :

Modifiez la chaîne renvoyée par la fonction home comme indiqué en surbrillance :

Enregistrez et fermez le fichier une fois terminé.

Ouvrez la page d'accueil de votre application dans le navigateur : http://your-server-public-ip:45644.

Vous ne verrez pas encore de modifications. En effet, la condition touch-reload détecte une modification du fichier uwsgi.ini . Vous pouvez utiliser touch pour activer la condition, rechargeant ainsi l'ensemble de l'application avec la commande suivante :

Maintenant, si vous rechargez la page d'accueil, vous verrez les nouvelles modifications s'afficher :

Touch Reload

À l'avenir, si vous apportez d'autres modifications, il vous suffira d'exécuter la commande sudo touch uwsgi.ini et l'application entière se rechargera avec moins de temps d'arrêt. Cela nous amène à la fin de ce tutoriel.

Conclusion

Dans ce tutoriel, vous avez implémenté et déployé une application Flask avec des images et des conteneurs Docker. Pour minimiser les temps d'arrêt en évitant d'avoir à redémarrer le conteneur, vous avez configuré touch-reload pour écouter les modifications d'un fichier particulier et recharger automatiquement l'ensemble de l'application. Vous avez enfin testé tout cela dans le navigateur pour vous assurer que cela fonctionne.

Docker garantit des déploiements plus rapides et permet une mise à l'échelle facile des applications. Si vous souhaitez en savoir plus sur les différentes commandes Docker, veuillez consulter ce tutoriel sur comment installer et utiliser Docker sur Ubuntu.

Pour plus de ressources sur Docker sur notre blog, vous pouvez consulter ce qui suit :

Bonne informatique !

author

Pranay Kapgate

Auteur · CloudSigma

Preslav Dobrev est un designer créatif chez CloudSigma, axé sur une identité commerciale cohérente à travers des canaux marketing traditionnels et innovants. Il excelle à fusionner la vision artistique avec le marketing stratégique pour créer des récits de marque percutants.

Commentaires

Aucun commentaire pour l'instant. Soyez le premier.