aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Outils & DevOps

Docker Compose : une application multi-services en un fichier

Docker Compose est l'outil qui permet de définir plusieurs conteneurs dans un seul fichier YAML et de les lancer tous d'une seule commande. Une véritable application se résume rarement à un seul processus : un serveur web, une base de données et, le plus souvent, une couche de cache fonctionnent ensemble. Les démarrer un par un avec docker run est à la fois fastidieux et source d'erreurs. Dans cet article, nous construirons de zéro une pile typique composée des services web, PostgreSQL et Redis, en abordant la communication entre services, les données persistantes et les variables d'environnement à travers des exemples concrets.

Quel problème résout Docker Compose ?

Lancer un seul conteneur est simple, mais dans les vrais projets les choses se compliquent vite. Chaque service a sa propre image, son port, son réseau et ses variables d'environnement — et ils doivent souvent démarrer dans un ordre précis. Compose déplace cette complexité dans un fichier déclaratif :

  • Source unique : toute la pile vit dans compose.yaml ; un collègue clone le dépôt et tape simplement docker compose up.
  • Réseau automatique : Compose crée un réseau partagé pour vos services, et les conteneurs se joignent par leur nom de service.
  • Reproductibilité : le même fichier produit la même pile sur la machine d'un développeur comme en CI.

Remarque : dans Docker moderne, la commande est docker compose (avec une espace) ; l'ancien binaire docker-compose (avec un tiret) fonctionne encore mais a été remplacé par Compose V2.

Votre premier fichier compose.yaml

Créez un dossier et ajoutez-y un compose.yaml. Commençons par un simple service web et une base de données :

services:
  web:
    image: nginx:1.27-alpine
    ports:
      - "8080:80"
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: appdb
    volumes:
      - db-data:/var/lib/postgresql/data

volumes:
  db-data:

Quelques détails importants : l'entrée "8080:80" sous ports relie le port 8080 de l'hôte au port 80 du conteneur. depends_on fait démarrer le service web après db (sans toutefois garantir que db soit réellement prête — nous y reviendrons). Le bloc volumes crée un volume persistant qui conserve les fichiers de la base même si le conteneur est supprimé.

Ajouter une couche de cache : Redis

La plupart des applications utilisent Redis pour les sessions, les files d'attente ou le cache. Ajouter un troisième service tient à un bloc supplémentaire :

services:
  web:
    image: nginx:1.27-alpine
    ports:
      - "8080:80"
    depends_on:
      - db
      - cache

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: appdb
    volumes:
      - db-data:/var/lib/postgresql/data

  cache:
    image: redis:7-alpine
    command: ["redis-server", "--save", "60", "1"]

volumes:
  db-data:

Voici le point agréable : depuis le conteneur web, vous atteignez la base via le nom d'hôte db et Redis via cache. Le DNS interne mis en place par Compose résout automatiquement le nom de service vers la bonne IP. Ainsi, dans la configuration de votre application, les chaînes de connexion deviennent postgres://app:secret@db:5432/appdb et redis://cache:6379 — aucune IP codée en dur n'est nécessaire.

Variables d'environnement et fichier .env

Coder en dur les mots de passe dans le YAML est une mauvaise idée. Compose lit automatiquement un fichier .env voisin et substitue les variables avec la syntaxe ${...} :

# .env
POSTGRES_PASSWORD=une-valeur-tres-secrete
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: appdb

Ajoutez .env à votre .gitignore pour que les secrets ne se retrouvent jamais dans le dépôt. Laisser un exemple .env.example pour le reste de l'équipe est une bonne habitude.

Une vraie disponibilité avec les health checks

depends_on ne contrôle que l'ordre de démarrage ; il ne garantit pas que la base accepte les connexions. Le service web peut tenter de se connecter alors que db démarre encore, et échouer. La solution consiste à définir un healthcheck et à combiner depends_on avec condition: service_healthy :

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: appdb
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d appdb"]
      interval: 5s
      timeout: 3s
      retries: 5

  web:
    image: nginx:1.27-alpine
    ports:
      - "8080:80"
    depends_on:
      db:
        condition: service_healthy

Désormais, le conteneur web ne démarre qu'après le succès de la commande pg_isready. Cela élimine la plupart des erreurs du type « la base n'est pas encore prête ».

Au quotidien : les commandes essentielles

Voici les commandes que vous utiliserez le plus souvent pour lancer et gérer la pile :

  • docker compose up -d — démarre tous les services en arrière-plan.
  • docker compose ps — liste les services en cours et leur état.
  • docker compose logs -f web — suit en direct les logs d'un service précis.
  • docker compose exec db psql -U app appdb — exécute une commande dans le conteneur db en cours.
  • docker compose down — arrête et supprime les services. Ajoutez -v pour supprimer aussi les volumes.

Si vous avez modifié une image (par exemple, vous construisez votre propre Dockerfile), reconstruisez avec docker compose up -d --build.

Questions fréquentes

Quelle est la différence entre docker-compose et docker compose ?

docker-compose (avec tiret) est l'ancien outil V1 écrit en Python. docker compose (avec espace) est le plugin V2 basé sur Go, intégré au CLI Docker. Sur les installations actuelles, il faut utiliser la version avec espace ; la syntaxe YAML est en grande partie identique.

Mes données seront-elles perdues quand le conteneur est supprimé ?

Non — les volumes nommés définis sous volumes sont indépendants du cycle de vie du conteneur. docker compose down supprime les conteneurs, mais le volume reste ; vos données sont toujours là au prochain up. Seul down -v supprime aussi les volumes.

Compose convient-il à la production ?

Il convient parfaitement aux petites et moyennes configurations sur un seul serveur. Pour des systèmes multi-nœuds, à mise à l'échelle automatique et auto-réparants, un orchestrateur comme Kubernetes est un meilleur choix. Pensez à Compose pour le développement et les scénarios de production simples, et à Kubernetes pour la grande échelle.

Vous souhaitez regrouper votre pile dans un seul fichier ? Pour simplifier votre développement et votre déploiement avec Docker Compose, contactez-moi — planifions ensemble l'infrastructure de votre projet.

Bu kategorideki tüm yazılar →

Devamı için