# Docker Compose ## Définition **Docker Compose** est un outil qui permet de définir et de gérer des applications composées de plusieurs conteneurs. Dans les environnements de développement, une application peut être divisée en plusieurs services distincts (comme une base de données, un serveur web, un backend API, etc.), chacun étant exécuté dans son propre conteneur. Docker Compose permet de simplifier la gestion de ces applications complexes en définissant tous les conteneurs nécessaires, ainsi que leurs configurations respectives, dans un seul fichier appelé **compose.yml.** ## Le fichier Compose Le chemin par défaut d'un fichier Compose est `compose.yaml` (préféré) ou `compose.yml`, placé dans le répertoire de travail. Compose prend également en charge `docker-compose.yaml` et `docker-compose.yml` pour la rétrocompatibilité avec les versions antérieures. Si les deux fichiers existent, Compose privilégie le chemin canonique `compose.yaml`. Docker Compose utilise un format de fichier appelé *YAML (Yet Another Markup Language)* pour définir les configurations des services, des réseaux, et des volumes dans une application multi-conteneurs. > 💡 Il faut noter que la **structure** d’un fichier YAML est un mappage ou une liste, et qu’elle suit une **hiérarchie** qui dépend de l’indentation et de la façon dont vous définissez vos valeurs clés. Les mappages permettent d’associer des **paires de clé-valeur**. Chaque clé doit être unique, et sont suivies d’un deux-points et d’une espace, puis de sa valeur. Le fichier compose.yaml décrit : **Les services** : Chaque service correspond à un conteneur qui exécute une partie de l’application, comme une base de données ou un serveur web. **Les réseaux** : Docker Compose permet de définir des réseaux personnalisés, permettant aux conteneurs de communiquer entre eux de manière sécurisée. **Les volumes** : Les volumes permettent de persister les données entre les redémarrages de conteneurs et d’isoler les données du système de fichiers de l’hôte. > Si vous souhaitez réutiliser d'autres fichiers Compose ou factoriser des parties de votre modèle d'application dans des fichiers Compose distincts, vous pouvez également utiliser `include`. Ceci est utile si votre application Compose dépend d'une autre application gérée par une autre équipe ou doit être partagée avec d'autres. ## CLI L'interface de ligne de commande Docker vous permet d'interagir avec vos applications Docker Compose via la commande `docker compose` et ses sous-commandes. Si vous utilisez Docker Desktop, l'interface de ligne de commande Docker Compose est incluse par défaut. Grâce à l'interface de ligne de commande (CLI), vous pouvez gérer le cycle de vie de vos applications multi-conteneurs définies dans le fichier `compose.yaml`. Les commandes CLI vous permettent de démarrer, d'arrêter et de configurer vos applications sans effort. ### Commandes clés Pour démarrer tous les services définis dans votre fichier `compose.yaml` : ```sh $ docker compose up ``` Pour arrêter et supprimer les services en cours d’exécution : ```sh $ docker compose down ``` Si vous souhaitez surveiller la sortie de vos conteneurs en cours d'exécution et déboguer les problèmes, vous pouvez afficher les journaux avec : ```sh $ docker compose logs ``` Pour lister tous les services ainsi que leur état actuel : ```sh $ docker compose ps ``` Pour une liste complète de toutes les commandes CLI Compose, consultez la [documentation de référence](https://docs.docker.com/reference/cli/docker/compose/) . ### Avantages: **Gestion simplifiée** : Docker Compose facilite le déploiement et la gestion d’applications complexes qui nécessitent plusieurs services fonctionnant ensemble. > 💡 Exemple pour une application web : Un serveur web, une base de données, un serveur cache, et un service de messagerie **Fichier unique** : Docker Compose permet de centraliser toutes les configurations nécessaires à une application dans un seul fichier `compose.yaml`. Cela rend l’application plus facile à gérer, documenter, et déployer sur différents environnements (développement, test, production). > 💡 Cela inclut les configurations des conteneurs (comme les variables d’environnement, les ports, les volumes, les réseaux, et les secrets). **Réutilisabilité** : Une fois que vous avez défini vos configurations dans le fichier `compose.yaml`, elles peuvent être réutilisées sur différents systèmes ou partagées avec d’autres développeurs.  **Portabilité** : Les configurations définies dans un fichier Docker Compose sont indépendantes de l’environnement hôte. Que vous exécutiez votre application sur votre machine de développement, dans un environnement de test, ou en production, le même fichier `compose.yaml` peut être utilisé, assurant ainsi une portabilité maximale. Cela rend le processus de déploiement non seulement plus simple mais aussi plus fiable. ### Exemple illustratif L'exemple suivant illustre les concepts de Compose décrits ci-dessus. Cet exemple est non normatif. Considérez une application divisée en une application Web frontale et un service back-end. Le frontend est configuré au moment de l'exécution avec un fichier de configuration HTTP géré par l'infrastructure, fournissant un nom de domaine externe et un certificat de serveur HTTPS injecté par le magasin de secrets sécurisé de la plateforme. Le backend stocke les données dans un volume persistant. Les deux services communiquent entre eux sur un réseau `back-tier` isolé, tandis que le front-end est également connecté à un réseau `front-tier` et expose le port 443 pour une utilisation externe. ![composition](images/compose-application.webp) L'exemple d'application est composé des parties suivantes : * Deux services, soutenus par des images Docker : `webapp` et `database` * Un secret (certificat HTTPS), injecté dans le frontend * Une configuration (HTTP), injectée dans le frontend * Un volume persistant, attaché au backend * Deux réseaux Fichier `compose.yaml`: ```yaml services: frontend: image: example/webapp ports: - "443:8043" networks: - front-tier - back-tier configs: - httpd-config secrets: - server-certificate backend: image: example/database volumes: - db-data:/etc/data networks: - back-tier volumes: db-data: driver: flocker driver_opts: size: "10GiB" configs: httpd-config: external: true secrets: server-certificate: external: true networks: # The presence of these objects is sufficient to define them front-tier: {} back-tier: {} ``` La commande `docker compose up` démarre les services **frontend** et **backend**, crée les réseaux et volumes nécessaires et injecte la configuration et le secret dans le service frontend. > Il est recommandé d'utilisé `docker compose up -d` afin que le processus soit en mode détaché, afin de pouvoir reprendre la main sur le terminal. La commande `docker compose ps` fournit un instantané de l'état actuel de vos services, ce qui permet de voir facilement quels conteneurs sont en cours d'exécution, leur statut et les ports qu'ils utilisent : ```sh $ docker compose ps NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS example-frontend-1 example/webapp "nginx -g 'daemon of…" frontend 2 minutes ago Up 2 minutes 0.0.0.0:443->8043/tcp example-backend-1 example/database "docker-entrypoint.s…" backend 2 minutes ago Up 2 minutes ``` ## Bonnes Pratiques *Pour optimiser l’utilisation de Docker Compose en production et en développement, garantissant des applications plus robustes, sécurisées, et maintenables.* 1. **Utiliser des noms de service explicites pour une meilleure lisibilité** : - Utilisez des noms de service qui reflètent la fonction ou le rôle du conteneur. - Évitez les abréviations obscures ou les noms non descriptifs. - Gardez une cohérence dans la nomenclature à travers vos projets. 2. **Utiliser des volumes nommés pour la persistance des données** : - Évitez d’utiliser des volumes anonymes, car ils sont plus difficiles à gérer et peuvent mener à une perte de données involontaire. 3. **Utilisation des réseaux personnalisés:** - Créez des réseaux dédiés pour chaque stack ou chaque environnement (dev, test, prod). - Évitez de partager des réseaux entre des applications qui n’ont pas besoin de communiquer. 4. **Minimiser la taille des images avec des Dockerfiles multi-étapes** : - Utilisez des Dockerfiles multi-étapes pour séparer les phases de construction et d’exécution.