## Introduction

Docker Compose est un outil incontournable pour définir et exécuter des applications multi-conteneurs, notamment en développement et dans des environnements de production de taille modeste. Cependant, lorsque vous devez mettre à niveau l'outil Compose lui-même, migrer vers une nouvelle version majeure ou déplacer votre pile de production vers un autre hôte, l'absence de plan clair entraîne des interruptions de service et des retours en arrière difficiles. Une approche structurée maintient la disponibilité de vos services et la confiance de votre équipe.

Ce guide présente un parcours pratique de mise à niveau et de migration de Docker Compose en production. Vous apprendrez à inventorier votre environnement actuel, à préparer des modifications de configuration sûres, à valider la mise à niveau avec des commandes concrètes, à gérer les modes de défaillance avec des procédures de retour en arrière et à suivre une liste de contrôle reproductible. Chaque étape inclut des commandes réelles et les sorties attendues. L'accent est mis sur un déploiement Compose sur un seul hôte, et non sur Swarm ou Kubernetes.

À la fin, vous serez en mesure d'exécuter une mise à niveau ou une migration Compose à faible risque et de récupérer rapidement en cas de problème.

## Inventaire des versions et de l'environnement

Avant de toucher à quoi que ce soit en production, vous devez avoir une vision complète de ce que vous possédez. Cela évite les surprises dues à des incompatibilités de versions, des dépendances manquantes ou une dérive de l'environnement. Un inventaire clair est la base d'une migration sûre.

### Vérifier les versions de Docker et Compose

Sur votre hôte de production, exécutez :

```bash
docker version
```

La sortie attendue inclut les versions du client et du serveur. Recherchez la compatibilité des versions d'API. Exemple (tronqué) :

```
Client: Docker Engine - Community
 Version:           24.0.7
 API version:       1.43
Server: Docker Engine - Community
 Engine:
  Version:          24.0.7
  API version:      1.43 (minimum version 1.12)
```

Ensuite, vérifiez la version de Docker Compose :

```bash
docker compose version
```

Notez si vous utilisez le `docker-compose` autonome (v1) ou le plugin `docker compose` (v2). La sortie indique :

```
Docker Compose version v2.23.0
```

Si `docker-compose` (avec trait d'union) est installé, vérifiez-le séparément :

```bash
docker-compose version
```

### Inventorier les services en cours d'exécution

Listez tous les conteneurs en cours d'exécution pour votre projet Compose :

```bash
docker compose ps
```

Ou, si vous utilisez une ancienne version autonome :

```bash
docker-compose ps
```

La sortie attendue montre les noms des services, leur état et les ports. Exemple :

```
NAME                COMMAND                  SERVICE             STATUS              PORTS
myapp_web_1         "nginx -g 'daemon of..."   web                 running             0.0.0.0:80->80/tcp
myapp_db_1          "docker-entrypoint.s..."   db                  running             5432/tcp
```

Notez cet état. Si quelque chose casse plus tard, vous pourrez comparer.

### Capturer la configuration actuelle

Sauvegardez toujours votre configuration de travail actuelle. Copiez l'intégralité du répertoire du projet, qui contient généralement `docker-compose.yml`, `.env` et les fichiers montés en bind. Par exemple :

```bash
tar -czf compose-backup-$(date +%Y%m%d).tar.gz /opt/myapp
```

Stockez cette archive hors du serveur, par exemple sur une machine locale ou un stockage d'objets.

### Identifier les variables d'environnement et les secrets

Les fichiers Compose font souvent référence à des variables d'environnement provenant d'un fichier `.env` ou du shell. Listez-les sans exposer les secrets :

```bash
docker compose config
```

Cette commande valide et affiche la configuration entièrement résolue. C'est un outil crucial. La sortie est longue, redirigez-la vers un fichier pour examen :

```bash
docker compose config > resolved-compose.yml
```

Ouvrez `resolved-compose.yml` et recherchez toute valeur incorrecte, manquante ou codée en dur. Cela confirme également quelle version de fichier Compose est interprétée.

### Prérequis pour la mise à niveau/migration

Avant de continuer, assurez-vous :

- Vous avez un accès SSH à l'hôte et des privilèges sudo si nécessaire.
- L'hôte dispose de suffisamment d'espace disque pour les nouvelles images. Vérifiez avec `df -h`.
- Vous connaissez l'état actuel des volumes persistants : `docker volume ls` et `docker volume inspect <volume>`.
- Vous avez un point de retour en arrière : l'archive de sauvegarde et un instantané de la base de données le cas échéant.
- Vous comprenez toutes les dépendances externes (équilibreurs de charge, DNS, surveillance) qui pointent vers cet hôte.

Documentez tout ce qui précède dans un tableau simple ou des notes. Voici un exemple de tableau d'inventaire :

| Élément                  | Valeur actuelle         | Notes                       |
|-----------------------|-----------------------|-----------------------------|
| Version Docker Engine | 24.0.7                | Prend en charge Compose v2  |
| Version Compose       | v2.23.0               | Plugin, non autonome        |
| Version fichier Compose | 3.8                   | Champ `version` de niveau supérieur |
| Services en cours d'exécution | web, db, cache        | Tous sains                  |
| Volumes persistants    | myapp_db_data         | Données PostgreSQL          |
| Fichier d'environnement | /opt/myapp/.env       | Contient le mot de passe DB |

Cet inventaire guidera toutes les étapes suivantes.

## Parcours de configuration sûr

Maintenant que vous connaissez l'état actuel, vous pouvez planifier la mise à niveau ou la migration en toute sécurité. La clé est d'apporter des modifications petites et révisables et de les tester avant de les appliquer en production.

### Décider des versions cibles

Déterminez vers quelles versions de Docker Engine et Compose vous souhaitez migrer. Consultez les matrices de compatibilité de la documentation Docker. Par exemple, Compose v2 nécessite Docker Engine 20.10 ou ultérieur. La mise à niveau de Compose seul est souvent plus simple que celle du moteur.

Si vous migrez également vers un nouvel hôte, les versions sur le nouvel hôte doivent être au moins identiques à celles de l'ancien, de préférence plus récentes.

### Utiliser un environnement de préproduction ou de staging

Idéalement, vous disposez d'un environnement de staging qui reflète la production. Mais même sans cela, vous pouvez tester la mise à niveau sur une machine virtuelle distincte ou une copie de l'hôte de production (par exemple, un instantané chez un fournisseur de cloud). C'est là que vous exécutez le premier pilote.

Créez un environnement de test aussi proche que possible de la production. Utilisez le même système d'exploitation, les mêmes versions de Docker et la même configuration Compose résolue. Ensuite, appliquez-y les étapes de mise à niveau et observez les résultats.

### Mettre à niveau Docker Compose (si la cible est uniquement Compose)

Si vous devez uniquement mettre à niveau Compose sur l'hôte existant, suivez la méthode d'installation officielle pour votre système d'exploitation. Pour Linux avec le plugin, vous pouvez le mettre à jour via le gestionnaire de paquets, par exemple sur Ubuntu :

```bash
sudo apt update && sudo apt upgrade docker-compose-plugin
```

Si vous avez installé le binaire manuellement, téléchargez le nouveau binaire et remplacez l'ancien :

```bash
sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
```

Après l'installation, vérifiez :

```bash
docker compose version
```

La sortie attendue affiche la nouvelle version.

### Mettre à niveau Docker Engine (si nécessaire)

Si le moteur doit également être mis à niveau, reportez-vous au guide officiel de mise à niveau Docker pour votre distribution. En général, vous arrêtez d'abord tous les conteneurs proprement :

```bash
docker compose down
```

Ensuite, mettez à niveau les paquets Docker et redémarrez Docker. Une fois le moteur mis à niveau, relancez la pile :

```bash
docker compose up -d
```

Testez toujours cela sur staging au préalable.

### Migration vers un nouvel hôte

Si vous migrez vers un nouveau serveur, la séquence la plus sûre est la suivante :

- Configurez le nouvel hôte avec les versions souhaitées de Docker et Compose.
- Copiez le répertoire du projet (y compris `.env` et les éventuels montages bind) vers le nouvel hôte.
- Sur l'ancien hôte, arrêtez l'application pour assurer la cohérence des données : `docker compose down` (mais conservez les volumes si vous devez copier les données).
- Copiez les volumes persistants de l'ancien hôte vers le nouveau. Une méthode consiste à utiliser `docker run` avec un pipe tar :

Depuis l'ancien hôte, pour chaque volume (par exemple, `myapp_db_data`) :

```bash
docker run --rm -v myapp_db_data:/data -v /tmp:/backup alpine tar czf /backup/myapp_db_data.tar.gz -C /data .
```

Copiez ensuite l'archive tar vers le nouvel hôte et restaurez :

```bash
docker run --rm -v myapp_db_data:/data -v /tmp:/backup alpine sh -c "cd /data && tar xzf /backup/myapp_db_data.tar.gz"
```

Remarque : cette méthode est acceptable pour de petits volumes. Pour les bases de données volumineuses ou critiques, utilisez plutôt les outils de sauvegarde natifs (par exemple, `pg_dump`).

- Sur le nouvel hôte, démarrez la pile : `docker compose up -d`.
- Vérifiez que tout fonctionne, puis basculez le trafic (DNS ou équilibreur de charge) vers le nouvel hôte.
- Conservez l'ancien hôte pendant une période de retour en arrière, puis mettez-le hors service.

### Modifier le fichier Compose pour la nouvelle version

Si la nouvelle version de Compose introduit des changements (par exemple, la suppression du champ `version` est désormais recommandée en v2), mettez à jour votre `docker-compose.yml` en conséquence. Testez avec `docker compose config` pour vous assurer qu'il n'y a ni avertissement ni erreur.

Exemple : supprimez la ligne `version` de niveau supérieur si elle est présente (Compose v2 ne l'utilise plus).

### Utiliser des overrides d'environnement pour des modifications plus sûres

Au lieu de modifier directement le fichier principal, utilisez un fichier override pour les modifications spécifiques à l'environnement. Par exemple, `docker-compose.override.yml` peut définir des limites de ressources ou la journalisation. Cela laisse votre fichier de base inchangé et réduit les erreurs.

## Vérification et diagnostics

Après la mise à niveau ou la migration, vous devez confirmer que l'application fonctionne comme prévu. Appuyez-vous à la fois sur les commandes Docker et sur des vérifications au niveau de l'application.

### Vérifier l'état des services

Exécutez :

```bash
docker compose ps
```

Tous les services doivent afficher "running" ou "running (healthy)" si des healthchecks sont définis. Exemple :

```
NAME                COMMAND                  SERVICE             STATUS              PORTS
myapp_web_1         "nginx -g 'daemon of..."   web                 running (healthy)   0.0.0.0:80->80/tcp
myapp_db_1          "docker-entrypoint.s..."   db                  running (healthy)   5432/tcp
```

### Consulter les journaux pour détecter les erreurs

```bash
docker compose logs --tail=100
```

Recherchez toute trace de pile, erreur de connexion ou avertissement de configuration. Si vous utilisez `-f` pour suivre les journaux, arrêtez avec Ctrl+C.

### Tester les points de terminaison HTTP

Si l'application sert du trafic web, utilisez `curl` pour vérifier une URL connue :

```bash
curl -I http://localhost
```

La sortie attendue inclut `HTTP/1.1 200 OK` ou une redirection. Si vous attendez un contenu de page spécifique, récupérez-le et recherchez une chaîne connue :

```bash
curl -s http://localhost | grep -i "welcome"
```

### Vérifier l'utilisation des ressources des conteneurs

Assurez-vous que les conteneurs ne consomment pas excessivement de CPU ou de mémoire :

```bash
docker stats --no-stream
```

Exemple de sortie :

```
CONTAINER ID   NAME          CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O   PIDS
abc123def456   myapp_web_1   0.50%     25MiB / 1GiB          2.44%     1.2kB / 0B        0B / 0B     5
```

Comparez avec les valeurs de référence d'avant la mise à niveau si vous les avez enregistrées.

### Vérifier les données persistantes

Pour les bases de données, exécutez une requête rapide pour vous assurer que les données sont intactes. Pour PostgreSQL à l'intérieur du conteneur :

```bash
docker compose exec db psql -U myuser -c "SELECT count(*) FROM mytable;"
```

La sortie attendue montre le nombre de lignes. Si vous avez migré les volumes, confirmez que le compte correspond à l'ancien hôte.

### Exécuter les healthchecks

Les healthchecks Docker fournissent un état automatique. S'ils sont définis dans votre fichier Compose, vous pouvez inspecter le dernier état de santé :

```bash
docker inspect --format='{{json .State.Health}}' myapp_web_1
```

La sortie inclut `"Status":"healthy"` et les entrées de journal récentes.

### Surveiller la connectivité réseau

Assurez-vous que les conteneurs peuvent communiquer entre eux. Par exemple, depuis le conteneur web, testez la connexion au nom d'hôte de la base de données :

```bash
docker compose exec web ping -c 2 db
```

Ou testez une connexion TCP avec `nc` si disponible :

```bash
docker compose exec web nc -zv db 5432
```

Attendu : `db (172.18.0.2:5432) open`.

### Valider avec des tests d'intégration

Si vous avez une suite de tests, exécutez un test de fumée contre le déploiement de production (sans écritures destructrices). Cela peut être aussi simple qu'un script qui interroge les points de terminaison clés et vérifie les réponses.

## Modes de défaillance et récupération

Même avec une planification minutieuse, des problèmes peuvent survenir. Voici les scénarios de défaillance courants lors d'une mise à niveau ou d'une migration Compose, et comment les résoudre.

### Le conteneur ne démarre pas après la mise à niveau

Causes possibles : syntaxe du fichier Compose incompatible, variables d'environnement manquantes, conflits de ports ou problèmes d'image.

Récupération :

- Vérifiez les journaux : `docker compose logs <service>`.
- Validez la configuration : `docker compose config`.
- Si le problème est clair (par exemple, une faute de frappe), corrigez le fichier Compose et relancez `docker compose up -d`.
- En cas de doute, revenez à la version précédente (voir le retour en arrière ci-dessous).

### L'application démarre mais se comporte de manière incorrecte

Cela peut être dû à des paramètres par défaut modifiés dans la nouvelle version de Compose ou à des différences d'environnement.

Récupération :

- Comparez la configuration résolue entre l'ancienne et la nouvelle : sortie de `docker compose config`.
- Consultez les journaux d'application pour détecter les erreurs.
- Envisagez de restaurer la version précédente et de re-tester.

### Corruption des données lors de la migration des volumes

Si vous avez utilisé la méthode du pipe tar et que le volume a été corrompu, l'application peut ne pas parvenir à lire les données.

Récupération :

- Arrêtez la pile sur le nouvel hôte : `docker compose down`.
- Recopiez le volume depuis l'ancien hôte (qui devrait être intact si vous l'avez conservé).
- Redémarrez et vérifiez.

### Problèmes de réseau après la migration

Si le trafic externe ne peut pas atteindre le nouvel hôte, vérifiez les règles de pare-feu, les groupes de sécurité et le DNS. Assurez-vous également que les ports sont publiés correctement dans Compose.

Récupération :

- Vérifiez avec `docker compose ps` quels ports sont mappés.
- Vérifiez le pare-feu de l'hôte : `sudo ufw status` ou `sudo iptables -L`.
- Revenez temporairement à l'ancien hôte si possible.

### Comment revenir en arrière sur une mise à niveau Compose

Si le binaire Compose lui-même pose problème, vous pouvez revenir à la version précédente. Pour les installations par plugin, vous pouvez installer une version spécifique. Pour les installations manuelles, remplacez le binaire par le précédent depuis la sauvegarde. Après le retour en arrière, redémarrez la pile.

### Comment revenir en arrière sur une migration

Si vous avez migré vers un nouvel hôte et que des problèmes surviennent, vous pouvez rebasculer le trafic vers l'ancien hôte s'il est toujours en cours d'exécution. Si l'ancien hôte a été mis hors service, vous devrez peut-être restaurer à partir des sauvegardes vers un nouveau serveur.

### Vérification de la récupération

Après tout retour en arrière ou correction, répétez les étapes de vérification pour confirmer que la pile est saine.

### Exemple construit : une mise à niveau échouée et sa récupération

Imaginez que vous ayez mis à niveau Compose de v2.23 à v2.24 et que votre `docker-compose.yml` utilisait une fonctionnalité obsolète supprimée en v2.24. Lorsque vous exécutez `docker compose up -d`, vous voyez une erreur :

```
Error: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion
```

En réalité, c'est un avertissement, pas une erreur, donc la pile peut quand même démarrer. Mais si vous voyez une erreur grave comme :

```
ERROR: The Compose file './docker-compose.yml' is invalid because:
services.web.ports contains an invalid type, it should be a string, or an array
```

Vous devrez corriger la définition des ports. Si vous ne pouvez pas corriger immédiatement, revenez au binaire Compose précédent et redémarrez.

## Pièges courants et comment les éviter

Au fil des années, certaines erreurs reviennent régulièrement. Les connaître à l'avance peut vous éviter un incident de production.

### Oublier de sauvegarder les volumes

De nombreux opérateurs sauvegardent le fichier Compose mais oublient les volumes persistants. Le résultat est une perte de données en cas de problème.

**Pourquoi cela arrive :** les volumes ne sont pas visibles dans le répertoire du projet ; ils vivent dans le stockage interne de Docker.

**Comment l'éviter :** listez toujours les volumes avec `docker volume ls` et incluez-les dans votre plan de sauvegarde. Automatisez les sauvegardes avec une tâche cron si possible.

### Ne pas tester en staging

Sauter l'étape de staging parce que « c'est une mise à niveau mineure » conduit souvent à des problèmes inattendus.

**Pourquoi cela arrive :** pression temporelle et excès de confiance.

**Comment l'éviter :** même un test rapide sur une machine virtuelle peut détecter des erreurs de configuration. Faites du staging une étape obligatoire dans votre processus de changement.

### Ignorer les avertissements de dépréciation

Les avertissements comme « l'attribut `version` est obsolète » sont faciles à ignorer, mais ils peuvent devenir des erreurs dans une version future.

**Pourquoi cela arrive :** les avertissements ne cassent pas le déploiement actuel, donc ils sont reportés.

**Comment l'éviter :** traitez les avertissements comme des actions à mener. Planifiez du temps pour les traiter après la mise à niveau.

### Ne pas avoir de plan de retour en arrière

Sans plan de retour en arrière, la récupération devient une devinette sous stress.

**Pourquoi cela arrive :** les gens supposent que la mise à niveau réussira.

**Comment l'éviter :** notez les étapes exactes pour revenir en arrière, y compris les commandes et les emplacements de fichiers, avant de commencer. Testez le retour en arrière en staging.

### Migrer les données avec la mauvaise méthode

Utiliser des pipes `tar` pour de grandes bases de données peut provoquer une corruption ou un temps d'arrêt prolongé.

**Pourquoi cela arrive :** la méthode tar est simple mais n'est pas conçue pour les bases de données en direct.

**Comment l'éviter :** pour les bases de données, utilisez des outils natifs comme `pg_dump` ou `mysqldump`. Pour les grands volumes de fichiers, envisagez `rsync` avec une fenêtre de maintenance.

## Liste de contrôle des opérations

Utilisez cette liste de contrôle avant, pendant et après toute mise à niveau ou migration Compose en production.

### Liste de contrôle avant le changement

- [ ] Inventaire complet : versions, services, volumes, variables d'environnement.
- [ ] Sauvegarde du répertoire du projet et des volumes effectuée et vérifiée.
- [ ] Environnement de staging ou de test prêt et correspondant à la production.
- [ ] Parcours de mise à niveau testé en staging sans problème.
- [ ] Plan de retour en arrière documenté et accessible.
- [ ] Fenêtre de maintenance planifiée si un temps d'arrêt est possible.
- [ ] Surveillance et alertes configurées pour détecter rapidement les défaillances.

### Liste de contrôle pendant le changement

- [ ] Exécutez les étapes de mise à niveau exactement comme testées en staging.
- [ ] Après chaque étape majeure, vérifiez la santé des services (par exemple, `docker compose ps`, healthchecks).
- [ ] En cas d'échec d'une étape, arrêtez-vous et évaluez ; ne forcez pas.
- [ ] Tenez un journal des commandes exécutées et de leurs sorties.

### Liste de contrôle après le changement

- [ ] Exécutez la vérification complète : journaux, points de terminaison, vérifications de base de données, utilisation des ressources.
- [ ] Comparez la nouvelle configuration résolue avec celle attendue.
- [ ] Surveillez pendant au moins 24 à 48 heures pour détecter les défaillances différées.
- [ ] Mettez à jour la documentation avec les nouveaux numéros de version et tout changement de configuration.
- [ ] Testez la procédure de retour en arrière à petite échelle pour vous assurer qu'elle fonctionne.
- [ ] Supprimez les anciennes sauvegardes uniquement après être satisfait de la stabilité.

### Exemple de tableau de vérification

| Vérification          | Commande                                    | Attendu           | Réussi/Échec |
|---------------------|--------------------------------------------|--------------------|-----------|
| État des services   | `docker compose ps`                        | Tous en cours d'exécution |           |
| Journaux sans erreurs | `docker compose logs --tail=100`           | Aucune trace de pile |           |
| Point de terminaison HTTP | `curl -I http://localhost`                 | 200 OK             |           |
| Requête base de données | `docker compose exec db psql ...`          | Nombre de lignes > 0 |           |
| Utilisation des ressources | `docker stats --no-stream`                 | Dans les limites   |           |
| Healthcheck          | `docker inspect ...`                       | healthy            |           |

Remplissez Réussi/Échec au fur et à mesure.

## Conclusion

La mise à niveau et la migration de Docker Compose en production ne doivent pas être risquées. En suivant un parcours structuré - inventaire, configuration sûre, vérification et planification de la récupération - vous pouvez minimiser les temps d'arrêt et être prêt à faire face aux problèmes. Les commandes pratiques et les tableaux de ce guide servent de modèle que vous pouvez adapter à votre propre pile.

Points clés à retenir :

- Inventoriez toujours votre environnement actuel, y compris les versions et les volumes.
- Apportez des modifications de manière incrémentale et testez-les d'abord dans un environnement de staging.
- Utilisez `docker compose config` et les healthchecks pour valider.
- Ayez un plan de retour en arrière clair avant de commencer.
- Gardez une liste de contrôle simple pour ne rien manquer.

Avec ces pratiques, votre prochaine mise à niveau ou migration Docker Compose sera plus fluide et plus prévisible.