Retour au cours

infra / docker-compose

Volumes et persistance des données

Leçon 41 exercice

Explication

Ce que vous allez apprendre

  • Comprendre pourquoi les données écrites dans un conteneur disparaissent avec lui
  • Choisir entre un volume nommé (persistance) et un bind mount (développement en direct)
  • Éviter le piège des volumes anonymes qui s'accumulent silencieusement sur le disque
  • Savoir que docker compose down ne supprime jamais les volumes nommés, sauf avec -v
  • Sécuriser un montage en lecture seule avec l'option :ro

Dans quel contexte ?

Une équipe redémarre régulièrement sa stack de développement avec docker compose down puis up pour repartir d'un environnement propre. Un jour, elle réalise que toutes les données de test de la base app_db ont disparu après un simple redémarrage, alors qu'elle pensait le volume db_data persistant. Cette leçon explique précisément pourquoi, et comment éviter ce genre de surprise.

Le point de départ : ce qui disparaît

Par nature, un conteneur est éphémère. Tout ce qu'il écrit sur son propre système de fichiers disparaît dès qu'il est supprimé. Pour l'application elle-même, ce n'est pas grave : on veut justement pouvoir la recréer identique à volonté.

Il reste un problème : les données qu'on veut garder

Mais que se passe-t-il pour les données qu'on veut absolument conserver, comme le contenu d'une base de données ? Si elles vivent uniquement dans le conteneur, un simple redémarrage les efface. C'est là qu'interviennent les volumes.

Première solution : le volume nommé

Un volume nommé est un espace de stockage géré entièrement par Docker, qui existe en dehors du cycle de vie du conteneur. Tu ne sais généralement pas où il vit réellement sur le disque, et ce n'est pas grave : c'est le bon choix pour des données qui doivent survivre à un docker compose down puis up, comme les fichiers d'une base Postgres.

Deuxième solution : le bind mount

Une fois qu'on comprend le volume nommé, il faut connaître son cousin : le bind mount. Il relie directement un dossier de ta machine à un dossier du conteneur. C'est idéal en développement, car toute modification du code sur ta machine est immédiatement visible dans le conteneur, sans reconstruire l'image.

Bien choisir entre les deux

Pour résumer simplement : volume nommé pour des données à conserver durablement, bind mount pour du code que tu modifies en direct pendant le développement. Les deux peuvent d'ailleurs cohabiter sur un même service.

Type de montageGéré parSurvit à down (sans -v)Cas d'usage typique
Volume nomméDockerOuiDonnées Postgres, Redis persistant
Bind mountLe système de fichiers hôteOui (c'est ton dossier)Code source en développement
Volume anonymeDocker, sans nomOui, mais introuvableÀ éviter

Un cas à éviter : le volume anonyme

Il existe une troisième forme, le volume anonyme, qui n'a pas de nom explicite, juste un chemin. Évite-le : sans nom, il devient vite impossible à identifier et s'accumule silencieusement sur le disque au fil du temps.

Le piège le plus dangereux de cette leçon

Beaucoup de débutants croient qu'un docker compose down supprime aussi les volumes nommés. C'est faux : il faut explicitement taper down -v pour cela. Ce piège classique a déjà fait perdre des données de test... et parfois de production.

Piège dangereux

docker compose down -v supprime IMMÉDIATEMENT et sans confirmation tous les volumes nommés du projet, y compris db_data. Ne l'utilise jamais par réflexe sur un environnement qui contient des données que tu veux garder — vérifie toujours d'abord avec docker volume ls ce qui va disparaître.

Un dernier réflexe de sécurité

Pense aussi à ajouter :ro (read-only) sur un montage qui ne devrait jamais être modifié par le conteneur : cela évite une brèche de sécurité inutile.

Bonne pratique

Avant toute opération risquée sur une base de données locale, sauvegarde le volume avec docker run --rm -v db_data:/data -v "$(pwd)":/backup alpine tar czf /backup/db_data.tar.gz -C /data .. Cette archive peut être restaurée plus tard, indépendamment du cycle de vie des conteneurs.

La prochaine leçon aborde un autre besoin fondamental : configurer une application différemment selon l'environnement, grâce aux variables d'environnement et aux fichiers .env.

Commandes & code

Volumes & persistance

Les conteneurs sont éphémères : sans volume, les données disparaissent avec le conteneur.

yaml
services:
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: changeme
    volumes:
      # Volume nommé : géré par Docker, persiste entre les "down/up"
      - db_data:/var/lib/postgresql/data

      # Bind mount : mappe un dossier de l'hôte (utile en dev)
      - ./init-scripts:/docker-entrypoint-initdb.d:ro

  web:
    image: nginx:1.27-alpine
    volumes:
      - ./html:/usr/share/nginx/html:ro     # ro = read-only dans le conteneur
      - nginx_cache:/var/cache/nginx

  redis:
    image: redis:7-alpine
    volumes:
      # Volume anonyme (pas de nom explicite) : évité en pratique
      - /data
    command: ["redis-server", "--appendonly", "yes"]

# Déclaration obligatoire des volumes nommés au niveau racine
volumes:
  db_data:
    driver: local
  nginx_cache:
bash
# Lister les volumes créés par Docker
docker volume ls

# Inspecter un volume (point de montage réel sur l'hôte)
docker volume inspect docker-compose_db_data

# Supprimer les volumes orphelins (non référencés par un conteneur)
docker volume prune

# Sauvegarder un volume nommé dans une archive tar
docker run --rm -v docker-compose_db_data:/data -v "$(pwd)":/backup \
  alpine tar czf /backup/db_data.tar.gz -C /data .
TypeExempleCas d'usage
Volume nommédb_data:/var/lib/postgresql/dataDonnées persistantes gérées par Docker
Bind mount./src:/app/srcLive reload en développement
Volume anonyme/dataÀ éviter : difficile à retrouver/nettoyer
:ro./conf:/etc/nginx:roEmpêche le conteneur de modifier l'hôte

Résumé

  • Sans volume = perte de données au down ou à la recréation du conteneur.
  • Volumes nommés pour la persistance, bind mounts pour le dev en live.
  • Toujours déclarer les volumes nommés sous la clé racine volumes:.

Exercices pratiques

1 disponible
1

Mission : sauver les données de staging avant un nettoyage douteux

Objectif : Distinguer volume nommé, bind mount et option -v, et anticiper une suppression accidentelle de données.

Contexte

Sur l'environnement de staging de boutique-api, un collègue s'apprête à taper docker compose down -v en pensant que -v signifie simplement "verbose" (plus de détails affichés). Le service db utilise un volume nommé db_data, et le service web monte ./html en lecture seule sur /usr/share/nginx/html.

Vérifie ce qui va réellement se passer avant de laisser faire, et sécurise la configuration.

Résoudre l’exercice →