Docker pour les devs - 13 - Volumes et persistance

Pourquoi les donnees disparaissent sans volumes, named volumes vs bind mounts vs tmpfs, et stratégies de backup.

  1. 01 Docker pour les devs - 00 - Pourquoi Docker change tout
  2. 02 Docker pour les devs - 01 - Containers vs VMs
  3. 03 Docker pour les devs - 02 - L'architecture de Docker
  4. 04 Docker pour les devs - 03 - Docker Desktop, Engine et alternatives
  5. 05 Docker pour les devs - 04 - Écrire un Dockerfile
  6. 06 Docker pour les devs - 05 - Layers et cache
  7. 07 Docker pour les devs - 06 - Le .dockerignore
  8. 08 Docker pour les devs - 07 - Multi-stage builds
  9. 09 Docker pour les devs - 08 - Choisir son image de base
  10. 10 Docker pour les devs - 09 - Docker Compose, les bases
  11. 11 Docker pour les devs - 10 - Docker Compose avance
  12. 12 Docker pour les devs - 11 - Networking Docker, les bases
  13. 13 Docker pour les devs - 12 - Networking Docker avance
  14. 14 Docker pour les devs - 13 - Volumes et persistance
  15. 15 Docker pour les devs - 14 - Variables d'environnement et secrets
  16. 16 Docker pour les devs - 15 - Permissions et utilisateurs
  17. 17 Docker pour les devs - 16 - Docker et monorepo
  18. 18 Docker pour les devs - 17 - Dev vs Prod
  19. 19 Docker pour les devs - 18 - ENTRYPOINT, CMD et scripts d'initialisation
  20. 20 Docker pour les devs - 19 - Debugger ses conteneurs
  21. 21 Docker pour les devs - 20 - Bases de donnees dans Docker
  22. 22 Docker pour les devs - 21 - Sauvegardes et restauration
  23. 23 Docker pour les devs - 22 - Conteneuriser un frontend
  24. 24 Docker pour les devs - 23 - Sécurité des conteneurs
  25. 25 Docker pour les devs - 24 - Optimisation des images
  26. 26 Docker pour les devs - 25 - Builds multi-platform
  27. 27 Docker pour les devs - 26 - Limiter les ressources de tes conteneurs
  28. 28 Docker pour les devs - 27 - Gerer les logs comme un adulte
  29. 29 Docker pour les devs - 28 - Healthchecks et restart policies
  30. 30 Docker pour les devs - 29 - Nettoyer Docker avant qu'il mange ton disque
  31. 31 Docker pour les devs - 30 - Registries et stratégie de tags
  32. 32 Docker pour les devs - 31 - Docker en CI/CD
  33. 33 Docker pour les devs - 32 - Au-dela de Compose
  34. 34 Docker pour les devs - 33 - Glossaire Docker de A a Z

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


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_dump est plus fiable que copier les fichiers bruts d'un volume PostgreSQL
  • docker compose down -v supprime les volumes : a utiliser avec precaution

Navigation : Precedent : 12 - Networking avance | Suivant : 14 - Variables d'environnement et secrets


Sources

Réservez un audit gratuit de 30 minutes. Je vous montre concrètement ce qu'on peut automatiser.