Problème n° 6 — Docker : Données perdues à chaque redémarrage du conteneur

Contexte

Un développeur déploie une application web avec une base de données MySQL via Docker Compose. L’application fonctionne parfaitement, les données s’enregistrent bien pendant la session. Mais à chaque docker compose down suivi d’un docker compose up, toutes les données ont disparu — la base est vide, comme au premier démarrage.

Le développeur est convaincu d’avoir bien configuré la persistance des données car il voit bien un volume déclaré dans son fichier docker-compose.yml :

services:
  app:
    image: monapp:latest
    ports:
      - "8080:80"
    depends_on:
      - db

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: appdb
      MYSQL_USER: appuser
      MYSQL_PASSWORD: apppass
    ports:
      - "3306:3306"

volumes:
  mysql_data:

Le volume mysql_data est bien présent quand il lance docker volume ls, et il n’est pas supprimé entre les redémarrages.

Problème

Les données sont perdues à chaque redémarrage malgré un volume déclaré. Identifier l’erreur et corriger le fichier docker-compose.yml pour assurer la persistance des données.

✓ Answer

Solution

Cause racine : Le volume mysql_data est bien déclaré dans la section volumes en bas du fichier, mais il n’est pas monté dans le service db. Sans la directive volumes: dans la définition du service, MySQL écrit ses données dans le système de fichiers interne du conteneur — qui est détruit à chaque docker compose down. Le volume existe mais n’est jamais utilisé.

Diagnostic :

Vérifier qu’aucun volume n’est monté sur le conteneur db en cours d’exécution :

docker inspect <nom_conteneur_db> --format='{{json .Mounts}}'

→ Retourne [] — aucun volume monté, confirme le problème

Fichier corrigé :

services:
  app:
    image: monapp:latest
    ports:
      - "8080:80"
    depends_on:
      - db

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: appdb
      MYSQL_USER: appuser
      MYSQL_PASSWORD: apppass
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql

volumes:
  mysql_data:

La ligne - mysql_data:/var/lib/mysql dans le service db mappe le volume déclaré vers le répertoire où MySQL stocke ses données.

Vérification :

# Relancer proprement
docker compose down
docker compose up -d

# Vérifier que le volume est bien monté
docker inspect <nom_conteneur_db> --format='{{json .Mounts}}'

→ Doit retourner le volume mysql_data monté sur /var/lib/mysql

Insérer des données, faire un docker compose down puis docker compose up -d → les données doivent persister.

Laisser un commentaire