Retour au cours

infra / docker

Volumes et bind mounts

Leçon 51 exercice

Explication

Ce que vous allez apprendre

  • Comprendre pourquoi un conteneur est éphémère et pourquoi ses données disparaissent sans précaution
  • Distinguer un volume nommé (géré par Docker) d'un bind mount (chemin hôte explicite)
  • Choisir la bonne solution de persistance selon le contexte (production, développement, données sensibles)
  • Sauvegarder et restaurer un volume nommé à l'aide d'un conteneur intermédiaire
  • Éviter le piège classique de chercher en vain le contenu d'un volume directement sur le disque hôte

Dans quel contexte ?

Une équipe déploie une base PostgreSQL en conteneur pour la première fois. Après quelques jours de tests concluants, elle supprime le conteneur par erreur avec docker rm -f db pour libérer de l'espace — et découvre que toutes les données créées ont disparu avec lui, car aucun volume n'avait été monté sur /var/lib/postgresql/data. Une leçon apprise à ses dépens qu'un volume nommé aurait évitée du premier coup.

Le problème que résout cette leçon

Un conteneur est par nature éphémère : tout ce qu'il écrit dans son propre système de fichiers disparaît définitivement dès qu'il est supprimé (docker rm). C'est très bien pour une application sans état, mais catastrophique pour une base de données ou tout ce qui doit survivre à un redémarrage. Il faut donc un moyen de faire persister des données en dehors du cycle de vie du conteneur.

TypeGéré parCas d'usage typique
Volume nomméDockerBases de données, données persistantes en prod
Bind mountToi (chemin hôte explicite)Développement, hot-reload de code
tmpfsRAM, jamais sur disqueSecrets temporaires, cache volatile

Prérequis

Il est utile d'être à l'aise avec le cycle de vie de base d'un conteneur (docker run, docker rm) vu dans la première leçon.

Deux façons de persister, deux philosophies

Un volume est un espace de stockage entièrement géré par Docker : on lui donne un nom, et Docker s'occupe de l'emplacement réel sur le disque. C'est la solution recommandée en production, car elle est portable, indépendante du système de fichiers de l'hôte et plus facile à sauvegarder ou migrer.

Un bind mount, à l'inverse, relie un chemin précis et connu de la machine hôte à un chemin dans le conteneur. C'est très pratique en développement : en montant le dossier source du projet, on peut modifier son code depuis son éditeur habituel et voir le changement pris en compte immédiatement dans le conteneur, sans reconstruire l'image à chaque fois.

Il existe une troisième option, plus rare : tmpfs, un stockage qui vit uniquement en mémoire RAM et n'est jamais écrit sur disque — utile pour des données sensibles ou temporaires qui ne doivent laisser aucune trace.

Le piège à connaître

Un volume nommé n'est pas directement consultable comme un simple dossier depuis l'hôte : il faut passer par un conteneur intermédiaire pour y accéder (par exemple pour faire une sauvegarde).

Piège fréquent

Beaucoup de débutants cherchent en vain le dossier du volume sur leur disque, alors qu'il est géré en interne par Docker dans un emplacement qu'il vaut mieux ne jamais manipuler directement. Pour sauvegarder ou inspecter son contenu, passe toujours par un conteneur temporaire qui le monte (voir l'exemple avec alpine + tar), jamais en fouillant directement /var/lib/docker/volumes.

Lien avec la suite

Cette notion de persistance sera reprise telle quelle dans Docker Compose (leçon 8), où chaque service pourra déclarer ses propres volumes de façon déclarative.

Commandes & code

Volumes et bind mounts

bash
# Un conteneur est éphémère : ses données disparaissent avec lui SAUF si elles sont persistées.

# --- Volumes Docker : gérés par Docker lui-même, recommandés en production ---
docker volume create data_postgres
docker volume ls
docker volume inspect data_postgres
docker volume rm data_postgres

docker run -d --name db -v data_postgres:/var/lib/postgresql/data postgres:16
# La partie gauche (data_postgres) est un volume nommé, géré par Docker (pas un chemin hôte)

# --- Bind mounts : lie un chemin PRÉCIS de l'hôte à un chemin du conteneur ---
docker run -d --name api -v /home/ned/mon-api/src:/app/src mon-api:1.0
# Utile en développement (hot-reload du code sans reconstruire l'image)

docker run -d --name api -v "$(pwd)":/app -w /app mon-api:1.0 npm run dev

# Syntaxe --mount (plus explicite, préférée en production, équivalente à -v)
docker run -d --name db \
  --mount type=volume,source=data_postgres,target=/var/lib/postgresql/data \
  postgres:16

docker run -d --name api \
  --mount type=bind,source=/home/ned/mon-api/src,target=/app/src,readonly \
  mon-api:1.0
# readonly empêche le conteneur d'écrire dans le dossier source de l'hôte

# tmpfs : stockage en mémoire RAM, jamais écrit sur disque (données sensibles/temporaires)
docker run -d --name cache --tmpfs /app/cache:size=100m mon-api:1.0

# Backup d'un volume nommé (le volume n'est pas directement accessible depuis l'hôte)
docker run --rm -v data_postgres:/data -v "$(pwd)":/backup alpine \
  tar czf /backup/postgres-backup.tar.gz -C /data .

# Restauration d'un volume à partir d'un backup
docker run --rm -v data_postgres:/data -v "$(pwd)":/backup alpine \
  tar xzf /backup/postgres-backup.tar.gz -C /data

# Voir quel(s) conteneur(s) utilisent un volume donné avant de le supprimer
docker ps -a --filter volume=data_postgres
TypeGéré parEmplacementCas d'usage
Volume nomméDocker/var/lib/docker/volumes/...bases de données, données persistantes en prod
Bind mountToi (chemin hôte explicite)n'importe où sur l'hôtedéveloppement, config, hot-reload
tmpfsRAM, jamais sur disquemémoiresecrets temporaires, cache volatile

Résumé

  • Sans volume, toute donnée écrite dans un conteneur disparaît à sa suppression.
  • Les volumes nommés sont gérés par Docker et recommandés en production ; les bind mounts pointent un chemin hôte précis.
  • Un volume se sauvegarde en passant par un conteneur intermédiaire (alpine + tar) qui le monte.

Exercices pratiques

1 disponible
1

Mission : sécuriser une base PostgreSQL avant une purge de conteneurs

Objectif : Mettre en place la persistance correcte d'une base de données et savoir en extraire une sauvegarde.

Contexte

Une équipe s'apprête à lancer docker container prune pour nettoyer un serveur de test, mais une base PostgreSQL tourne dedans sans volume. Tu dois d'abord sécuriser ses données avant tout nettoyage.

Résoudre l’exercice →