Serveurs Vps Docker compose Conteneurs

Docker Compose : guide multi-conteneurs

Docker Compose orchestre plusieurs conteneurs avec un fichier lisible : services, réseau, volumes, secrets, santé et diagnostic sans perte de données.

Julien Bernard
Julien Bernard

Serveurs dédiés, infogérance et migration

Il couvre les serveurs dédiés, l'infogérance, le stockage, la supervision et les plans de sortie.

9 min de lecture

Docker Compose décrit une application composée de plusieurs conteneurs dans un fichier compose.yaml, puis les crée, les relie et les arrête comme un ensemble. Pour un déploiement fiable, séparez les services, persistez les données, attendez les contrôles de santé et validez la configuration avant chaque démarrage.

Sur un serveur comme dans un atelier, ranger les outils ne les rend pas infaillibles. Compose rend leurs relations explicites : image ou construction locale, réseau, volume, configuration, secret et ordre de démarrage. Cette lisibilité permet de relire l’application avant de la lancer et de comprendre ce qui survivra à son arrêt.

Ce guide construit un exemple générique avec une application et une base de données. Adaptez les noms de variables à votre logiciel : une image n’accepte pas magiquement les paramètres montrés ici. Commencez par le contrat de l’image, puis écrivez le fichier Compose qui le respecte.

Docker Compose est un contrat d’application

Le fichier compose.yaml décrit l’état attendu. La section services contient les composants exécutables. Les sections volumes, networks et secrets déclarent des ressources partagées ou contrôlées. La spécification Compose actuelle est la référence ; ajouter une ancienne clé version n’améliore pas la compatibilité et détourne l’attention du modèle réellement appliqué.

Un service n’est pas un serveur miniature. C’est une définition à partir de laquelle Compose crée un conteneur. Deux services qui partagent un réseau peuvent se joindre par leur nom de service. Ils n’ont pas besoin de connaître une adresse IP de conteneur, car cette adresse peut changer lors d’une recréation.

Avant d’écrire le YAML, dressez cet inventaire :

  • processus : application, base, cache, proxy ou tâche ponctuelle ;
  • données durables : répertoires qui doivent survivre au conteneur ;
  • flux réseau : communications internes et ports réellement publics ;
  • configuration : valeurs non sensibles qui changent selon l’environnement ;
  • secrets : mots de passe, clés et certificats à distribuer au strict nécessaire ;
  • signal de disponibilité : test qui prouve que chaque dépendance répond vraiment.

Si cet inventaire reste flou, le fichier sera seulement une collection de commandes déplacée en YAML.

Construire un fichier multi-services lisible

L’exemple suivant sépare une application construite localement d’une base PostgreSQL. Le réseau front reçoit l’application, tandis que le réseau back relie l’application à la base. Le volume db-data conserve les données. Le secret db-password est accordé aux deux services parce que chacun doit lire le même mot de passe.

name: atelier

services:
  app:
    build: ./app
    ports:
      - "127.0.0.1:8080:8080"
    environment:
      DATABASE_HOST: db
      DATABASE_NAME: app
      DATABASE_USER: app
      DATABASE_PASSWORD_FILE: /run/secrets/db-password
    secrets:
      - db-password
    depends_on:
      db:
        condition: service_healthy
        restart: true
    networks:
      - front
      - back

  db:
    image: postgres:alpine
    environment:
      POSTGRES_DB: app
      POSTGRES_USER: app
      POSTGRES_PASSWORD_FILE: /run/secrets/db-password
    secrets:
      - db-password
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d app"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - back

networks:
  front:
  back:
    internal: true

volumes:
  db-data:

secrets:
  db-password:
    file: ./secrets/db-password.txt

Ne copiez pas cet exemple sans vérifier l’image. Le suffixe de variable FILE est une convention acceptée par certaines images officielles, pas une capacité universelle. Votre application locale doit elle aussi savoir lire le fichier indiqué. Sinon, adaptez son point d’entrée sans remettre le secret en clair dans le YAML.

Le fichier de secret reste sur l’hôte. Excluez-le du gestionnaire de versions, limitez ses permissions et prévoyez sa sauvegarde séparée. Compose le monte dans les services autorisés sous le répertoire des secrets ; il ne devient pas pour autant un coffre-fort distant ni un système de rotation.

Réseau : publier uniquement ce qui doit sortir

Le nom db est l’adresse stable dans le projet. L’application contacte la base avec ce nom sur le réseau back. Publier le port PostgreSQL sur l’hôte serait inutile pour ce trajet et augmenterait la surface exposée.

La liaison du port applicatif commence par l’adresse loopback de l’hôte. Elle rend le service accessible depuis la machine, mais pas directement depuis toutes ses interfaces. Un proxy installé sur l’hôte peut alors le publier avec TLS et les règles d’accès adaptées.

Si le proxy tourne lui-même dans Compose, placez-le sur le réseau front et retirez le port hôte de l’application. Le trafic reste ainsi dans le réseau du projet jusqu’au composant chargé de l’exposition publique.

Un port écrit seulement sous la forme hôte:conteneur est généralement lié à toutes les interfaces de la machine. Vérifiez l’adresse de liaison, pas seulement le numéro. Sur un VPS doté d’une adresse publique, une omission devient vite une exposition réelle.

Les réseaux explicites servent aussi de cloison. Le service db ne rejoint pas front ; un composant attaché uniquement à front ne peut donc pas le contacter. Cette séparation ne remplace ni l’authentification ni le pare-feu, mais elle évite les chemins réseau gratuits.

Dépendances : démarré ne veut pas dire prêt

depends_on organise la création, pas la disponibilité métier. Sans condition de santé, Compose sait qu’un conteneur de base a démarré, pas qu’il accepte déjà des connexions. Une application rapide peut tenter sa première connexion pendant l’initialisation de PostgreSQL et échouer alors que les deux conteneurs paraissent actifs.

Le healthcheck de l’exemple interroge PostgreSQL avec son propre outil. La condition service_healthy demande à Compose d’attendre ce verdict avant de créer l’application. Les temporisations sont des valeurs de départ, pas des constantes sacrées. Ajustez-les à la durée réelle d’initialisation et au coût du test.

Gardez aussi une stratégie de reconnexion dans l’application. Un contrôle de santé règle la course au premier démarrage ; il ne garantit pas qu’une dépendance restera disponible. Une base peut redémarrer plus tard, un réseau peut être brièvement indisponible et une opération de maintenance peut recréer le conteneur.

La directive restart placée dans la dépendance de l’exemple concerne les redémarrages explicites effectués par Compose. Elle aide l’application à rétablir sa connexion après une opération contrôlée. Elle ne remplace ni une politique de redémarrage du conteneur ni le traitement des erreurs dans le code.

Données, configuration et secrets

Ces trois mécanismes répondent à des besoins différents :

BesoinMécanismeContrôle indispensable
Conserver l’état de la baseVolume nomméSauvegarde et restauration testée
Régler un comportement non sensibleenvironment ou env_fileValeur finale après interpolation
Fournir un mot de passe ou une cléSecret accordé au servicePermissions, rotation et absence des journaux
Monter du code local en développementBind mountPropriétaire, droits et impact sur l’image

Un volume n’est pas une sauvegarde. Il survit à la recréation d’un conteneur, mais reste lié au moteur Docker et au stockage de l’hôte. Le disque décide souvent au pire moment : exportez les données avec l’outil de la base et testez la restauration ailleurs.

Le fichier .env sert d’abord à l’interpolation du modèle Compose. La section env_file ou environment peuple l’environnement du conteneur. Ces chemins se ressemblent assez pour provoquer des erreurs de priorité. Affichez le modèle résolu avant le démarrage et n’utilisez pas l’environnement pour dissimuler un secret : il peut apparaître dans un diagnostic ou un journal.

Valider, démarrer et diagnostiquer

Validez avant de modifier l’hôte. La commande config résout les variables, fusionne les fichiers éventuels et rend le modèle canonique. Son mode silencieux permet un contrôle simple dans une intégration continue.

docker compose config
docker compose config --quiet

Relisez particulièrement les ports, les chemins, les noms d’images et les variables vides. Une configuration valide syntaxiquement peut rester dangereuse opérationnellement.

Démarrez ensuite le projet, puis observez son état avant de conclure :

docker compose up -d --build
docker compose ps
docker compose logs --tail 100 app db

Si un service échoue, réduisez le diagnostic à sa frontière :

docker compose logs app
docker compose logs db
docker compose exec app getent hosts db
docker compose config --environment

La résolution du nom db confirme le chemin réseau, pas la disponibilité de PostgreSQL. Les journaux de la base et son état de santé complètent le diagnostic. Demandez le plan de panne : quel signal distingue une erreur de configuration, une dépendance indisponible et une donnée corrompue ?

Arrêter sans effacer les données

La commande suivante arrête le projet et supprime ses conteneurs ainsi que les réseaux créés pour lui. Les volumes nommés restent présents.

docker compose down

L’option qui ajoute la suppression des volumes change complètement le niveau de risque. Elle convient à un environnement jetable dont les données peuvent être recréées, pas à une base que personne n’a sauvegardée.

docker compose down --volumes

Avant cette commande, listez les volumes du projet, identifiez leur contenu et restaurez une sauvegarde sur une autre cible. La persistance doit avoir un chemin d’entrée, mais aussi un chemin de sortie. La migration fait partie du coût, même pour une petite pile auto-hébergée.

Quand choisir ou éviter Docker Compose

SituationCompose convientRéserve à traiter
Développement local multi-servicesOuiAlignement avec l’environnement cible
Application sur un seul hôte administréOuiSauvegardes, supervision et procédure de retour
Petit service interne stableOuiMises à jour d’images et exposition réseau
Répartition automatique sur plusieurs hôtesNonUtiliser un orchestrateur conçu pour ce rôle
Déploiement sans interruption exigéPas seulPrévoir proxy, stratégie de bascule et supervision
Équipe sans propriétaire opérationnelNonChoisir un service géré ou attribuer l’exploitation

Compose est un bon choix quand la limite de l’application tient sur un hôte et dans un fichier que l’équipe sait relire. Il devient un mauvais alibi quand personne ne possède les sauvegardes, les alertes ou la procédure de mise à jour.

Liste de contrôle

  • Vérifiez le modèle résolu et bloquez toute variable vide, tout port public inattendu ou tout chemin absent.
  • Contrôlez chaque dépendance avec un test de santé qui mesure la disponibilité utile, pas seulement un processus actif.
  • Restaurez le volume de données sur une cible distincte afin de mesurer le risque réel avant une mise à jour.
  • Documentez l’arrêt, la recréation et le retour arrière avant de confier le projet à une exploitation régulière.

Questions fréquentes

Faut-il ajouter une clé version dans compose.yaml ?
Non. La spécification Compose actuelle est la référence recommandée. Décrivez les services et ressources nécessaires, puis validez le modèle avec la version de Compose installée.
Comment deux services Compose communiquent-ils ?
Ils doivent partager un réseau. Chaque service y est joignable par son nom ; utilisez ce nom plutôt qu’une adresse IP de conteneur susceptible de changer.
depends_on suffit-il pour attendre une base de données ?
Non. Il faut associer un healthcheck à la base et une condition service_healthy à la dépendance, puis conserver des tentatives de reconnexion dans l’application.
Un fichier .env protège-t-il les mots de passe ?
Non. Il facilite la configuration et l’interpolation. Pour une donnée sensible, accordez un secret uniquement aux services qui en ont besoin et organisez sa rotation.

Préparé par

Julien Bernard
Julien Bernard

Serveurs dédiés, infogérance et migration

Il couvre les serveurs dédiés, l'infogérance, le stockage, la supervision et les plans de sortie.

Faits vérifiés

HostScout editorial

Articles liés