Applications multi-conteneurs
Explication
Démarrer une application à conteneur unique est facile. Par exemple, un script Python qui effectue une tâche de traitement de données spécifique s'exécute dans un conteneur avec toutes ses dépendances. De même, une application Node.js servant un site web statique avec un petit point de terminaison d'API peut être efficacement conteneurisée avec toutes ses bibliothèques et dépendances nécessaires. Cependant, à mesure que les applications grossissent, leur gestion en tant que conteneurs individuels devient plus difficile.
Imaginez que le script Python de traitement de données doive se connecter à une base de données. Soudain, vous gérez non seulement le script, mais aussi un serveur de base de données dans le même conteneur. Si le script nécessite des connexions utilisateur, vous aurez besoin d'un mécanisme d'authentification, ce qui augmentera encore la taille du conteneur.
Une bonne pratique pour les conteneurs est que chaque conteneur doit faire une chose et la faire bien. Bien qu'il y ait des exceptions à cette règle, évitez la tendance à faire en sorte qu'un conteneur fasse plusieurs choses.
Maintenant, vous pourriez vous demander : « Dois-je exécuter ces conteneurs séparément ? Si je les exécute séparément, comment les connecter tous ensemble ? »
Bien que docker run
soit un outil pratique pour lancer des conteneurs, il devient difficile de gérer une pile d'applications croissante avec lui. Voici pourquoi :
- Imaginez exécuter plusieurs commandes
docker run
(frontend, backend et base de données) avec différentes configurations pour les environnements de développement, de test et de production. C'est source d'erreurs et chronophage. - Les applications dépendent souvent les unes des autres. Démarrer manuellement les conteneurs dans un ordre spécifique et gérer les connexions réseau devient difficile à mesure que la pile s'agrandit.
- Chaque application a besoin de sa propre commande
docker run
, ce qui rend difficile la mise à l'échelle des services individuels. La mise à l'échelle de l'ensemble de l'application signifie potentiellement un gaspillage de ressources sur des composants qui n'ont pas besoin d'un coup de pouce. - La persistance des données pour chaque application nécessite des montages de volume ou des configurations distincts dans chaque commande
docker run
. Cela crée une approche de gestion des données dispersée. - La définition de variables d'environnement pour chaque application via des commandes
docker run
distinctes est fastidieuse et source d'erreurs.
C'est là que Docker Compose vient à la rescousse.
Docker Compose définit l'ensemble de votre application multi-conteneurs dans un seul fichier YAML appelé compose.yml
. Ce fichier spécifie les configurations de tous vos conteneurs, leurs dépendances, les variables d'environnement, et même les volumes et les réseaux. Avec Docker Compose :
- Vous n'avez pas besoin d'exécuter plusieurs commandes
docker run
. Tout ce que vous avez à faire est de définir l'ensemble de votre application multi-conteneurs dans un seul fichier YAML. Cela centralise la configuration et simplifie la gestion. - Vous pouvez exécuter des conteneurs dans un ordre spécifique et gérer facilement les connexions réseau.
- Vous pouvez simplement mettre à l'échelle des services individuels à la hausse ou à la baisse dans la configuration multi-conteneurs. Cela permet une allocation efficace en fonction des besoins en temps réel.
- Vous pouvez implémenter des volumes persistants avec facilité.
- Il est facile de définir des variables d'environnement une seule fois dans votre fichier Docker Compose.
En tirant parti de Docker Compose pour exécuter des configurations multi-conteneurs, vous pouvez créer des applications complexes avec modularité, évolutivité et cohérence au cœur.
Essayez-le
Dans ce guide pratique, vous verrez d'abord comment construire et exécuter une application web de compteur basée sur Node.js, un proxy inverse Nginx et une base de données Redis à l'aide des commandes docker run
. Vous verrez également comment vous pouvez simplifier l'ensemble du processus de déploiement à l'aide de Docker Compose.
Configuration
-
Obtenez l'application exemple. Si vous avez Git, vous pouvez cloner le dépôt de l'application exemple. Sinon, vous pouvez télécharger l'application exemple. Choisissez l'une des options suivantes.
Utilisez la commande suivante dans un terminal pour cloner le dépôt de l'application exemple. ```console $ git clone https://github.com/dockersamples/nginx-node-redis ``` Naviguez dans le répertoire `nginx-node-redis` : ```console $ cd nginx-node-redis ``` À l'intérieur de ce répertoire, vous trouverez deux sous-répertoires - `nginx` et `web`.
Téléchargez la source et extrayez-la. <div class="button not-prose"> <a href="https://github.com/dockersamples/nginx-node-redis/archive/refs/heads/main.zip">Télécharger la source</a> </div> Naviguez dans le répertoire `nginx-node-redis-main` : ```console $ cd nginx-node-redis-main ``` À l'intérieur de ce répertoire, vous trouverez deux sous-répertoires - `nginx` et `web`.
-
Téléchargez et installez Docker Desktop.
Construire les images
-
Naviguez dans le répertoire
nginx
pour construire l'image en exécutant la commande suivante :$ docker build -t nginx .
-
Naviguez dans le répertoire
web
et exécutez la commande suivante pour construire la première image web :$ docker build -t web .
Exécuter les conteneurs
-
Avant de pouvoir exécuter une application multi-conteneurs, vous devez créer un réseau pour qu'ils puissent tous communiquer. Vous pouvez le faire à l'aide de la commande
docker network create
:$ docker network create sample-app
-
Démarrez le conteneur Redis en exécutant la commande suivante, qui l'attachera au réseau précédemment créé et créera un alias réseau (utile pour les recherches DNS) :
$ docker run -d --name redis --network sample-app --network-alias redis redis
-
Démarrez le premier conteneur web en exécutant la commande suivante :
$ docker run -d --name web1 -h web1 --network sample-app --network-alias web1 web
-
Démarrez le deuxième conteneur web en exécutant ce qui suit :
$ docker run -d --name web2 -h web2 --network sample-app --network-alias web2 web
-
Démarrez le conteneur Nginx en exécutant la commande suivante :
$ docker run -d --name nginx --network sample-app -p 80:80 nginx
NoteNginx est généralement utilisé comme proxy inverse pour les applications web, acheminant le trafic vers les serveurs backend. Dans ce cas, il achemine vers les conteneurs backend Node.js (web1 ou web2).
-
Vérifiez que les conteneurs sont en cours d'exécution en exécutant la commande suivante :
```console
$ docker ps
```
Vous verrez une sortie comme la suivante :
```text
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2cf7c484c144 nginx "/docker-entrypoint.…" 9 seconds ago Up 8 seconds 0.0.0.0:80->80/tcp nginx
7a070c9ffeaa web "docker-entrypoint.s…" 19 seconds ago Up 18 seconds web2
6dc6d4e60aaf web "docker-entrypoint.s…" 34 seconds ago Up 33 seconds web1
008e0ecf4f36 redis "docker-entrypoint.s…" About a minute ago Up About a minute 6379/tcp redis
```
-
Si vous regardez le tableau de bord de Docker Desktop, vous pouvez voir les conteneurs et approfondir leur configuration.
-
Avec tout en place et en cours d'exécution, vous pouvez ouvrir http://localhost dans votre navigateur pour voir le site. Actualisez la page plusieurs fois pour voir l'hôte qui traite la demande et le nombre total de demandes :
web2: Number of visits is: 9 web1: Number of visits is: 10 web2: Number of visits is: 11 web1: Number of visits is: 12
NoteVous avez peut-être remarqué que Nginx, agissant comme un proxy inverse, distribue probablement les requêtes entrantes de manière circulaire entre les deux conteneurs backend. Cela signifie que chaque requête peut être dirigée vers un conteneur différent (web1 et web2) de manière rotative. La sortie montre des incréments consécutifs pour les conteneurs web1 et web2 et la valeur réelle du compteur stockée dans Redis n'est mise à jour qu'après que la réponse est renvoyée au client.
-
Vous pouvez utiliser le tableau de bord de Docker Desktop pour supprimer les conteneurs en sélectionnant les conteneurs et en sélectionnant le bouton Supprimer.
Simplifier le déploiement à l'aide de Docker Compose
Docker Compose fournit une approche structurée et rationalisée pour la gestion des déploiements multi-conteneurs. Comme indiqué précédemment, avec Docker Compose, vous n'avez pas besoin d'exécuter plusieurs commandes docker run
. Tout ce que vous avez à faire est de définir l'ensemble de votre application multi-conteneurs dans un seul fichier YAML appelé compose.yml
. Voyons comment cela fonctionne.
Accédez à la racine du répertoire du projet. À l'intérieur de ce répertoire, vous trouverez un fichier nommé compose.yml
. Ce fichier YAML est l'endroit où toute la magie opère. Il définit tous les services qui composent votre application, ainsi que leurs configurations. Chaque service spécifie son image, ses ports, ses volumes, ses réseaux et tout autre paramètre nécessaire à son fonctionnement.
-
Utilisez la commande
docker compose up
pour démarrer l'application :$ docker compose up -d --build
Lorsque vous exécutez cette commande, vous devriez voir une sortie similaire à la suivante :
Running 5/5 ✔ Network nginx-nodejs-redis_default Created 0.0s ✔ Container nginx-nodejs-redis-web1-1 Started 0.1s ✔ Container nginx-nodejs-redis-redis-1 Started 0.1s ✔ Container nginx-nodejs-redis-web2-1 Started 0.1s ✔ Container nginx-nodejs-redis-nginx-1 Started
-
Si vous regardez le tableau de bord de Docker Desktop, vous pouvez voir les conteneurs et approfondir leur configuration.
-
Alternativement, vous pouvez utiliser le tableau de bord de Docker Desktop pour supprimer les conteneurs en sélectionnant la pile d'applications et en sélectionnant le bouton Supprimer.
Dans ce guide, vous avez appris à quel point il est facile d'utiliser Docker Compose pour démarrer et arrêter une application multi-conteneurs par rapport à docker run
qui est source d'erreurs et difficile à gérer.