Guide pratique des volumes Docker : 5 exemples pour ne plus perdre les données des conteneurs

Dernière ligne du terminal : « Database import completed successfully ». Quatre heures pour importer vingt mille enregistrements de test dans un conteneur MySQL. Quelques appels API, les tests passent.
Le lendemain, reflexe : docker ps pour voir l’état. Vide. Oublié de le relancer hier soir ? docker ps -a. Rien non plus. Puis le souvenir : avant de dormir, pour libérer de l’espace disque, docker system prune -a.
Terminé. Toutes les données perdues. Vingt mille lignes, quatre heures de travail, remis à zéro.
Trois semaines avec Docker : conteneurs rapides, isolation propre — mais pas le talon d’Achille : un conteneur n’est pas fait pour stocker des données. Supprimez-le, les données partent ; redémarrez-le, la config revient à zéro.
Cet article propose cinq cas pratiques pour utiliser Docker Volume et sortir les données du conteneur, afin qu’elles ne suivent plus son cycle de vie.
La vérité sur la perte de données des conteneurs
Pourquoi supprimer un conteneur efface-t-il les données ?
Docker utilise un système de fichiers en couches. Imaginez un gâteau mille-feuilles : couche inférieure = image (lecture seule, partagée) ; couche supérieure = couche conteneur (écriture, propre à chaque instance). Fichiers créés, config modifiée, données importées : tout est écrit dans cette couche supérieure.
Point clé : à la suppression du conteneur, cette couche en écriture est détruite.
Vous doutez ? Essayez :
# Démarrer un conteneur Alpine et écrire un fichier
docker run -it --name test-container alpine sh
# Dans le conteneur
echo "données importantes" > /tmp/data.txt
exit
# Supprimer le conteneur
docker rm test-container
# Tenter de récupérer
docker run -it --name test-container alpine sh
cat /tmp/data.txt # Erreur : No such file or directory
Les données disparaissent sans avertissement.
Le design est cohérent : les conteneurs visent les applications sans état. Nginx, serveur API — pas besoin de persistance, chaque démarrage est identique. Base de données, Redis, upload de fichiers ? Il faut garder les données.
La solution officielle Docker : Volume — données hors du conteneur, cycle de vie du conteneur et des données totalement découplés.
Qu’est-ce qu’un Volume ? Comment il sauve vos données
L’essence du Volume : un disque externe pour le conteneur
Un Volume, c’est comme brancher un disque au conteneur. Les données ne sont pas dans la couche du conteneur, mais dans un répertoire de l’hôte, monté dans le conteneur (par ex. /var/lib/mysql). En réalité : /var/lib/docker/volumes/mysql-data/_data sur l’hôte.
Conteneur supprimé ? Les données restent sur l’hôte. Nouveau conteneur, même Volume : tout revient.
Trois types de montage — faciles à confondre au début :
| Type de montage | Emplacement des données | Cas d’usage | Gestion |
|---|---|---|---|
| Volume | Répertoire géré par Docker (/var/lib/docker/volumes/) | Persistance BDD, prod | Commandes docker volume |
| Bind Mount | Chemin arbitraire sur l’hôte | Code, config en dev | Chemins manuels |
| tmpfs | Mémoire | Données temporaires, sensibles (sans disque) | Vidé à l’arrêt du conteneur |
Au début, Volume et Bind Mount semblaient identiques (« monter un répertoire hôte »). Jusqu’au piège : Bind Mount sur le répertoire de données MySQL, suppression du dossier hôte — conteneur MySQL en panne.
Volume = gestion complète par Docker : pas de souci de chemins, permissions, stratégie de backup. Emplacement ? docker volume inspect. Migration ? commandes docker volume. D’où la recommandation officielle Volume plutôt que Bind Mount pour la persistance.
Où sont réellement les données Volume ?
Sur Linux, par défaut :
/var/lib/docker/volumes/<volume-name>/_data/
Sur Mac et Windows avec Docker Desktop, tout tourne dans une VM : ce chemin n’est pas visible localement. Utilisez docker volume inspect pour les détails.
5 exemples pour maîtriser les Volume
Assez de théorie — cinq cas du simple au réel. Faites-les une fois, vous aurez compris l’essentiel.
Exemple 1 : créer votre premier Volume nommé
Le plus simple : un Volume vide.
# Créer un Volume nommé my-data
docker volume create my-data
# Lister les Volume
docker volume ls
# Détails
docker volume inspect my-data
Sortie attendue (inspect) :
[
{
"CreatedAt": "2025-12-17T12:00:00Z",
"Driver": "local",
"Mountpoint": "/var/lib/docker/volumes/my-data/_data",
"Name": "my-data"
}
]
Mountpoint : l’emplacement réel des données.
Exemple 2 : persistance d’un site statique Nginx
Scénario : site statique en dev, redémarrage Nginx à chaque modification — images et logs perdus à chaque fois.
Solution : monter /usr/share/nginx/html sur un Volume.
# Volume pour le contenu du site
docker volume create nginx-html
# Nginx avec Volume
docker run -d \
--name my-nginx \
-p 8080:80 \
-v nginx-html:/usr/share/nginx/html \
nginx:latest
# Page de test dans le conteneur
docker exec my-nginx bash -c 'echo "<h1>Hello Docker Volume!</h1>" > /usr/share/nginx/html/index.html'
# Test (navigateur http://localhost:8080 ou curl)
curl http://localhost:8080
Supprimez le conteneur :
docker rm -f my-nginx
Nouveau conteneur, même Volume :
docker run -d \
--name my-nginx-v2 \
-p 8080:80 \
-v nginx-html:/usr/share/nginx/html \
nginx:latest
# Le contenu est toujours là
curl http://localhost:8080
Rien n’est perdu. C’est ça, la magie du Volume.
Exemple 3 : persistance MySQL (niveau production)
Cas le plus courant : MySQL en conteneur, données obligatoirement persistantes.
# Volume dédié MySQL
docker volume create mysql-data
# Conteneur MySQL
docker run -d \
--name mysql-demo \
-e MYSQL_ROOT_PASSWORD=my-secret-pw \
-e MYSQL_DATABASE=testdb \
-p 3306:3306 \
-v mysql-data:/var/lib/mysql \
mysql:8.0
# Attendre le démarrage (~10 s)
sleep 10
# Table de test
docker exec -it mysql-demo mysql -uroot -pmy-secret-pw testdb -e "
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50)
);
INSERT INTO users (name) VALUES ('Alice'), ('Bob');
"
# Lecture
docker exec -it mysql-demo mysql -uroot -pmy-secret-pw testdb -e "SELECT * FROM users;"
Suppression du conteneur (simulation d’erreur) :
docker rm -f mysql-demo
Relance avec le même Volume :
docker run -d \
--name mysql-demo-v2 \
-e MYSQL_ROOT_PASSWORD=my-secret-pw \
-p 3306:3306 \
-v mysql-data:/var/lib/mysql \
mysql:8.0
sleep 10
# Les données sont toujours là
docker exec -it mysql-demo-v2 mysql -uroot -pmy-secret-pw testdb -e "SELECT * FROM users;"
Point clé : répertoire de données MySQL = /var/lib/mysql. Chemins différents selon le moteur : Redis /data, PostgreSQL /var/lib/postgresql/data.
Exemple 4 : persistance Redis
Redis stocke par défaut en mémoire ; RDB ou AOF permettent la persistance disque.
docker volume create redis-data
docker run -d \
--name redis-demo \
-p 6379:6379 \
-v redis-data:/data \
redis:latest redis-server --appendonly yes
# --appendonly yes active l'AOF
docker exec -it redis-demo redis-cli SET mykey "Hello Redis Volume"
docker exec -it redis-demo redis-cli GET mykey
Suppression :
docker rm -f redis-demo
Relance :
docker run -d \
--name redis-demo-v2 \
-p 6379:6379 \
-v redis-data:/data \
redis:latest redis-server --appendonly yes
docker exec -it redis-demo-v2 redis-cli GET mykey
Attention : sans --appendonly yes, Redis ne persiste qu’en mémoire — redémarrage = perte malgré le Volume.
Exemple 5 : Volume partagé entre plusieurs conteneurs
Scénario : un conteneur Nginx sert des fichiers statiques, un autre écrit des logs — même Volume.
docker volume create shared-logs
# Conteneur applicatif qui écrit les logs
docker run -d \
--name app-writer \
-v shared-logs:/logs \
alpine sh -c "while true; do echo $(date) >> /logs/app.log; sleep 2; done"
# Nginx en lecture seule
docker run -d \
--name log-reader \
-p 8080:80 \
-v shared-logs:/usr/share/nginx/html:ro \
nginx:latest
# :ro = lecture seule (read-only)
sleep 5
curl http://localhost:8080/app.log
Points clés :
- Un Volume peut être monté sur plusieurs conteneurs
- Suffixe
:ropour le mode lecture seule - En prod : architecture « conteneur de collecte de logs + conteneur applicatif »
Commandes de gestion des Volume
Après les cinq exemples : comment lister, supprimer, nettoyer ?
# 1. Créer
docker volume create <volume-name>
# 2. Lister
docker volume ls
# 3. Détails (chemin de montage)
docker volume inspect <volume-name>
# 4. Supprimer un Volume
docker volume rm <volume-name>
# Erreur si un conteneur l'utilise encore
# 5. Supprimer tous les Volume inutilisés
docker volume prune
# Confirmation : taper y
# 6. Forcer sans confirmation
docker volume prune -f
Problème courant : « volume is in use »
Un conteneur utilise encore ce Volume :
docker ps -a --filter volume=<volume-name>
docker rm -f <container-name>
docker volume rm <volume-name>
Espace disque occupé
# Linux/Mac
docker volume inspect <volume-name> --format '{{ .Mountpoint }}' | xargs du -sh
# Exemple : 512M /var/lib/docker/volumes/mysql-data/_data
Bind Mount vs Volume : lequel choisir ?
Question classique des débutants. Règle simple : données de prod → Volume ; code de dev → Bind Mount.
| Scénario | Recommandation | Raison |
|---|---|---|
| MySQL / PostgreSQL | Volume | Gestion Docker, backup, perfs |
| Redis / MongoDB | Volume | Idem |
| Logs, fichiers uploadés | Volume | Sécurité, survit à la suppression |
| Code source en dev | Bind Mount | Modifications immédiates sans rebuild |
| Config (nginx.conf) | Bind Mount | Édition rapide sur l’hôte |
| Cache, données temporaires | tmpfs | Rapide, pas de disque |
Comparaison de syntaxe
# Volume (persistance recommandée)
docker run -v my-volume:/data redis:latest
# Bind Mount (dev)
docker run -v /Users/me/code:/app node:latest
# Syntaxe --mount (plus explicite, prod)
docker run --mount type=volume,source=my-volume,target=/data redis:latest
docker run --mount type=bind,source=/Users/me/code,target=/app node:latest
Arbre de décision
- Les données doivent-elles être conservées longtemps ? Oui → Volume ; non → tmpfs
- Faut-il les modifier directement sur l’hôte ? Oui → Bind Mount ; non → Volume
- Prod ou dev ? Prod → Volume ; dev → Bind Mount
Exemple réel
Environnement de dev :
docker run -d \
--name dev-app \
-v $(pwd)/src:/app/src \ # Bind Mount : code à jour tout de suite
-v app-uploads:/app/uploads \ # Volume : fichiers uploadés
-v postgres-data:/var/lib/postgresql/data \ # Volume : BDD
my-app:dev
Production :
docker run -d \
--name prod-app \
-v app-uploads:/app/uploads \
-v postgres-data:/var/lib/postgresql/data \
my-app:latest
# Le code est dans l'image, pas de montage nécessaire
FAQ et bonnes pratiques
FAQ : pièges et solutions
Q1 : les données Volume peuvent-elles disparaître ?
Non, tant que vous n’exécutez pas docker volume rm. Même après redémarrage de l’hôte, les données restent.
Attention : docker system prune -a --volumes supprime tous les Volume inutilisés — à utiliser avec prudence.
Q2 : que se passe-t-il si le Volume n’existe pas au démarrage ?
Docker le crée automatiquement :
docker run -d -v auto-created-volume:/data alpine
Je recommande toutefois de créer le Volume explicitement pour savoir où sont les données.
Q3 : comment sauvegarder un Volume ?
Méthode recommandée :
docker run --rm \
-v mysql-data:/source \
-v $(pwd):/backup \
alpine tar -czf /backup/mysql-backup.tar.gz -C /source .
# Restauration
docker run --rm \
-v mysql-data:/target \
-v $(pwd):/backup \
alpine tar -xzf /backup/mysql-backup.tar.gz -C /target
Q4 : migrer un Volume entre machines ?
Oui, manuellement :
- Sur la machine source : archiver comme ci-dessus
- Transférer le
.tar.gz - Sur la nouvelle machine : créer le Volume et extraire
Pour aller plus loin : driver Volume NFS ou stockage cloud.
Q5 : volume anonyme ? Nettoyage ?
Sans nom explicite, Docker crée un volume anonyme :
docker run -d -v /data alpine # nom aléatoire du type a1b2c3d4...
Difficile à gérer, risque de saturation disque :
docker volume prune # supprime les Volume inutilisés, anonymes inclus
Bonne pratique : toujours un Volume nommé.
6 bonnes pratiques (production)
-
Volume nommé systématiquement
# ✓ Bon docker run -v mysql-data:/var/lib/mysql mysql:8.0 # ✗ Mauvais docker run -v /var/lib/mysql mysql:8.0 # volume anonyme -
Sauvegardes régulières des données critiques
Tâche planifiée quotidienne sur les Volume de BDD. Une perte de données, on n’oublie pas. -
Docker Compose pour les projets complexes
# docker-compose.yml services: db: image: mysql:8.0 volumes: - mysql-data:/var/lib/mysql volumes: mysql-data: driver: local -
En prod, préférer
--mountà-v
Syntaxe plus explicite, messages d’erreur plus clairs :docker run --mount type=volume,source=mysql-data,target=/var/lib/mysql mysql:8.0 -
Nettoyer les Volume inutilisés
Une fois par mois :docker volume prune -
Données sensibles : chiffrement
Mots de passe, clés dans un Volume : envisager le chiffrement (ex. partition LUKS).
Conclusion
Retour à cette nuit-là — avec Docker Volume, une seule ligne aurait suffi :
docker run -d --name mysql-demo -v mysql-data:/var/lib/mysql mysql:8.0
Les données n’auraient pas suivi le conteneur dans la poubelle. Quatre heures de travail, vingt mille lignes, en sécurité sur l’hôte.
Les conteneurs Docker sont sans état — atout et limite. Le Volume existe pour dépasser cette limite : légèreté et isolation du conteneur, données persistantes en confiance.
Cinq exemples : premier Volume, Nginx, MySQL, Redis, partage multi-conteneurs — environ 90 % des besoins du quotidien.
À vous : terminal, premier Volume, conteneur MySQL, écrivez des données. Supprimez le conteneur, relancez — quand les données sont encore là, vous comprenez vraiment la persistance.
Et si vous ne voulez plus revivre la peur des 3 h du matin sans backup, gardez cet article sous la main. Un jour, il pourra vous sauver.
Parcours complet des volumes Docker en pratique
5 exemples pour éliminer la perte de données des conteneurs, du concept de base à MySQL et Redis
⏱️ Estimated time: 30 min
- 1
Step 1: Comprendre la cause : pourquoi les données des conteneurs disparaissent
Cause du problème :
• Un conteneur Docker n'est pas fait pour stocker des données ; supprimez-le et les données partent
• Au redémarrage, la configuration revient à l'état d'origine
• À la suppression, la couche en écriture est détruite avec le conteneur
• C'est le talon d'Achille de Docker
Système de fichiers en couches :
• Couche inférieure : image (lecture seule, partagée par tous les conteneurs)
• Couche supérieure : couche conteneur (écriture, propre à chaque conteneur)
• Fichiers créés, config modifiée, données importées : tout est écrit dans cette couche supérieure
• À la suppression du conteneur, cette couche en écriture est détruite - 2
Step 2: Cas 1 : créer votre premier Volume
Créer un Volume :
• docker volume create
• Commande : docker volume create my-data
• Géré par Docker, stocké dans le répertoire de données Docker — adapté à la production
Utiliser le Volume :
• Au démarrage : docker run -d -v my-data:/data alpine
• Les données restent dans le Volume ; supprimez le conteneur, les données restent
Vérifier :
• docker volume ls pour lister
• docker volume inspect my-data pour les détails - 3
Step 3: Cas 2 à 5 : Nginx, MySQL, Redis et partage multi-conteneurs
Cas 2 : persistance d'un site statique Nginx
• Monter le Volume : docker run -d -v nginx-html:/usr/share/nginx/html nginx
• Les fichiers statiques restent dans le Volume après suppression du conteneur
Cas 3 : persistance MySQL
• Monter sur /var/lib/mysql : docker run -d -v mysql-data:/var/lib/mysql mysql:8.0
• Les données de la base restent dans le Volume
Cas 4 : persistance Redis
• Monter sur /data : docker run -d -v redis-data:/data redis
• Les données Redis restent dans le Volume
Cas 5 : Volume partagé entre plusieurs conteneurs
• Plusieurs conteneurs, même Volume :
docker run -d -v shared-data:/data container1
docker run -d -v shared-data:/data container2
• Les conteneurs partagent les données - 4
Step 4: Volume vs Bind Mount et bonnes pratiques
Volume vs Bind Mount :
Volume
• Géré par Docker, stocké dans le répertoire de données Docker
• Adapté à la production, plus sûr et fiable
Bind Mount
• Monte directement un répertoire de l'hôte
• Adapté au développement, plus flexible
Bonnes pratiques :
• Production : Volume
• Développement : Bind Mount possible
• Sauvegarder régulièrement :
docker run --rm -v mysql-data:/data -v $(pwd):/backup alpine tar czf /backup/mysql-backup.tar.gz /data
• Volume nommé pour faciliter la gestion ; éviter les volumes anonymes
• Nettoyer les volumes inutilisés : docker volume prune une fois par mois
FAQ
Pourquoi les données des conteneurs disparaissent-elles ? Un conteneur n'est-il pas fait pour stocker des données ?
Docker utilise un système de fichiers en couches, comme un gâteau mille-feuilles :
• Couche inférieure : image (lecture seule, partagée)
• Couche supérieure : couche conteneur (écriture, propre à chaque conteneur)
• Fichiers, config, données importées : tout dans cette couche supérieure
• Suppression du conteneur : destruction de cette couche en écriture
Comment Docker Volume résout-il la perte de données ?
Créer un Volume :
• docker volume create my-data
• Géré par Docker, adapté à la production
Utiliser :
• docker run -d -v my-data:/data alpine
• Données dans le Volume ; suppression du conteneur sans perte
Comment configurer la persistance pour MySQL et Redis ?
• Monter sur /var/lib/mysql : docker run -d -v mysql-data:/var/lib/mysql mysql:8.0
• Données de la base dans le Volume
Redis :
• Monter sur /data : docker run -d -v redis-data:/data redis
• Données Redis dans le Volume
Vérifier :
• Supprimer puis recréer le conteneur : les données sont toujours là
• docker volume inspect pour l'emplacement
• Stockage sur l'hôte
Quelle différence entre Volume et Bind Mount ? Lequel choisir ?
Volume :
• Géré par Docker, répertoire de données Docker
• Production : plus sûr et fiable
Bind Mount :
• Répertoire hôte direct
• Développement : plus flexible
Choix :
• Production → Volume (gestion Docker, plus sûr)
• Développement → Bind Mount (accès direct aux fichiers hôte, debug plus simple)
Bonnes pratiques :
• Production : Volume ; développement : Bind Mount possible
• Sauvegardes régulières
• Volume nommé ; éviter l'anonyme
10 min de lecture · Publié le: 17 déc. 2025 · Mis à jour le: 27 juil. 2026
Guide pratique Docker
Si vous arrivez depuis la recherche, le plus rapide est de passer à l’article précédent ou suivant de cette série.
Précédent
Déployer un environnement PHP avec Docker Compose : tutoriel DNMP complet (Nginx+MySQL+PHP)
Guide pas à pas pour déployer DNMP (Docker+Nginx+MySQL+PHP) en un clic avec Docker Compose en 10 minutes, éliminer les écarts d'environnement en équipe, avec fichiers de configuration complets et guide de dépannage
Partie 13 sur 38
Suivant
Sauvegarde et migration des volumes Docker : guide pratique en 3 méthodes
Trois méthodes de sauvegarde des volumes Docker : tar, docker cp et outils automatisés. Points d'attention pour les bases de données, flux complet de migration serveur et pièges à éviter.
Partie 15 sur 38



Commentaires
Connectez-vous avec GitHub pour laisser un commentaire