Introduction
Mettre à niveau Docker Compose ne se limite pas à installer un nouveau binaire. Une mise à niveau sécurisée consiste à passer d’un problème observé à un résultat vérifié, sans perdre de données, sans casser les services dépendants et sans faire de suppositions sur le comportement en cours d’exécution. Ce guide fournit des étapes pratiques pour la mise à niveau, la migration, la restauration, le changement de version et la validation de Docker Compose, avec des commandes concrètes et les sorties attendues.
Cet article s’adresse aux développeurs, aux consultants DevOps et aux équipes techniques de startups qui gèrent des applications conteneurisées en développement, en préproduction ou en production. Il se concentre sur le flux opérationnel : vérifier les prérequis, capturer l’état actuel, appliquer un changement minimal, vérifier le résultat et savoir comment récupérer en cas de problème.
L’objectif est la sécurité opérationnelle. Observez avant de modifier, limitez le rayon d’impact, utilisez des variables d’environnement plutôt que des secrets dans les fichiers de configuration, vérifiez chaque étape et documentez les commandes de récupération avant d’en avoir besoin. Chaque section comprend un exemple pratique pour que vous puissiez suivre sur vos propres systèmes.
Inventaire des versions et de l’environnement
Avant de toucher à un service en cours d’exécution, vous devez disposer d’un inventaire clair de la version de Docker Compose installée, de l’état actif du projet et de l’environnement de déploiement. Cet inventaire vous aide à choisir la bonne voie de mise à niveau et à anticiper les problèmes de compatibilité.
Vérifier la version actuelle de Docker Compose
Exécutez la commande suivante pour voir la version actuellement installée :
docker compose version
Exemple de sortie :
Docker Compose version v2.24.5
Si vous utilisez l’ancien binaire autonome docker-compose (v1), vérifiez avec :
docker-compose version
Exemple de sortie :
docker-compose version 1.29.2, build 5becea4c
Savoir si vous êtes sur la v1 ou la v2 est important car la syntaxe des commandes diffère. Docker Compose v2 est un plugin invoqué sous la forme docker compose, tandis que la v1 est un binaire distinct. La plupart des systèmes modernes utilisent la v2, mais les anciens serveurs peuvent encore avoir la v1. Le processus de mise à niveau de la v1 vers la v2 implique l’installation du plugin et éventuellement l’ajustement des scripts qui appellent docker-compose.
Inspecter l’état du projet en cours d’exécution
Listez les conteneurs actuels et leur statut :
docker compose ps
Exemple de sortie :
NAME COMMAND SERVICE STATUS PORTS
web-1 "docker-entrypoint.s…" web running 0.0.0.0:8080->80/tcp
db-1 "docker-entrypoint.s…" db running 5432/tcp
Cela montre les noms des services, les noms des conteneurs et les mappages de ports. Comparez avec votre docker-compose.yml pour vous assurer que l’état en cours correspond à la configuration prévue.
Consultez les journaux récents pour détecter tout problème en cours :
docker compose logs --tail 50 web
Recherchez les messages d’erreur ou les avertissements qui pourraient affecter la mise à niveau.
Identifier les volumes et le stockage des données
La sécurité des données est essentielle lors d’une mise à niveau. Déterminez où sont stockées les données de votre application en inspectant les volumes :
docker volume ls
Exemple de sortie :
DRIVER VOLUME NAME
local myapp_db_data
local myapp_uploads
Inspectez ensuite un volume pour voir son point de montage et ses étiquettes :
docker volume inspect myapp_db_data
Exemple de sortie (partielle) :
[
{
"CreatedAt": "2024-03-01T12:00:00Z",
"Driver": "local",
"Labels": {
"com.docker.compose.project": "myapp",
"com.docker.compose.volume": "db_data"
},
"Mountpoint": "/var/lib/docker/volumes/myapp_db_data/_data",
"Name": "myapp_db_data",
"Options": null,
"Scope": "local"
}
]
Si votre docker-compose.yml utilise un montage de type bind, le chemin apparaîtra sous Mounts dans docker inspect pour le conteneur :
docker inspect db-1 --format '{{ json .Mounts }}'
Exemple de sortie :
[{"Type":"bind","Source":"/home/user/myapp/data","Destination":"/var/lib/postgresql/data","Mode":"rw","RW":true,"Propagation":"rprivate"}]
Notez tous les volumes et montages bind. Lors d’une mise à niveau, les conteneurs peuvent être recréés et si les données sont stockées dans des couches éphémères de conteneur, elles seront perdues.
Vérifier la persistance des données avec un test de redémarrage
Avant toute mise à niveau, effectuez un test de redémarrage contrôlé pour confirmer que les données persistent lors de la recréation du conteneur. Arrêtez et redémarrez un service :
docker compose stop db
docker compose start db
Vérifiez ensuite que l’application peut toujours lire ses données. Par exemple, s’il s’agit d’une base de données PostgreSQL, exécutez :
docker compose exec db psql -U myuser -c "SELECT count(*) FROM mytable;"
Sortie attendue :
count
-------
123
(1 row)
Si le compte est nul ou si la table est absente, les données étaient probablement stockées dans la couche du conteneur et vous devez corriger la configuration du volume avant de continuer.
Parcours de configuration sécurisé
Un parcours de configuration sécurisé signifie modifier votre docker-compose.yml en comprenant clairement l’effet de chaque changement et en ayant un plan de restauration. Évitez d’apporter plusieurs modifications sans rapport à la fois.
Sauvegarder la configuration actuelle
Faites une copie horodatée de votre docker-compose.yml actuel et de tout fichier .env associé :
cp docker-compose.yml docker-compose.yml.bak.$(date +%Y%m%d%H%M%S)
Exemple :
docker-compose.yml.bak.20250315120000
Sauvegardez également tout fichier .env :
cp .env .env.bak.$(date +%Y%m%d%H%M%S)
Cela vous permet de restaurer la configuration précédente rapidement si nécessaire.
Mettre à jour la clé de version du fichier Compose (le cas échéant)
Pour les anciens fichiers Compose, la clé de premier niveau version était utilisée pour spécifier la version du schéma. Dans Docker Compose v2, cette clé est obsolète mais toujours acceptée pour la compatibilité ascendante. Si vous migrez de la v1 vers la v2, vous pouvez supprimer la clé version ou la laisser ; elle sera ignorée.
Exemple d’ancien fichier :
version: '3.8'
services:
web:
image: nginx:1.25
ports:
- "8080:80"
Vous pouvez supprimer en toute sécurité la ligne version. Le nouveau fichier commencerait directement par services:.
Valider la configuration avant de l’appliquer
Utilisez la commande config pour analyser et valider votre fichier Compose :
docker compose config
Cela affiche la configuration normalisée. S’il y a des erreurs de syntaxe, elles seront signalées. Exemple de sortie réussie (tronquée) :
name: myapp
services:
web:
image: nginx:1.25
ports:
- mode: ingress
target: 80
published: "8080"
protocol: tcp
networks:
default:
name: myapp_default
Vérifiez s’il y a des avertissements ou des changements inattendus dans la sortie. Exécutez également :
docker compose config --quiet
Si cette commande se termine avec le code 0 et sans sortie, la configuration est valide.
Gérer les variables d’environnement en toute sécurité
Ne codez jamais en dur des secrets dans docker-compose.yml. Utilisez un fichier .env pour les variables d’environnement. Par exemple, dans votre fichier Compose :
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
Créez un fichier .env avec la valeur réelle (mais ne validez jamais ce fichier dans le contrôle de version) :
DB_PASSWORD=change_me_strong_password
Validez que la variable est substituée correctement :
docker compose config | grep POSTGRES_PASSWORD
La sortie attendue montre la valeur réelle. Pour éviter d’exposer les secrets dans les journaux, envisagez d’utiliser les secrets Docker en production (Swarm) ou une gestion de secrets externe.
Appliquer le changement avec une mise à jour progressive ou une recréation
Pour un simple changement comme la mise à jour d’une balise d’image, vous pouvez exécuter :
docker compose up -d --no-deps web
Cela recrée uniquement le service web sans toucher aux dépendances. Si vous devez forcer la recréation :
docker compose up -d --force-recreate web
Observez la sortie :
[+] Running 1/1
✔ Container myapp-web-1 Recreated
Vérifiez ensuite que le service est sain :
docker compose ps
Exemple de migration de la v1 vers la v2
Si vous utilisez l’ancien binaire docker-compose, migrez vers le plugin v2. Tout d’abord, vérifiez si la v2 est installée :
docker compose version
Si elle n’est pas installée, suivez le guide d’installation officiel de Docker pour votre système d’exploitation. Sur Ubuntu, installez le paquet docker-compose-plugin :
sudo apt-get update
sudo apt-get install docker-compose-plugin
Après l’installation, mettez à jour tous les scripts qui appellent docker-compose pour utiliser docker compose (espace au lieu du trait d’union). Testez avec votre projet :
cd /path/to/project
docker compose up -d
Vérification et diagnostic
Après avoir appliqué un changement de configuration ou une mise à niveau, vérifiez que l’application fonctionne correctement. Cela implique de vérifier la santé des services, les journaux et la connectivité.
Vérifier l’état et la santé des services
Utilisez docker compose ps pour voir l’état :
docker compose ps
Exemple :
NAME COMMAND SERVICE STATUS PORTS
web-1 "docker-entrypoint.s…" web running (healthy) 0.0.0.0:8080->80/tcp
db-1 "docker-entrypoint.s…" db running (healthy) 5432/tcp
L’indicateur (healthy) apparaît si le conteneur a une vérification de santé définie. Si vos services n’ont pas de vérifications de santé, ajoutez-les à votre fichier Compose pour une meilleure observabilité. Exemple de vérification de santé pour un service web :
services:
web:
image: nginx:1.25
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/"]
interval: 30s
timeout: 10s
retries: 3
Après l’ajout, recréez le service :
docker compose up -d web
Vérifiez à nouveau.
Examiner les journaux pour détecter les erreurs
Affichez les journaux de services spécifiques :
docker compose logs --tail 100 web
Recherchez les erreurs de démarrage, les échecs de connexion ou les erreurs de configuration. Par exemple, une erreur de connexion à la base de données peut apparaître comme :
web-1 | [error] 23#23: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "http://172.18.0.2:5432/"
Cela indique que le service web ne peut pas atteindre la base de données, probablement en raison d’un changement de réseau ou de nom de service.
Tester la connectivité et les points de terminaison des services
Pour les applications web, utilisez curl depuis l’hôte ou à l’intérieur d’un autre conteneur. Depuis l’hôte :
curl -I http://localhost:8080
Sortie attendue :
HTTP/1.1 200 OK
Server: nginx/1.25.3
Date: Sat, 15 Mar 2025 12:00:00 GMT
Content-Type: text/html
Si vous devez tester depuis le réseau, exécutez un conteneur temporaire :
docker run --rm --network myapp_default curlimages/curl curl -s http://web:80
Remplacez myapp_default par le nom du réseau de votre projet (vérifiez avec docker network ls).
Valider la configuration par rapport à l’état en cours d’exécution
Comparez la configuration actuelle avec l’état déployé :
docker compose config --services
Cela liste tous les services définis. Comparez ensuite avec docker compose ps --services pour voir lesquels sont en cours d’exécution. Toute divergence peut indiquer un problème.
Vérifier l’utilisation des ressources et les performances
Utilisez docker stats pour surveiller la consommation des ressources :
docker stats --no-stream
Exemple de sortie (partielle) :
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
abc123def456 web-1 0.50% 25.5MiB / 1.95GiB 1.28% 1.2kB / 0B 0B / 0B 3
def456abc123 db-1 2.10% 102.4MiB / 1.95GiB 5.12% 850kB / 1.1MB 9.8MB / 12MB 27
Une utilisation anormalement élevée du processeur ou de la mémoire peut indiquer un service mal configuré après la mise à niveau.
Modes de défaillance et récupération
Chaque mise à niveau doit être planifiée en tenant compte des défaillances. Voici les modes de défaillance courants et les étapes de récupération spécifiques.
Erreur de syntaxe de configuration
Si docker compose up échoue avec une erreur YAML, revenez à la configuration de sauvegarde.
Exemple d’erreur :
yaml: line 5: could not find expected ':'
Récupération : restaurez le fichier de sauvegarde :
cp docker-compose.yml.bak.YYYYMMDDHHMMSS docker-compose.yml
Validez à nouveau :
docker compose config --quiet
Version d’image incompatible
Si la nouvelle version de l’image ne démarre pas en raison de dépendances manquantes ou d’un point d’entrée modifié, vérifiez les journaux puis annulez la balise de l’image.
Exemple : vous avez changé image: myapp:2.0 en myapp:3.0 et le conteneur se termine avec une erreur. Les journaux montrent :
web-1 | Error: Cannot find module 'express'
Récupération : remettez la balise d’image à la version précédente dans docker-compose.yml, puis exécutez :
docker compose up -d --force-recreate web
Défaillance de dépendance de service
Si un service dépendant ne démarre pas parce qu’un autre service n’est pas sain, vérifiez les vérifications de santé et l’ordre de démarrage. Compose v2 prend en charge depends_on avec conditions :
services:
web:
depends_on:
db:
condition: service_healthy
Assurez-vous que le service db passe sa vérification de santé. Sinon, inspectez les journaux de db et corrigez le problème sous-jacent.
Perte de volume ou de données
Si après une mise à niveau l’application signale des données manquantes, vérifiez les montages de volume. Utilisez docker inspect pour voir les points de montage :
docker inspect db-1 --format '{{ json .Mounts }}'
Si le volume est manquant ou pointe vers un emplacement différent, restaurez les données à partir des sauvegardes. Prenez toujours des sauvegardes de volume avant des changements majeurs. Exemple de sauvegarde pour un volume PostgreSQL :
docker run --rm -v myapp_db_data:/data -v $(pwd):/backup alpine tar czf /backup/db_data_backup.tar.gz -C /data .
Restauration :
docker run --rm -v myapp_db_data:/data -v $(pwd):/backup alpine sh -c "cd /data && tar xzf /backup/db_data_backup.tar.gz"
Procédure de restauration
Une procédure de restauration générale :
- Arrêtez les services affectés :
docker compose stop web db
- Restaurez la configuration précédente à partir de la sauvegarde :
cp docker-compose.yml.bak.TIMESTAMP docker-compose.yml
- Recréez les services avec l’ancienne configuration :
docker compose up -d --force-recreate
- Vérifiez que l’application est saine.
Liste de contrôle opérationnelle
Utilisez cette liste de contrôle pour garantir une mise à niveau ou une migration Docker Compose sécurisée. Remplissez les valeurs spécifiques à votre environnement.
| Étape | Commande / Action | Résultat attendu | Notes |
|---|---|---|---|
| 1. Enregistrer la version actuelle | docker compose version | La sortie affiche la version (par ex., v2.24.5) | Notez v1 vs v2 |
| 2. Capturer l’état en cours | docker compose ps --services | Liste des services en cours d’exécution | Comparer à la config |
| 3. Sauvegarder la config et l’env | cp docker-compose.yml docker-compose.yml.bak.$(date +%Y%m%d%H%M%S) | Fichier créé | Sauvegarder aussi .env |
| 4. Sauvegarder les volumes (le cas échéant) | docker run --rm -v VOLUME:/data -v $(pwd):/backup alpine tar czf /backup/volume_backup.tar.gz -C /data . | Archive tar créée | Remplacer VOLUME par le nom réel |
| 5. Valider la config | docker compose config --quiet | Code de sortie 0, aucune sortie | Corriger les erreurs |
| 6. Appliquer le changement | docker compose up -d ou service spécifique | Services recréés | Utiliser --no-deps pour limiter |
| 7. Vérifier l’état | docker compose ps | Tous les services en cours d’exécution, sains si vérifications définies | Rechercher les redémarrages |
| 8. Vérifier les journaux | docker compose logs --tail 50 SERVICE | Aucune erreur fatale | Enquêter sur les avertissements |
| 9. Tester la fonctionnalité | curl -I http://localhost:PORT ou commande appropriée | HTTP 200 ou réponse attendue | Vérifier les points de terminaison critiques |
| 10. Surveiller les ressources | docker stats --no-stream | CPU et mémoire dans la plage normale | Surveiller les fuites |
| 11. Confirmer la persistance des données | Test de redémarrage : docker compose stop puis start | Données intactes | Si perdues, corriger les volumes |
| 12. Documenter le plan de restauration | Écrire les commandes de restauration | Étapes claires sauvegardées | Tester la restauration en préproduction si possible |
Exemple de liste de contrôle remplie pour un projet exemple
Supposons un projet nommé myapp avec les services web et db, utilisant un volume nommé myapp_db_data, et mettant à niveau la balise d’image de web:1.0 à web:2.0.
- Version actuelle :
docker compose versionrenvoieDocker Compose version v2.24.5. - Services en cours :
docker compose ps --servicesrenvoiewebetdb. - Sauvegarde de la configuration :
cp docker-compose.yml docker-compose.yml.bak.20250315120000. - Sauvegarde du volume :
docker run --rm -v myapp_db_data:/data -v $(pwd):/backup alpine tar czf /backup/myapp_db_data_backup.tar.gz -C /data . - Valider la configuration :
docker compose config --quietne renvoie aucune erreur. - Appliquer le changement : modifier la balise d’image en
web:2.0, puisdocker compose up -d web. - Vérifier l’état :
docker compose psmontreweben cours et sain. - Vérifier les journaux :
docker compose logs --tail 50 webmontre le succès du démarrage. - Tester la fonctionnalité :
curl -I http://localhost:8080renvoieHTTP/1.1 200 OK. - Surveiller les ressources :
docker stats --no-streammontre web utilisant 30 Mo de RAM, normal. - Confirmer la persistance des données :
docker compose stoppuisdocker compose start, puisdocker compose exec db psql -U myuser -c "SELECT count(*) FROM mytable;"renvoie 123. - Documenter la restauration :
cp docker-compose.yml.bak.20250315120000 docker-compose.yml && docker compose up -d --force-recreate.
Conclusion
La mise à niveau et la migration de Docker Compose sont des opérations courantes mais risquées. Une approche systématique réduit les temps d’arrêt et les pertes de données. En inventoriant votre environnement, en sauvegardant la configuration et les données, en validant les changements et en vérifiant la fonctionnalité après chaque étape, vous gardez le contrôle sur le processus.
N’oubliez pas de définir la portée de chaque recommandation en fonction de la version, d’observer avant de modifier et d’avoir toujours un plan de restauration. Commencez par une vérification à faible risque sur un environnement de préproduction ou un service non critique, enregistrez l’état actuel, appliquez le changement et comparez le résultat au signal attendu.
Avec ces pratiques, les mises à niveau de Docker Compose deviennent prévisibles et sûres, même en production. Utilisez la liste de contrôle comme un document vivant qui évolue avec votre infrastructure et l’expérience de votre équipe.
Pour approfondir, explorez la documentation officielle de Docker sur la référence du fichier Compose, la mise en réseau et les volumes, et envisagez d’automatiser ces étapes avec des pipelines CI/CD dans votre flux de travail de développement.