13 - Volumes et persistance
Ce que tu vas apprendre
- Pourquoi les donnees disparaissent quand un conteneur est supprime
- La différence entre named volumes, bind mounts et tmpfs
- La syntaxe des volumes dans Docker Compose
- Les commandes docker volume
- Ou sont stockes les volumes sur ta machine
- Comment sauvegarder tes volumes
Prerequisites
- Avoir suivi les bases du networking
- Comprendre le cycle de vie d'un conteneur
J'ai perdu une base de donnees de dev complète la première fois que j'ai lance docker compose down -v sans reflechir. Toutes les donnees de test, les migrations appliquees, les fixtures que j'avais passees une heure a créer. Parce que je n'avais pas compris comment fonctionnent les volumes Docker.
Le filesystem éphémère
Un conteneur Docker a son propre système de fichiers. Quand tu ecris un fichier dans un conteneur, il est stocke dans une couche "writable" au-dessus de l'image. Quand le conteneur est supprime, cette couche disparaît.
bashdocker run -it alpine sh
echo "hello" > /data.txt
exit
# Le conteneur est arrete. Si tu le supprimes :
docker rm <container_id>
# /data.txt n'existe plus
Pour PostgreSQL, ca veut dire : tes tables, tes donnees, tout est dans le conteneur. Pas de volume = pas de persistance.
Les trois types de stockage
Named volumes
C'est le type le plus courant. Docker gere le stockage. Tu ne te soucies pas de l'emplacement sur le disque :
yamlservices:
db:
image: postgres:16-alpine
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
Le volume pgdata survit a docker compose down. Les donnees persistent entre les recreations de conteneurs. C'est ce que j'utilise pour toutes les bases de donnees sur paltemps.fr.
Bind mounts
Un bind mount monte un répertoire de ta machine directement dans le conteneur :
yamlservices:
app:
build: .
volumes:
- ./src:/app/src
Le dossier ./src de ta machine est accessible dans le conteneur a /app/src. Les modifications sont bidirectionnelles : si tu edites un fichier sur ta machine, il change dans le conteneur, et inversement.
Les bind mounts sont parfaits pour le développement (hot reload), mais ils ont des pièges qu'on verra dans l'article sur les permissions.
tmpfs
Un montage en mémoire. Les donnees disparaissent quand le conteneur s'arrêté :
yamlservices:
app:
tmpfs:
- /tmp
- /app/cache
Utile pour les fichiers temporaires ou les caches qui n'ont pas besoin de persister. C'est plus rapide que le disque et ca ne laisse pas de traces.
Syntaxe dans Docker Compose
La syntaxe courte :
yamlvolumes:
- pgdata:/var/lib/postgresql/data # named volume
- ./src:/app/src # bind mount
- /tmp # tmpfs anonyme
La syntaxe longue, plus explicite :
yamlvolumes:
- type: volume
source: pgdata
target: /var/lib/postgresql/data
- type: bind
source: ./src
target: /app/src
read_only: false
- type: tmpfs
target: /tmp
tmpfs:
size: 100000000 # 100 Mo
La syntaxe longue est plus verbeuse mais permet des options comme read_only ou la taille du tmpfs.
Le flag read_only
Tu peux monter un volume en lecture seule :
yamlvolumes:
- ./config/nginx.conf:/etc/nginx/nginx.conf:ro
Le :ro a la fin empeche le conteneur de modifier le fichier. Pour les fichiers de configuration, c'est une bonne pratique.
Commandes docker volume
bash# Lister tous les volumes
docker volume ls
# Inspecter un volume (voir son emplacement)
docker volume inspect pgdata
# Supprimer un volume
docker volume rm pgdata
# Supprimer tous les volumes inutilises
docker volume prune
Attention avec docker volume prune. Ca supprime tous les volumes qui ne sont attaches a aucun conteneur. Si tes conteneurs sont arretes (mais pas supprimes), les volumes sont conserves. Si tu as fait docker compose down sans -v, les volumes existent toujours mais ne sont attaches a rien. Un prune les supprimera.
Ou sont stockes les volumes
Sur Linux, les named volumes sont dans /var/lib/docker/volumes/. Sur Docker Desktop (Mac et Windows), ils sont dans la VM Linux de Docker Desktop, pas directement accessibles depuis l'explorateur de fichiers.
bashdocker volume inspect pgdata
Le champ Mountpoint te donne le chemin exact. Sur Linux, tu peux aller lire les fichiers directement (en root). Sur Mac et Windows, tu dois passer par un conteneur pour y acceder.
Stratégies de backup
Backup d'un named volume
La méthode classique : monter le volume dans un conteneur temporaire et copier les fichiers :
bashdocker run --rm \
-v pgdata:/data \
-v $(pwd):/backup \
alpine tar czf /backup/pgdata-backup.tar.gz -C /data .
Ca créé une archive pgdata-backup.tar.gz dans ton répertoire courant.
Restore
bashdocker run --rm \
-v pgdata:/data \
-v $(pwd):/backup \
alpine sh -c "cd /data && tar xzf /backup/pgdata-backup.tar.gz"
Pour PostgreSQL spécifiquement
Utilise pg_dump et pg_restore plutot que de copier les fichiers bruts :
bash# Backup
docker compose exec db pg_dump -U postgres myapp > backup.sql
# Restore
docker compose exec -T db psql -U postgres myapp < backup.sql
C'est plus fiable que de copier les fichiers du volume, surtout si la base est en cours d'utilisation.
Les erreurs courantes
Oublier de déclarer le volume en bas du fichier :
yamlservices:
db:
volumes:
- pgdata:/var/lib/postgresql/data
# Si tu oublies ca, Compose cree un volume anonyme
volumes:
pgdata:
Utiliser un bind mount pour une base de donnees : les bases de donnees (PostgreSQL, MySQL, MongoDB) ne fonctionnent pas bien avec des bind mounts sur Docker Desktop a cause des différences de permissions et de performance. Utilise toujours un named volume.
Confondre docker compose down et docker compose down -v : le premier conserve les volumes, le second les supprime. Fais attention.
Résumé
- Sans volume, les donnees disparaissent avec le conteneur
- Named volumes pour les bases de donnees (Docker gere le stockage)
- Bind mounts pour le code source en dev (synchronisation bidirectionnelle)
- tmpfs pour les fichiers temporaires en mémoire
pg_dumpest plus fiable que copier les fichiers bruts d'un volume PostgreSQLdocker compose down -vsupprime les volumes : a utiliser avec precaution
Navigation : Precedent : 12 - Networking avance | Suivant : 14 - Variables d'environnement et secrets
Sources
- Docker volumes par Docker
- Manage data in Docker par Docker
- PostgreSQL Docker backup par PostgreSQL