/
/

Comment conteneuriser une application avec Docker

par Team Ninja
how to containerize an application using docker blog banner

La plupart des projets de développement impliquent une multitude d’environnements : production, développement, assurance qualité, préproduction, sans oublier les environnements locaux de chaque développeur. Maintenir la cohérence entre tous ces environnements pour que votre projet se comporte de la même façon (ou fonctionne tout simplement) partout peut relever du défi.
Les causes d’incompatibilité sont nombreuses, mais Docker vous aidera à en éliminer la plupart. Dans cet article, nous nous intéressons à Docker, aux conteneurs applicatifs et à la manière dont ces outils vous permettent d’exécuter votre application partout où vous pouvez installer Docker, et donc d’éviter les problèmes de compatibilité.

Qu’est-ce qu’un conteneur applicatif ?

Un conteneur applicatif est un paquet léger et autonome qui regroupe une application et toutes ses dépendances : bibliothèques, environnements d’exécution et fichiers de configuration. Un conteneur contient tout ce dont l’application a besoin pour fonctionner efficacement dans un environnement isolé. Les conteneurs sont conçus pour s’exécuter sur n’importe quel système d’exploitation et matériel compatibles, car ils font abstraction des différences entre les distributions de systèmes d’exploitation et partagent le noyau du système d’exploitation hôte. Plusieurs applications ou services isolés peuvent ainsi s’exécuter sur un seul hôte, sans qu’il soit nécessaire d’installer un système d’exploitation complet pour chaque application.
Les conteneurs applicatifs se distinguent de la virtualisation traditionnelle sur plusieurs points : l’allocation des ressources, le système d’exploitation, l’isolation et l’évolutivité. Les conteneurs partagent des ressources telles que le processeur, la mémoire et le stockage au niveau du système d’exploitation, et consomment donc moins de ressources que les machines virtuelles (MV), qui exigent un système d’exploitation complet par instance. C’est pourquoi les conteneurs démarrent en quelques secondes, là où les MV peuvent mettre plusieurs minutes. Cette caractéristique rend également les conteneurs plus évolutifs que les MV. Les MV conservent toutefois un avantage : elles offrent une isolation bien plus forte entre les instances que les conteneurs, puisque chaque MV exécute son propre système d’exploitation.

Pourquoi conteneuriser ses applications ?

La conteneurisation des applications apporte de nombreux avantages qui facilitent la gestion de certaines difficultés liées au développement logiciel, au déploiement et à l’exploitation. Voici les principales raisons de conteneuriser une application :

  • Portabilité :la conteneurisation fournit un environnement d’exécution homogène en empaquetant une application avec ses dépendances et sa configuration. Le comportement reste ainsi identique, que le conteneur s’exécute sur le poste d’un développeur ou sur une plateforme cloud.
  • Évolutivité : les conteneurs permettent de déployer, de mettre à jour et de faire évoluer rapidement les applications. Les orchestrateurs de conteneurs peuvent gérer intelligemment la montée en charge, en exécutant exactement le nombre d’instances nécessaire pour absorber la charge actuelle, tout en tenant compte des ressources disponibles.
  • Productivité : les conteneurs offrent un environnement prévisible et homogène, où qu’ils s’exécutent. Plutôt que de configurer chaque environnement manuellement, les développeurs n’ont généralement qu’une seule commande à lancer pour démarrer un conteneur, qui construit et lance l’environnement à leur place.
  • Flexibilité : l’efficacité des conteneurs facilite le découpage d’une application en microservices plus petits et déployables, sans la consommation de ressources qu’impliquerait l’exploitation de plusieurs serveurs physiques, ou même de plusieurs MV.

Présentation de Docker

Docker a été lancé en 2013 comme une plateforme open source qui simplifie la création, l’exécution, la gestion et la distribution d’applications grâce à la conteneurisation. Pour de nombreuses équipes de développement, c’est un outil incontournable des flux de travail de développement et de déploiement logiciels : il permet aux développeurs d’empaqueter leurs applications et leurs dépendances dans des conteneurs légers et portables.
Passons rapidement en revue quelques composants clés de Docker pour comprendre son fonctionnement.

Dockerfile

Un Dockerfile est un fichier texte qui contient les instructions de création d’une image Docker. Il précise quelle image Docker servira de base, l’emplacement du code source de l’application à intégrer à l’image, ainsi que les bibliothèques, paquets et autres dépendances nécessaires à l’exécution de l’application. Docker lit ce fichier et exécute les instructions qu’il contient pour créer l’image Docker.

Images Docker

Une image Docker est un modèle en lecture seule qui contient le code source de l’application et ses dépendances, et qui sert de base aux conteneurs Docker. Les images Docker sont créées à partir d’un Dockerfile et peuvent être versionnées, stockées dans des registres et partagées. Elles reposent sur une architecture en couches, où chaque couche représente une modification de l’image. Comme ce découpage en couches est directement lié à chaque commande du Dockerfile, chaque instruction peut produire une nouvelle couche.

Conteneurs Docker

Un conteneur Docker est une instance en cours d’exécution d’une image Docker. Comme les autres conteneurs, il s’exécute dans un environnement isolé sur un système hôte, reste léger, démarre rapidement et se comporte de manière homogène quel que soit le système hôte sur lequel il tourne.

Conteneuriser une application avec Docker : mode d’emploi

De nombreux types d’applications peuvent être conteneurisés, aussi bien frontend que backend. Nous allons maintenant voir comment conteneuriser une application web Python Flask très simple. D’autres langages et d’autres applications peuvent bien sûr être empaquetés avec Docker, mais nous utiliserons Python Flask pour nos exemples.

Prérequis pour la conteneurisation avec Docker

Comme la conteneurisation d’une application regroupe l’ensemble de son code et de ses dépendances dans un conteneur, les prérequis sont en réalité peu nombreux :

  • Docker doit être installé. Vous trouverez les paquets d’installation pour Linux, Mac ou Windows ici.
  • Créez un dossier de projet pour y placer tous les fichiers de l’application. Dans notre exemple ci-dessous, nous n’utiliserons que trois fichiers.
  • Vous pouvez installer localement les langages de programmation et les bibliothèques que vous utilisez afin de tester votre application avant de la conteneuriser. Ce n’est toutefois pas indispensable, puisque vous les installerez dans le conteneur applicatif et que Docker s’en chargera.

Comprendre le code de l’application et ses dépendances

Pour notre exemple, nous allons créer une petite application Python Flask. Voici à quoi ressemblera le dossier du projet :

my_flask_app/
    - app.py
    - requirements.txt

Notre application se compose de deux fichiers : app.py, qui contient le code de l’application web, et requirements.txt, le fichier que Python utilise pour installer les dépendances. Voici le contenu de app.py, accompagné de quelques commentaires expliquant le rôle de chaque partie :

# Import the Python Flask module
from flask import Flask


# Flask constructor uses the name of the current module
app = Flask(__name__)


# The route() function is a decorator,
# It binds a URL to an associated function
@app.route('/')
def hello_world():
return 'Hello World'


# If the file is run directly
# run the Flask application
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')

Le fichier requirements.txt est très simple : il se contente de déclarer Flask comme dépendance :

Flask==2.3.2

Conteneuriser une application pas à pas

Maintenant que nous avons une application à conteneuriser, l’étape suivante consiste à créer un Dockerfile qui contiendra les instructions de création de l’image Docker.

Créer le Dockerfile

Commencez par créer un fichier Dockerfile vide dans le projet. Ce fichier n’a pas d’extension. Votre dossier de projet doit ressembler à ceci :

my_flask_app/
    - app.py
    - Dockerfile
    - requirements.txt

Voici le contenu du Dockerfile :

FROM python:3.10


COPY . /app
WORKDIR /app


RUN pip install -r requirements.txt
EXPOSE 5000


CMD ["python3", "app.py"]

Voici ce que signifie chacune de ces instructions :

  • FROM : définit le conteneur qui servira de base. Vous trouverez un large choix de conteneurs de base sur Docker Hub.
  • COPY : lors de la création du conteneur, les fichiers de notre projet, représentés par le point, seront copiés dans un dossier /app à l’intérieur du conteneur.
  • WORKDIR : indique à Docker où exécuter la commande située au bas de notre fichier, à savoir le dossier dans lequel nous avons copié le projet.
  • RUN : l’instruction RUN indique à Docker une commande à exécuter pendant la création du conteneur. Cette commande est lancée lors de la création de l’image, pas au démarrage du conteneur. Ici, nous lui demandons d’installer les dépendances listées dans notre fichier requirements.txt.
  • EXPOSE : indique à Docker le port sur lequel le conteneur écoutera, c’est-à-dire celui sur lequel notre application Flask s’exécutera.
  • CMD : indique à Docker les commandes qui seront exécutées au démarrage du conteneur et qui lanceront l’application Flask. L’instruction CMD fournit les valeurs par défaut pour l’exécution d’un conteneur et peut être remplacée lors du docker run.

Créer l’image Docker

Maintenant que nous avons créé le Dockerfile, nous pouvons construire l’image Docker en exécutant cette commande dans le répertoire du projet :

docker build -t flask-app .

Dans cette commande, -t signifie tag et attribue un nom à l’image, flask-app est le nom que nous donnons à l’image, et le . définit le contexte de build, à savoir le répertoire courant.
Une fois la commande lancée, Docker construit votre image et vous obtenez un résultat de ce type :

Résultat de la création de l'image Docker

Exécuter le conteneur Docker

Maintenant que l’image Docker est créée, vous pouvez lancer le conteneur avec la commande suivante dans le répertoire du projet :

docker run -it -p 5000:5000 flask-app

Dans la commande ci-dessus, -it demande à Docker d’exécuter le conteneur en mode interactif, ce qui vous permet d’interagir avec le shell du conteneur, et d’allouer un tty au conteneur, qui vous donne une console en mode texte. L’option -it n’est toutefois pas toujours nécessaire pour exécuter l’application Flask, car il ne s’agit pas d’un outil en ligne de commande nécessitant un terminal interactif. L’option -p définit le mappage des ports du conteneur. Le premier 5000 correspond au port de la machine hôte que vous voulez associer au port du conteneur. Le second 5000 est le port du conteneur. Enfin, flask-app est le nom de l’image que nous venons de créer et que nous voulons exécuter.
Le résultat affiché dans le terminal après l’exécution de la commande ressemblera à ceci :

Exemple d'image de conteneur
Et lorsque vous ouvrez http://localhost:5000/, vous découvrez l’application Flask, très basique.

Bonnes pratiques de conteneurisation avec Docker

La conteneurisation d’une application avec Docker offre d’innombrables avantages pour le développement et le déploiement applicatifs, mais il faut respecter certaines bonnes pratiques pour en tirer pleinement parti.
Voici quelques règles importantes à suivre :

  • Utilisez une image de base minimale : choisissez l’image de base la plus légère possible, comme Alpine Linux, afin de réduire la taille de votre image finale, de limiter la consommation de ressources et d’accélérer les builds.
  • Utilisez des builds multi-étapes : réalisez la compilation et la construction dans une première étape, puis copiez uniquement les artefacts nécessaires dans l’étape finale afin de réduire la taille de l’image finale.
  • Limitez le nombre de couches : réduisez le nombre de couches de votre image en regroupant les commandes dans une seule commande RUN, car chaque couche ajoute de la surcharge.
  • Supprimez les fichiers inutiles : supprimez les fichiers temporaires, les caches et les artefacts de build après l’installation des dépendances ou la construction de l’application, afin de réduire la taille de l’image.
  • Exécutez des conteneurs sans état : stockez les données persistantes en dehors du conteneur, dans des bases de données, du stockage objet ou un autre système de stockage externe, afin de pouvoir arrêter le conteneur sans perdre de données.
  • Taguez vos images : les tags aident à gérer les versions de vos images. Utiliser des tags uniques pour vos déploiements vous permet d’étendre rapidement un cluster de production à de nombreux nœuds.
  • Mettez vos conteneurs à jour : appliquer les correctifs et les mises à jour à vos conteneurs est une démarche proactive qui renforce la sécurité et réduit les menaces.

Vous cherchez une meilleure façon de déployer vos applications ? Découvrez comment conteneuriser une application avec Docker.

Docker : un outil incontournable du développement moderne

La conteneurisation avec Docker a révolutionné le développement applicatif. Les applications conteneurisées apportent des bénéfices majeurs : portabilité, évolutivité, productivité, efficacité et flexibilité. Docker a simplifié ce processus en proposant une approche standardisée et facile à utiliser de la conteneurisation.
Adopter Docker, en veillant à respecter les bonnes pratiques de conteneurisation, peut améliorer le développement, le déploiement et la gestion des applications modernes. En fournissant un environnement d’exécution homogène, les conteneurs permettent aux développeurs de développer une application une seule fois et de l’exécuter n’importe où, ce qui simplifie le travail sur l’ensemble des environnements. L’évolutivité des conteneurs facilite le déploiement et la montée en charge rapides des applications découpées en microservices plus petits et déployables.
Plateforme de conteneurisation de référence, Docker simplifie la création, l’exécution, la gestion et la distribution des applications conteneurisées, ce qui en fait un outil incontournable du développement logiciel moderne.

You might also like

Prêt à simplifier les aspects les plus complexes de l'informatique et de la sécurité ?