Docker Compose

09 Docker Compose : Création et gestion de multi-conteneur

L’un des principaux avantages de la conteneurisation est qu’elle nous permet de partitionner un serveur en services distincts. Nous pouvons ainsi déployer et gérer chaque service de manière indépendante. Contrairement aux machines virtuelles, où tous les services s’exécutent sur le même système d’exploitation, la conteneurisation offre une flexibilité accrue. Lors des mises à jour, nous devons souvent arrêter la machine virtuelle, ce qui entraîne des interruptions de service et des pertes financières. Cependant, avec la conteneurisation, chaque service s’exécute dans son propre conteneur. Les conteneurs partagent le noyau du système d’exploitation, ce qui les rend plus légers et plus portables que les machines virtuelles. De plus, Docker Compose nous permet de déployer des services rapidement et facilement, et de les mettre à l’échelle de manière dynamique.

Présentation de Docker Compose

Docker Compose est un service qui permet d’envoyer des instructions à Docker, telles que la spécification des dépendances, des informations de configuration et des interactions, afin de créer et de gérer des conteneurs Docker pour une application multi-conteneurs. Les instructions sont données sous forme de mot clé dont en voici les principaux utilisés :

  • version : Spécifie la version de la syntaxe Docker Compose à utiliser.
  • networks : Définit les réseaux auxquels un service est connecté.
  • services : Définit les différents services (conteneurs) qui composent votre application.
  • command : Spécifie la commande à exécuter dans le conteneur lors du démarrage.
  • image : Indique l’image Docker à utiliser pour un service.
  • volumes_from : Montez des volumes à partir d’un autre service.
  • build : Permet de construire une image personnalisée pour un service en utilisant un Dockerfile.
  • links : Crée des liaisons entre les services pour permettre la communication.
  • ports : Définit les ports à exposer depuis le conteneur vers l’hôte.

  • restart : Définit la politique de redémarrage du service en cas d’échec.

  • volumes : Spécifie les volumes à monter pour un service, permettant le partage de données

  • logging : Configure les options de journalisation pour le service.

  • environment : Définit des variables d’environnement pour un service.

  • configs et secrets : Pour spécifier des configurations et des secrets à utiliser dans un service dans un environnement de swarm.
  • depends_on : Déclare les dépendances entre les services pour garantir l’ordre de démarrage.
  • healthcheck : Définit des vérifications de santé pour un service.

Les instructions doivent être contenu dans un fichier qui se nommera « docker-compose.yml ». Dans ce Docker compose, nous allons pouvoir faire des appels à des Dockerfiles. Dans un premier temps nous nous concentrerons sur Docker compose. Cela nous permettra de comprendre sont fonctionnement. Dans un second temps nous verrons comment faire fonctionner Docker-compose avec des Dockerfiles.

Exemple de Docker-compose

Pour illustrer, nous prendrons comme exemple la conteneurisation d’un stack LAMP (Linux Apache MariaDB et PHP) où nous installerons WordPress.

Installation de Docker Compose

Avant cela, nous allons avoir besoin d’installer l’outils Docker Compose. Docker Compose est un outil écrit en Python et il est distribué via le gestionnaire de paquet Python appelé « pip ».

Installation le gestionnaire pip puis nous installerons Docker-Compose.

[root@docker ~]# dnf install -y python3-pip
[root@docker ~]# pip3 install docker-compose
Création environnement de travail

Ensuite, nous créerons ensuite un répertoire de travail.

[root@docker ~]# mkdir /home/Stack-LAMP
Création du fichier YAML

Nous ne rendrons dans le répertoire que nous avons créés , nous créerons un fichier nommé « docker-compose.yml ». Nous éditerons ce fichier à l’aide d’un éditeur de texte en ligne de commande (nano, vi, etc…)

[root@docker ~]# cd /home/Stack-LAMP/
[root@docker Stack-LAMP]# vi docker-compose.yml
Contenu du fichier de YAML

Pour rappel, les fichiers YAML à une syntaxe basée sur l’indentation (espaces ou tabulations). Cette contrainte rend le code plus lisible mais exige une attention particulière à la mise en forme. Rappelons également YAML est sensible à la case.

Dans un premier temps , nous allons définir la version de la syntaxe qui sera utilisé dans ce fichier. La version de la syntaxe est liée à la version de Docker Engine installée sur la machine. Dans notre exemple, nous sommes en version 24.0.5, nous utiliserons la version 3.8.

Nous commencerons donc notre fichier à déclarer la version de la syntaxe.

version: '3.8'
Déclaration des services

Ensuite, nous allons spécifier nos services : un container hébergera la base de données, le second hébergera le serveur web et l’application WordPress. Ses informations seront renseignées dans la section « services ».

version: '3.8'
services :
#Service base de données
db :
#Instruction
# Web Server et wordpress
wordpress :
#Instruction
Instruction pour le service db

Dans les instructions du conteneur db, nous indiquerons l’images que nous utiliserons, à savoir l’image officiel de mariadb dans sa dernière version, les données de la base de données devront être persistante, nous montrons donc un volume.

services :
#Service base de données
db:
 image: mariadb:latest
 volumes:
 - db_data:/var/lib/mysql
# Web Server et wordpress
wordpress :
#Instruction

Nous allons définir les variables d’environnement pour paramétrer la base de données, en spécifiant un mot de passe pour l’utilisateur root. Nous créerons également un utilisateur dédié à la gestion de la base de données WordPress, avec un identifiant et un mot de passe spécifiques, et créerons une base de données dédiée à WordPress.

services :
#Service base de données
db:
image: mariadb:latest
volumes:
- db_data:/var/lib/mysql
 environment:
 MYSQL_ROOT_PASSWORD: p@ssw0rd1
 MYSQL_DATABASE: wordpress
 MYSQL_USER: wordpress_user
 MYSQL_PASSWORD: p@ssw0rd1
# Web Server et wordpress
wordpress :
#Instruction
Instruction pour le service WordPress

Le conteneur de notre base de données étant configuré, nous pouvons maintenant passer à la création de notre conteneur WordPress. Nous indiquerons que le conteneur « wordpress » dépend du conteneur « db », cela aura pour conséquence que Docker s’assurera que le container « db» soit démarrer avant le container « Apache ».

services :
#Service base de données
db:
#+---------------+
#|Instruction db |
#+---------------+
# Web Server et wordpress
wordpress :
 depends_on:
 - db
 image: wordpress:latest

Le conteneur « wordpress » sera en écoute sur le port 80 de la machine hôte, il nous faut donc mapper le port 80 de notre conteneur (qui est le port pas défaut d’écoute du serveur web) sur le port 80 de la machine hôte.

services :
#Service base de données
db:
#+---------------+
#|Instruction db |
#+---------------+
# Web Server et wordpress
wordpress :
depends_on:
- db
image: wordpress:latest
 ports:
 - "80:80"

Les données de l’application seront persistantes, nous créerons le volumes pour stocker les fichiers de WordPress.

services :
#Service base de données
db:
#+---------------+
#|Instruction db |
#+---------------+
# Web Server et wordpress
wordpress :
depends_on:
- db
image: wordpress:latest
ports:
- "80:80"
 volumes:
 - wordpress_data:/var/www/html

Pour conclure la configuration du conteneur, nous configurerons notre environnement pour permettre à WordPress de se connecter à la base de donnée que nous avons préparer dans le conteneur « db ».

services :
#Service base de données
db:
#+---------------+
#|Instruction db |
#+---------------+
# Web Server et wordpress
wordpress :
depends_on:
- db
image: wordpress:latest
ports:
- "80:80"
volumes:
- wordpress_data:/var/www/html
 environment:
 WORDPRESS_DB_HOST: db
 WORDPRESS_DB_USER: wordpress_user
 WORDPRESS_DB_PASSWORD: p@ssw0rd1
 WORDPRESS_DB_NAME: wordpress
Gestion des volumes

Pour assurer la persistance des données des volumes utilisées par nos conteneurs, nous devons les déclarés explicitement. Nous monterons le volumes que nous avons utilisées dans nos conteneurs.

services :
#Service base de données
db:
#+---------------+
#|Instruction db |
#+---------------+
# Web Server et wordpress
wordpress :
depends_on:
- db
image: wordpress:latest
ports:
- "80:80"
volumes:
- wordpress_data:/var/www/html
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress_user
WORDPRESS_DB_PASSWORD: p@ssw0rd1
WORDPRESS_DB_NAME: wordpress
volumes:
 db_data:
 wordpress_data:
Exécution du Docker compose

Nous exécuterons ce docker-compose à l’aide de la commande suivante :

[root@docker Stack-LAMP]# docker compose up

Après avoir exécuter la commande, un certain nombre de tâche s’exécute, notamment les téléchargement des images utilisées dans le fichier docker-compose.yml. Une fois que toutes les tâches ont été exécuté, nous testerons l’accès à notre serveur WordPress depuis un navigateur.

Exécution de nos conteneur en arriere plan avec Docker-compose

Notre serveur est pleinement opérationnel. Ceux-ci étant dit, nous avons perdu l’accès à notre terminal, en effet, il est attaché à nos conteneurs, si nous le détachons cela provoquera l’arrêt des conteneurs. Pour exécuter les containeurs en arrière-plan, nous devons ajouter le commutateur « -d », lorsque nous exécutons le docker-compose. Pour tester cette commande, nous allons supprimer ce que nous avons fait, nous tuerons nos conteneurs à l’aide de la combinaison de touche [ctrl]+[c].

Nous supprimerons les services à l’aide de la commande suivante :

[root@docker Stack-LAMP]# docker compose down

Dans notre docker-compose des volumes sont créés, nous les supprimerons afin de repartir d’une configuration initiale, nous listerons les volumes pour récupérer leurs noms complets.

[root@docker Stack-LAMP]# docker volume list | grep "stack-lamp"
[root@docker Stack-LAMP]# docker volume rm stack-lamp_db_data stack-lamp_wordpress_data

Nous exécutons à nouveau le docker-compose en précisant l’option « -d ».

Docker Compose offre une approche déclarative, simplifiant la définition complète d’une application, de ses services, de ses dépendances et de ses configurations dans un unique fichier (docker-compose.yml). Cette approche favorise un déploiement homogène et reproductible en décrivant l’état souhaité sans spécifier les détails de mise en œuvre.

Pour exploiter pleinement Docker Compose, il est essentiel de comprendre comment l’associer à un autre élément clé de l’écosystème Docker que nous avons vu plus tôt : les Dockerfiles.