## Introduction

Les mises à niveau et migrations de Docker Desktop deviennent risquées lorsque des changements sont appliqués sans connaître la version actuelle, la configuration et l'organisation des données. Un développeur ou ingénieur DevOps peut passer d'un conteneur défaillant à une mise à niveau réussie et vérifiée en suivant une séquence d'observations, de changements ciblés et de contrôles explicites. Ce guide s'adresse aux développeurs, consultants DevOps et équipes techniques de startups qui veulent éviter les échecs courants et récupérer rapidement en cas de problème.

L'article se concentre sur les étapes pratiques de la mise à niveau de Docker Desktop, de la migration d'applications conteneurisées vers une nouvelle version ou machine, du retour en arrière en cas d'échec et de la validation du résultat. Chaque section fournit des commandes avec les sorties attendues, les signaux d'échec et les décisions de récupération. Le principe sous-jacent est la sécurité opérationnelle : observer avant de changer, limiter le rayon d'impact, utiliser des variables d'environnement plutôt que des secrets, vérifier les résultats et documenter les chemins de récupération à l'avance.

## Inventaire des versions et de l'environnement

Avant toute mise à niveau ou migration, documentez l'état actuel de Docker Desktop et des conteneurs qu'il gère. Cet inventaire vous indique ce qui existe, ce qui dépend de quoi et ce qui pourrait casser.

Commencez par vérifier la version installée de Docker Desktop et la version du moteur. Les versions client et serveur doivent être compatibles, surtout lorsqu'une mise à niveau de Docker Desktop modifie le moteur intégré. Sur macOS, Windows ou Linux, exécutez :

```bash
docker version
```

La sortie attendue comprend une section Client et une section Serveur, chacune avec un champ Version comme `24.0.2`. Si la section Serveur n'apparaît pas, le démon Docker n'est pas en cours d'exécution ou le CLI ne peut pas l'atteindre. Notez les deux versions car certaines fonctionnalités, comme BuildKit ou le magasin d'images containerd, dépendent de la version du moteur.

Ensuite, listez tous les conteneurs en cours d'exécution et arrêtés pour savoir ce qui est actuellement déployé :

```bash
docker ps -a --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"
```

Le tableau inclut les noms des conteneurs, les images, l'état actuel et les mappages de ports. Notez tout conteneur qui s'exécute depuis longtemps ou qui utilise un réseau ou un volume spécifique.

Inspectez un conteneur lorsque vous avez besoin d'une configuration d'exécution détaillée, en particulier les montages et les variables d'environnement :

```bash
docker inspect <nom_du_conteneur> --format '{{json .Mounts}}'
```

Cela renvoie un JSON comme :

```json
[{"Type":"volume","Name":"app_data","Source":"/var/lib/docker/volumes/app_data/_data","Destination":"/var/lib/app"}]
```

Confirmez où les données de l'application sont stockées avant de modifier les conteneurs. Un volume nommé comme `app_data:/var/lib/app` est géré par Docker et persiste lors des reconstructions de conteneurs. Un montage bind comme `./data:/var/lib/app` mappe directement un répertoire de l'hôte, ce qui est utile pour le développement local mais peut causer des problèmes de permissions et de portabilité si le même chemin n'existe pas sur une autre machine.

Pour les projets Compose, utilisez :

```bash
docker compose ps
```

Cela liste les services, leur état et les ports publiés. Pour les journaux en direct d'un service spécifique :

```bash
docker compose logs -f <nom_du_service>
```

Et pour exécuter un shell dans un service en cours sans modifier l'image :

```bash
docker compose exec <nom_du_service> sh
```

Un test essentiel pour la persistance des données est le test de redémarrage. Arrêtez un conteneur, recréez-le et confirmez que l'application voit toujours les fichiers attendus. Par exemple :

```bash
docker stop conteneur_app
docker start conteneur_app
docker exec conteneur_app ls /var/lib/app
```

Si le répertoire est vide ou manquant après le redémarrage, le service écrivait probablement dans le système de fichiers du conteneur plutôt que dans un volume ou un montage bind. Corrigez cela avant la mise à niveau pour éviter la perte de données.

## Chemin de configuration sûr

Un chemin de configuration sûr sépare l'inspection en lecture seule des changements destructeurs. Avant de modifier un paramètre, capturez les valeurs actuelles et les horodatages, protégez les secrets et assurez-vous de pouvoir revenir en arrière.

Tout d'abord, exportez les paramètres actuels de Docker Desktop. Docker Desktop stocke les paramètres dans un fichier JSON, généralement situé dans le répertoire personnel de l'utilisateur. Sur macOS et Linux, le chemin est souvent `~/.docker/daemon.json` pour la configuration du démon et `~/Library/Group Containers/group.com.docker/settings-store.json` ou `~/.docker/settings.json` pour les paramètres de l'application, selon la version. Sur Windows, utilisez `%USERPROFILE%\.docker\daemon.json` et l'interface des paramètres de Docker Desktop. Pour afficher la configuration du démon sans la modifier :

```bash
cat ~/.docker/daemon.json
```

Créez une copie de sauvegarde avec un horodatage :

```bash
cp ~/.docker/daemon.json ~/.docker/daemon.json.$(date +%Y%m%d)
```

Cela garantit que vous pouvez restaurer la configuration précédente si une mise à niveau modifie le fichier ou introduit des options incompatibles.

Lorsque vous modifiez les paramètres de Docker Desktop, modifiez un élément à la fois de manière ciblée. Par exemple, si vous devez augmenter la limite de mémoire pour la VM Docker, ouvrez les paramètres de Docker Desktop, accédez à Ressources et ajustez le curseur Mémoire. Enregistrez le changement, puis vérifiez qu'il a pris effet :

```bash
docker info --format '{{.MemTotal}}'
```

La sortie est en octets. Pour convertir en Gio, divisez par 1024 trois fois. Si vous définissez 8 Gio (8 589 934 592 octets), la commande doit renvoyer une valeur proche. Si la valeur est inchangée, redémarrez Docker Desktop et vérifiez à nouveau.

Protégez les secrets lorsque vous configurez des registres ou des proxys. Ne mettez jamais de mots de passe en clair dans `daemon.json`. Utilisez plutôt l'assistant d'identification de Docker Desktop ou un gestionnaire de secrets. Par exemple, lors de l'ajout d'un registre privé, utilisez `docker login` pour stocker les identifiants de manière sécurisée plutôt que de les intégrer dans un fichier de configuration :

```bash
docker login registre.exemple.com
```

Après la connexion, les identifiants sont stockés dans le trousseau du système d'exploitation ou un magasin d'identifiants, pas dans la configuration du démon.

Pour les équipes, standardisez la configuration via des fichiers sous contrôle de version. Conservez une copie de `daemon.json` et des fichiers de surcharge Docker Compose dans un dépôt Git, mais excluez tout fichier susceptible de contenir des secrets. Utilisez un `.gitignore` avec des motifs comme `*.secret`, `.env` et `daemon.json.local`.

Un changement sûr inclut également un plan de retour en arrière. Pour Docker Desktop, cela signifie généralement télécharger l'installateur précédent depuis l'archive des versions ou utiliser un gestionnaire de paquets prenant en charge la rétrogradation. Sur macOS avec Homebrew :

```bash
brew install --cask docker@4.27.2
```

Ajustez la version à celle que vous utilisiez avant la mise à niveau. Sous Windows, conservez l'exécutable de l'installateur précédent dans un emplacement connu.

## Vérification et diagnostics

Après tout changement, vérifiez que le système se comporte comme prévu. La vérification doit être scriptée lorsque possible et inclure des contrôles au niveau de Docker et au niveau de l'application.

Commencez par les opérations Docker de base :

```bash
docker run --rm hello-world
```

La sortie attendue inclut un message indiquant que l'installation Docker fonctionne. Si cela échoue, le démon peut ne pas être en cours d'exécution ou le réseau peut être bloqué.

Vérifiez que tous les conteneurs précédemment en cours d'exécution le sont toujours :

```bash
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
```

Comparez la sortie avec votre inventaire d'avant la mise à niveau. Tout conteneur manquant ou mappage de port modifié est un signe d'avertissement.

Pour un conteneur spécifique, vérifiez son état de santé s'il est défini :

```bash
docker inspect <nom_du_conteneur> --format '{{.State.Health.Status}}'
```

Si le conteneur a un healthcheck, la sortie doit être `healthy` après une période de démarrage. Si elle est `unhealthy` ou `starting`, investiguez avec les journaux :

```bash
docker logs <nom_du_conteneur> --tail 100
```

Recherchez les messages d'erreur liés à des variables d'environnement manquantes, des problèmes de permission sur les montages ou des conflits de ports.

Pour les applications basées sur Compose, validez la configuration avant d'appliquer les changements :

```bash
docker compose config
```

Cela analyse le fichier Compose et imprime la configuration fusionnée. Cela détecte les erreurs de syntaxe et résout l'interpolation des variables d'environnement. Si des variables sont manquantes, cela affiche une erreur comme `La variable VAR_NAME n'est pas définie. Utilisation d'une chaîne vide par défaut.`

Ensuite, testez avec un essai à sec si la version de Compose le prend en charge, ou recréez les services avec le drapeau `--no-deps` pour limiter l'impact :

```bash
docker compose up -d --no-deps <nom_du_service>
```

Cela recrée uniquement le service spécifié et laisse ses dépendances en cours d'exécution. Surveillez le démarrage du service avec `docker compose logs -f <nom_du_service>`.

Commandes de diagnostic pour les problèmes de réseau et de stockage :

- Vérifiez les liaisons de ports : `docker port <nom_du_conteneur>` pour voir les mappages réels hôte-conteneur.
- Inspectez la connectivité réseau : `docker exec <nom_du_conteneur> ping -c 4 <autre_nom_de_conteneur>` si ping est disponible dans l'image.
- Examinez l'utilisation des volumes : `docker system df` pour voir l'utilisation du disque par les images, conteneurs et volumes. La sortie montre l'espace récupérable et aide à identifier si un volume croît de manière inattendue.

Si un conteneur ne peut pas se connecter à une base de données, testez avec `docker exec <nom_du_conteneur> nc -zv <hôte_bd> <port_bd>` si netcat est installé. Remplacez `nc` par `curl` pour les vérifications HTTP.

## Modes d'échec et récupération

Les mises à niveau et migrations peuvent échouer de manière prévisible. Reconnaissez les symptômes et ayez un chemin de récupération pour chacun.

**1. Docker Desktop ne démarre pas après la mise à niveau.**

Symptôme : L'icône de Docker Desktop tourne ou affiche une erreur comme « Docker Desktop est incapable de démarrer ».

Pourquoi : La nouvelle version peut avoir des paramètres incompatibles dans `daemon.json`, une VM corrompue ou un conflit avec d'anciens fichiers.

Récupération :
- Restaurez le `daemon.json` précédent depuis la sauvegarde : `cp ~/.docker/daemon.json.20250815 ~/.docker/daemon.json`.
- Réinitialisez Docker Desktop aux paramètres d'usine via le menu de dépannage (cela supprime tous les conteneurs et volumes, ne le faites que si les données sont sauvegardées ou non critiques).
- Réinstallez la version précédente en utilisant l'installateur que vous avez conservé.
- Consultez les journaux à `~/Library/Containers/com.docker.docker/Data/log/vm/dockerd.log` sur macOS, ou `%LOCALAPPDATA%\Docker\log\vm\dockerd.log` sur Windows.

**2. Les conteneurs ne peuvent pas accéder aux volumes montés après migration vers une nouvelle machine.**

Symptôme : Les applications échouent avec « permission refusée » ou « fichier introuvable » lors de la lecture depuis un montage bind.

Pourquoi : Le répertoire de l'hôte n'existe pas sur la nouvelle machine, ou la propriété et les permissions diffèrent.

Récupération :
- Vérifiez que le chemin de l'hôte existe : `ls -ld ./data`.
- Corrigez la propriété si nécessaire : `sudo chown -R $(id -u):$(id -g) ./data` sur Linux. Sur macOS et Windows, les permissions des montages bind sont gérées par les paramètres de partage de fichiers de Docker Desktop ; assurez-vous que le répertoire est partagé.
- Préférez les volumes nommés pour les données portables : `docker volume create app_data` et utilisez `app_data:/var/lib/app` dans la définition du conteneur. Ensuite, migrez les données en les copiant depuis l'ancien hôte : `docker run --rm -v app_data:/data -v $(pwd):/backup alpine tar czf /backup/app_data.tar.gz -C /data .` et restaurez sur la nouvelle machine.

**3. Le tirage d'image échoue lors de la mise à niveau.**

Symptôme : `docker pull` renvoie des erreurs d'authentification ou de manifeste inconnu.

Pourquoi : Les identifiants du registre ne sont pas disponibles sur le nouvel environnement, ou l'étiquette de l'image n'a pas été migrée.

Récupération :
- Exécutez `docker login registre.exemple.com` et saisissez à nouveau les identifiants.
- Utilisez `docker images` pour voir les images locales disponibles, et `docker tag <ancienne_image> <nouveau_registre>/<image>:<étiquette>` si vous devez pousser vers un nouveau registre.
- Pour les registres privés, vérifiez si l'assistant d'identification de Docker Desktop est correctement configuré. Réinitialisez via Docker Desktop Paramètres > Docker Engine > « Appliquer et redémarrer » après avoir ajouté `"credsStore": "desktop"`.

**4. Les ports réseau changent après la migration.**

Symptôme : Les services sont inaccessibles au port hôte attendu.

Pourquoi : Le nouvel hôte peut avoir des disponibilités de ports différentes, ou le fichier de surcharge Compose n'a pas été appliqué.

Récupération :
- Vérifiez `docker ps` pour les mappages de ports et comparez avec la sortie de l'ancien environnement.
- Utilisez `docker port <nom_du_conteneur>` pour voir les mappages réels.
- Mettez à jour les fichiers Compose pour utiliser des variables d'environnement pour les ports : `ports: - "${APP_PORT:-8080}:80"` et définissez `APP_PORT` dans un fichier `.env`. Cela rend les changements de ports explicites.

**5. Perte de données due à des volumes anonymes ou à des écritures dans le système de fichiers du conteneur.**

Symptôme : Après avoir recréé un conteneur, l'application démarre à neuf sans données précédentes.

Pourquoi : Le conteneur utilisait un volume anonyme ou écrivait dans sa couche inscriptible au lieu d'un volume nommé. Les volumes anonymes sont supprimés lorsque le conteneur est supprimé (sauf si `--volumes-from` est utilisé).

Récupération :
- Inspectez les volumes du conteneur : `docker inspect <nom_du_conteneur> --format '{{json .Mounts}}'` avant la suppression.
- Si un volume anonyme existe, sauvegardez-le : `docker run --rm -v <nom_du_volume>:/data -v $(pwd):/backup alpine tar czf /backup/volume.tar.gz -C /data .`.
- Recréez le conteneur avec un volume nommé explicite et restaurez les données dedans.
- Empêchez la récurrence en spécifiant toujours les volumes dans les fichiers Compose ou les commandes `docker run -v`.

## Liste de contrôle opérationnelle

Utilisez cette liste de contrôle avant, pendant et après une mise à niveau ou migration de Docker Desktop. Attribuez un responsable unique à chaque élément et revoyez la liste à chaque migration ou trimestriellement, selon la première échéance.

### Liste de contrôle pré-mise à niveau (Responsable : Ingénieur DevOps, p. ex. Priya Shah)

- [ ] Enregistrez la version actuelle de Docker Desktop : sortie de `docker version` enregistrée dans un fichier.
- [ ] Exportez les paramètres actuels : `cp ~/.docker/daemon.json ~/.docker/daemon.json.premigration`.
- [ ] Listez tous les conteneurs et leurs montages : `docker ps -a --format "table {{.Names}}\t{{.Mounts}}"` et enregistrez la sortie.
- [ ] Sauvegardez les données critiques des volumes nommés et des montages bind. Pour chaque volume, exécutez un conteneur de sauvegarde qui compresse les données vers un emplacement sûr.
- [ ] Confirmez que l'installateur de retour en arrière est disponible : version précédente de Docker Desktop téléchargée et stockée localement.
- [ ] Informez les membres de l'équipe de la fenêtre de maintenance et de la durée prévue.

### Liste de contrôle pendant la mise à niveau (Responsable : Ingénieur DevOps)

- [ ] Installez la nouvelle version de Docker Desktop en suivant les instructions officielles.
- [ ] Démarrez Docker Desktop et attendez que le moteur soit prêt : `docker info` renvoie sans erreur.
- [ ] Vérifiez que tous les conteneurs attendus sont en cours d'exécution : la sortie de `docker ps` correspond à l'inventaire.
- [ ] Vérifiez la persistance des volumes et montages bind : redémarrez un conteneur de test et vérifiez les données.
- [ ] Exécutez des tests de fumée de l'application : p. ex. `curl http://localhost:8080/health` renvoie HTTP 200.

### Liste de contrôle post-mise à niveau (Responsable : Propriétaire de l'application, p. ex. Marcus Chen, Responsable Ingénierie)

- [ ] Mettez à jour la documentation avec le nouveau numéro de version et tout paramètre modifié.
- [ ] Exécutez la suite complète de tests de régression pour l'application.
- [ ] Surveillez les journaux pendant 24 à 48 heures : `docker logs <nom_du_conteneur> --since 24h | grep -i error`.
- [ ] Vérifiez que les sauvegardes fonctionnent toujours avec la nouvelle version de Docker.
- [ ] Créez un ticket pour tout avertissement de dépréciation vu dans les journaux.

### Liste de contrôle post-migration (Responsable : Ingénieur DevOps)

- [ ] Confirmez que tous les volumes de données ont été transférés et sont lisibles : `docker run --rm -v app_data:/data alpine ls /data` montre les fichiers attendus.
- [ ] Vérifiez la connectivité réseau entre tous les services : utilisez `docker exec` avec ping ou nc selon le cas.
- [ ] Mettez à jour les enregistrements DNS ou les équilibreurs de charge si les noms d'hôtes ont changé.
- [ ] Mettez hors service l'ancien environnement seulement après une période de validation réussie (p. ex. une semaine).

Revoyez ces listes de contrôle au moins trimestriellement, ou après toute version majeure de Docker Desktop, pour intégrer de nouvelles exigences.

## Pièges courants et comment les éviter

**Piège 1 : Ignorer la compatibilité de version entre Docker Desktop et les fonctionnalités du moteur Docker.**

Pourquoi cela arrive : Les équipes supposent que toutes les fonctionnalités sont rétrocompatibles, mais Docker Desktop inclut une version spécifique du moteur. Par exemple, les fonctionnalités de Docker Compose v2 peuvent nécessiter un moteur récent.

Comment éviter : Consultez les notes de version de Docker Desktop et du moteur intégré. Utilisez `docker version` pour confirmer la version du moteur avant de vous fier à de nouvelles fonctionnalités. Testez d'abord dans un environnement de préproduction.

**Piège 2 : Ne pas sauvegarder les données avant une migration.**

Pourquoi cela arrive : Les développeurs pensent que les montages bind survivront parce que le répertoire de l'hôte est copié, mais des permissions ou des chemins incohérents causent des échecs.

Comment éviter : Exécutez toujours un script de sauvegarde qui crée des archives de tous les volumes nommés et des données des montages bind, et stockez-les hors machine. Testez une restauration avant la migration réelle.

**Piège 3 : Utiliser des identifiants en clair dans les fichiers de configuration.**

Pourquoi cela arrive : Les exemples de configuration rapide dans la documentation montrent souvent des identifiants en ligne, et les équipes les copient sans les nettoyer.

Comment éviter : Utilisez les secrets Docker, les variables d'environnement ou les assistants d'identification. Analysez les fichiers de configuration à la recherche de mots de passe avant de les valider dans le contrôle de version.

**Piège 4 : Appliquer des changements sans plan de retour en arrière.**

Pourquoi cela arrive : La pression du temps conduit à sauter la préparation du retour en arrière, en supposant que la mise à niveau fonctionnera simplement.

Comment éviter : Gardez toujours l'installateur précédent et les sauvegardes de configuration. Pratiquez un retour en arrière dans un environnement de test pour connaître les étapes.

**Piège 5 : Négliger les healthchecks des conteneurs.**

Pourquoi cela arrive : Les développeurs se fient uniquement à `docker ps` pour montrer qu'un conteneur est en cours d'exécution, mais l'application à l'intérieur peut être dans une boucle de plantage.

Comment éviter : Définissez des healthchecks dans les Dockerfiles ou les fichiers Compose. Utilisez `docker inspect` pour vérifier l'état de santé après le déploiement.

**Piège 6 : Ne pas tester dans un environnement qui reflète les tailles de données de production.**

Pourquoi cela arrive : De petits ensembles de données de test cachent les problèmes de performance qui apparaissent avec les volumes de données de production.

Comment éviter : Utilisez un sous-ensemble représentatif de données ou générez un test de charge. Après la migration, exécutez l'application avec un trafic de type production pendant une période avant le basculement.

## Conclusion

Les mises à niveau et migrations de Docker Desktop réussissent lorsque vous les traitez comme des procédures opérationnelles avec des étapes définies, pas comme des actions ad hoc. Commencez par un inventaire approfondi des versions, des configurations et des données. Effectuez des changements par petits incréments réversibles. Vérifiez chaque changement avec des commandes concrètes et des sorties attendues. Ayez un chemin de récupération documenté pour les échecs courants. Utilisez des listes de contrôle avec des responsables clairs pour vous assurer que rien n'est oublié.

Comme prochaine étape, choisissez une vérification à faible risque de ce guide, comme le test de redémarrage pour la persistance des données ou une vérification `docker compose config`. Enregistrez l'état actuel, exécutez le test et comparez le résultat. Planifiez ensuite une revue trimestrielle de votre liste de contrôle de mise à niveau pour la maintenir à jour.

Un flux de travail fiable rend les échecs visibles, protège les valeurs sensibles, limite les changements à la ressource prévue et définit la vérification de la récupération avant qu'un incident ne force la décision.