1.3Volumes : persister les données au-delà des conteneurs
L'essentiel en 30 secondes
- Le conteneur est éphémère : tout ce qu'il écrit en lui-même meurt avec lui (rm = tout perdu) — pour une base, c'est inacceptable : on stocke hors du conteneur.
- Nommé pour les données, bind pour le code : -v pgdata:/var/lib/postgresql/data (volume géré par Docker, portable) pour les données ; -v ./site:/usr/share/nginx/html (dossier machine) pour le code en dev.
- Le test qui sauve : supprimer le conteneur, relancer sur le même volume — les données doivent être là ; docker volume ls inventorie, rm supprime (définitif).
Mini-cas filé — Idir perd (presque) une base
Idir a lancé la base de démo sans volume « pour aller vite ». Le soir, il supprime le conteneur pour repartir propre — et réalise que les données de test saisies l'après-midi ont disparu avec lui. Le lendemain, il relance avec -v pgdata:/var/lib/postgresql/data, recrée les données, supprime le conteneur, relance sur le même volume : tout est là. Il a transformé une frayeur en réflexe : données = volume nommé, vérifié par un test rm + relance avant chaque mise en route sérieuse.
Suite du cas 1.1-1.2 — Idir passe des conteneurs jetables aux données qui survivent.
1. Le drame du conteneur éphémère
Par défaut, tout ce qu'un conteneur écrit en lui-même meurt avec lui (rm = tout perdu). Pour une base de données, c'est inacceptable. La solution : stocker hors du conteneur, dans un volume géré par Docker ou un dossier monté de la machine.
Attention au faux ami : stop n'efface rien, rm efface tout ce qui n'est pas monté. Croire l'inverse est la perte de données la plus classique du niveau 1.
2. Volume nommé vs bind mount
Le volume nommé (-v pgdata:/var/lib/postgresql/data) est stocké par Docker, portable et sauvegardable : le choix pour les données. Le bind mount (-v ./site:/usr/share/nginx/html) relie un dossier de votre machine : le choix pour le code en développement (modifiez un fichier, le conteneur le voit aussitôt).
Le piège est le mauvais chemin interne : monter à côté du répertoire où l'application écrit vraiment, c'est persister du vide. On vérifie le chemin dans la documentation de l'image.
3. Le réflexe qui sauve : tester la suppression
Le test de vérité : supprimez le conteneur, relancez-en un sur le même volume — les données doivent être là. docker volume ls inventorie, docker volume rm supprime (attention, définitif). Les volumes orphelins se purgent avec prune, avec prudence.
Idir en a fait un rituel : aucun service de données ne part en démo sans avoir passé le test rm + relance.
🔎 Exemple concret — 🔎 Exemple concret — Postgres qui survit au rm
La base d'Idir, avant et après : avec volume, rien ne se perd.
docker run -d --name bdd -e POSTGRES_PASSWORD=secret -v pgdata:/var/lib/postgresql/data postgres:16.4
# ... créez des données ...
docker rm -f bdd
docker run -d --name bdd2 -e POSTGRES_PASSWORD=secret -v pgdata:/var/lib/postgresql/data postgres:16.4
# les données sont toujours là
Lecture : le volume pgdata a survécu à la suppression du conteneur.
Leçon : sans -v, la même séquence aurait tout effacé.
Vocabulaire de la section
- Volume nommé
- Espace de stockage géré par Docker, persistant hors des conteneurs, portable et sauvegardable.
Exemple simple : pgdata conserve la base d'Idir entre bdd et bdd2.
Ce que ce n'est pas : un fichier écrit dans le conteneur sans montage.
Réflexe : données = volume nommé.
- Bind mount
- Dossier de la machine monté tel quel dans le conteneur ; idéal pour le code en développement.
Exemple simple : -v ./site:/usr/share/nginx/html : Idir modifie, le conteneur voit aussitôt.
Ce que ce n'est pas : un stockage portable pour une base de production.
Réflexe : code dev = bind, données prod = volume nommé.
- Point de montage
- Le chemin interne où le volume apparaît dans le conteneur ; il doit être celui où l'application écrit.
Exemple simple : /var/lib/postgresql/data pour postgres:16.4.
Ce que ce n'est pas : un dossier quelconque choisi au hasard.
Réflexe : vérifier le chemin dans la doc de l'image.
- prune
- Nettoyage des ressources inutilisées, volumes orphelins inclus — suppression définitive.
Exemple simple : Idir purge les volumes de ses essais jetables, jamais pgdata.
Ce que ce n'est pas : une corbeille dont on peut restaurer le contenu.
Réflexe : vérifier la liste avant tout prune.
En pratique — En pratique — Prouver la persistance
- Lancez postgres AVEC un volume nommé et créez une table.
- Supprimez le conteneur (rm -f) sans toucher au volume.
- Relancez un conteneur sur le même volume et vérifiez la table.
- Refaites l'essai SANS volume : constatez la perte.
Script prêt à dire — sécuriser une base (30 s)
« Mes données vont dans un volume nommé : -v pgdata:/var/lib/postgresql/data, au chemin documenté de l'image. Je prouve : je supprime le conteneur, je relance sur le même volume, les données sont là. Sans volume, la même séquence efface tout. »
À dire en exécutant le rm + relance en direct ; montrer la table toujours présente.
Modèle copier-coller — base persistante
docker run -d --name bdd \
-e POSTGRES_PASSWORD=secret \
-v pgdata:/var/lib/postgresql/data \
postgres:16.4
# Preuve : docker rm -f bdd, relancer pareil en --name bdd2, vérifier.
# Jamais : docker volume rm pgdata (définitif) ni prune sans vérifier.
Base d'Idir en démo
Comme ci-dessus : pgdata nommé comme le service, test rm + relance passé avant de montrer quoi que ce soit au responsable.
Site web en dev
-v ./site:/usr/share/nginx/html : Idir édite ses pages sur sa machine, le conteneur Nginx les sert aussitôt — bind mount, pas volume nommé.
Reprise après frayeur
Base lancée sans volume par erreur : créer le volume, relancer avec -v, re-saisir — et graver le réflexe « données = volume nommé ».
Ménage des essais
docker volume ls pour inventorier, rm ciblé pour les volumes de test, prune seulement après vérification — jamais sur pgdata.
✓ Bonnes pratiques
- Données = volume nommé, code dev = bind mount.
- Tester le rm + relance avant de croire.
- Nommer les volumes comme les services (pgdata).
✗ Pièges fréquents
- Croire que stop efface (non) et que rm garde (non).
- Monter au mauvais chemin interne (données à côté).
- Purger les volumes (prune) sans vérifier.
Points clés à retenir
- Sans volume, rm = perte totale.
- Volume nommé pour les données, bind pour le code.
- Le test rm + relance prouve la persistance.
- prune avec prudence : suppression définitive.
Défi 48h — appliquez demain
Lancez postgres avec volume nommé, créez une table, faites rm -f + relance et vérifiez. Puis refaites sans volume : constatez la perte — et ne l'oubliez plus.
- Je monte un volume nommé pour toute donnée qui compte.
- Je distingue volume nommé (données) et bind mount (code dev).
- Je prouve la persistance par rm + relance avant usage sérieux.
Questions fréquentes
Où sont les volumes sur mon disque ?
Dans l'espace de Docker (docker volume inspect pgdata donne le chemin). On ne les manipule pas à la main : on passe par des conteneurs ou des sauvegardes.
Bind mount ou volume pour une base en prod ?
Volume nommé : portable, sauvegardable, indépendant de l'arborescence de la machine. Le bind est réservé au dev et aux fichiers de config.
Un conteneur postgres sans volume est supprimé (rm). Que deviennent ses données ?