Volumes Docker vs montages Bind : conserver les données du conteneur de la bonne manière

  1. Accueil
  2. Blog
  3. DevOps

DevOps

Volumes Docker et montages Bind : Conserver les données du conteneur de la bonne manière

Supprimez un conteneur et ses données l’accompagnent, à moins que vous ne le stockiez dans un endroit plus sûr. Découvrez la différence entre les volumes, les montages de liaison et les tmpfs, quand les utiliser et comment sauvegarder ce qui compte.

9 min de lecture
Volumes Docker vs montages de liaison : conserver les données du conteneur de la bonne manière

À retenir

  • La couche inscriptible d’un conteneur est supprimée avec le conteneur, les données importantes nécessitent donc un montage.
  • Les Volumes nommés sont gérés par Docker et constituent le choix habituel pour les bases de données et les données de production.
  • Les Bind mounts mappent un dossier hôte, ce qui les rend idéaux pour le code en direct pendant le développement.
  • docker compose down -v supprime des volumes, utilisez-le donc avec précaution et conservez des sauvegardes testées.

Vous démarrez une base de données dans un conteneur, ajoutez des données, supprimez le conteneur et en démarrez un nouveau. Les données ont disparu. Presque tout le monde apprend cette leçon à ses dépens. Les volumes Docker et les montages de liaison existent pour maintenir les données en vie au-delà de la durée de vie d’un conteneur.

Ce guide explique comment chacun fonctionne et comment choisir. Les commandes et fichiers ici sont des exemples standards, basés sur le comportement documenté de Docker, et nous ne les avons pas exécutés pour cet article, alors essayez-les d’abord sur des données jetables. Les détails peuvent différer entre les versions de Docker et sur Docker Desktop. Si vous débutez avec les conteneurs, commencez par notre Tutoriel Docker pour débutants.

Pourquoi les données des conteneurs disparaissent

Une image Docker est constituée de calques en lecture seule. Lorsqu’un conteneur démarre, Docker ajoute une fine couche inscriptible sur le dessus et toutes les modifications y sont transférées. Cette couche survit à un arrêt et un redémarrage, mais elle est supprimée lorsque le conteneur est supprimé.

docker run -d --name db -e POSTGRES_PASSWORD=devonly postgres:17
# ... create tables and add data ...
docker rm -f db
docker run -d --name db -e POSTGRES_PASSWORD=devonly postgres:17
# The data you added is not there

C’est intentionnel, car cela vous permet de remplacer librement les conteneurs. Cela signifie que tout ce que vous devez conserver doit vivre en dehors du conteneur. Il existe trois façons de procéder :

Tapez Stocké dans Survit au retrait du conteneur ?
Volume nommé Une zone gérée par Docker Oui
Lier le support Un chemin d’hôte que vous choisissez Oui
montage tmpfs Mémoire hôte Non

Volumes Docker vs montages de liaison côte à côte

Aspect Volume nommé Lier le support
Géré par Docker Vous
Emplacement Zone de stockage de Docker N’importe quel chemin sur l’hôte
Cela dépend des dossiers hôtes ? Non Oui
Modification depuis l’hôte Maladroit de par sa conception Facile, les modifications apparaissent instantanément
Cible vide pré-remplie à partir de l’image ? Oui Non, le chemin de l’hôte le cache
Commandes Docker CLI Oui, docker volume Non
Pilotes pour le stockage distant Oui Non
Idéal pour Bases de données, données de production Code source en développement

Volumes nommés

Un volume est un stockage créé et géré par Docker. Vous l’appelez par son nom et vous n’avez pas besoin de vous soucier de l’endroit où il vit physiquement.

docker volume create pgdata

docker run -d --name db \
  -e POSTGRES_PASSWORD=devonly \
  -v pgdata:/var/lib/postgresql/data \
  postgres:17

Désormais, les fichiers de la base de données résident dans pgdata. Supprimez le conteneur et démarrez-en un nouveau avec le même volume, et vos données seront toujours là. Sous Linux, les volumes se trouvent généralement sous /var/lib/docker/volumes/, mais vous ne devez pas modifier ces fichiers directement. Sur Docker Desktop, ils vivent dans une machine virtuelle, pas dans un dossier normal.

Le chemin à l’intérieur du conteneur dépend de l’image, consultez donc la documentation de l’image. Monter sur le mauvais chemin est une erreur classique : tout semble fonctionner, mais les données sont toujours en cours d’écriture dans la couche conteneur. Les versions majeures plus récentes d’une image peuvent également modifier ce chemin, alors lisez les notes de version avant la mise à niveau.

Docker créera automatiquement un volume nommé s’il n’existe pas. Un volume anonyme, créé sans nom, fonctionne également, mais il obtient un long identifiant aléatoire et est facile à perdre de vue. Donnez toujours les noms de vos volumes.

Lier les montures

Un montage de liaison mappe un chemin d’hôte spécifique directement dans le conteneur. Les deux parties voient immédiatement les mêmes fichiers. Cela le rend parfait pour le développement, car les modifications dans votre éditeur prennent effet dans le conteneur en cours d’exécution sans reconstruction :

docker run -d --name web \
  -p 8080:80 \
  -v "$(pwd)/site:/usr/share/nginx/html:ro" \
  nginx:1.27

Modifiez un fichier dans site/, actualisez le navigateur et vous verrez le changement. Le :ro rend le montage en lecture seule à l’intérieur du conteneur, ce qui est une bonne habitude lorsque le conteneur n’a pas besoin d’y écrire.

Les montures liées comportent certains compromis :

  • Ils vous lient à l’hôte. Le chemin doit exister sur chaque machine, les configurations sont donc moins portables.
  • Ils cachent le contenu de l’image. Si vous montez sur /app, tout ce que l’image contenait devient invisible. Un exemple courant est la disparition de node_modules.
  • Ils exposent l’hôte. Un conteneur avec un montage inscriptible peut modifier ou supprimer de vrais fichiers hôtes. Ne montez jamais de chemins sensibles comme / ou le socket Docker à moins que vous ne compreniez parfaitement le risque.
  • Les performances peuvent varier. Sur Docker Desktop pour macOS et Windows, le partage de fichiers franchit les limites de la virtualisation et peut être plus lent que sous Linux.

montages tmpfs

Un montage tmpfs réside dans la mémoire de l’hôte et n’est jamais écrit dans la couche conteneur. Il disparaît lorsque le conteneur s’arrête, il convient donc aux fichiers temporaires, aux caches et aux données sensibles de courte durée :

docker run -d --tmpfs /app/cache:size=64m myapp:1.0

tmpfs est disponible sur les hôtes Linux. Il peut également accélérer les bases de données dans des environnements de test jetables, où vous ne vous souciez pas de conserver les données.

-v ou –mount ?

Les deux drapeaux fonctionnent. --mount est plus long, mais il est plus explicite, et beaucoup de gens le préfèrent dans les scripts :

# Short form
docker run -v pgdata:/var/lib/postgresql/data postgres:17

# Explicit form
docker run --mount type=volume,source=pgdata,target=/var/lib/postgresql/data postgres:17

# Bind mount, read-only
docker run --mount type=bind,source="$(pwd)"/site,target=/usr/share/nginx/html,readonly nginx:1.27

Il y a une différence significative. Avec -v, un chemin d’hôte manquant est créé pour vous sous la forme d’un dossier vide, ce qui peut masquer une faute de frappe. Avec --mount et un type de liaison, Docker signale une erreur à la place. De plus, avec -v, le côté gauche décide du type : un nom signifie un volume et un chemin signifie un montage lié. Donc -v data:/x et -v ./data:/x font des choses très différentes.

Volumes dans Docker Compose

La plupart des projets réels déclarent le stockage dans un fichier Compose. Celui-ci utilise les deux types, chacun pour son propre travail :

services:
  web:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - ./src:/app/src      # bind mount: live code
    depends_on:
      - db

  db:
    image: postgres:17
    environment:
      POSTGRES_PASSWORD: devonly
    volumes:
      - pgdata:/var/lib/postgresql/data   # named volume: data

volumes:
  pgdata:

Les volumes nommés doivent être déclarés dans la section de niveau supérieur volumes. Compose préfixe le nom réel avec le nom du projet. Consultez notre Tutoriel Docker Compose pour une présentation complète.

Astuce : docker compose down conserve les volumes nommés, mais docker compose down -v les supprime, ainsi que vos données. Soyez particulièrement prudent avec les scripts et l’historique du shell qui incluent -v.

Commandes de volume utiles

Commande Ce que ça fait
volume du docker ls Répertorie les volumes
nom de création du volume Docker Crée un volume
nom d'inspection du volume Docker Affiche les détails, y compris son emplacement
nom du volume Docker rm Supprime un volume et ses données
élaguer le volume Docker Supprime les volumes inutilisés
système docker df -v Affiche l’utilisation du disque, y compris les volumes

Vérifiez ce que prune supprimera avant de le confirmer, car cela ne peut pas être annulé. Les volumes qu’aucun conteneur n’utilise actuellement peuvent toujours contenir des données importantes.

Sauvegarder et restaurer un volume

Un volume peut être sauvegardé en exécutant un conteneur éphémère qui monte à la fois le volume et un dossier hôte :

# Back up
docker run --rm \
  -v pgdata:/data:ro \
  -v "$(pwd)":/backup \
  alpine tar czf /backup/pgdata.tar.gz -C /data .

# Restore into a new volume
docker volume create pgdata_restored
docker run --rm \
  -v pgdata_restored:/data \
  -v "$(pwd)":/backup \
  alpine tar xzf /backup/pgdata.tar.gz -C /data

Pour une base de données active, la copie de fichiers comme celui-ci peut capturer un état incohérent. Arrêtez d’abord le conteneur, ou mieux, utilisez le propre outil de la base de données, tel que pg_dump pour PostgreSQL. Et une sauvegarde que vous n’avez jamais restaurée n’est en réalité qu’un espoir, alors testez la restauration.

Autorisations de fichiers

« Autorisation refusée » est le problème le plus courant avec les montages. Les fichiers conservent leurs identifiants numériques d’utilisateur et de groupe sous Linux, donc si un conteneur s’exécute en tant qu’utilisateur 1000 et que le dossier hôte appartient à un autre utilisateur, les écritures échoueront. Quelques façons de résoudre ce problème :

  • Exécutez le conteneur avec un utilisateur correspondant : docker run --user "$(id -u):$(id -g)" ...
  • Configurez la propriété correcte de votre image, comme décrit dans nos Bonnes pratiques Dockerfile.
  • Préférez les volumes nommés pour les données, car un nouveau volume devient propriétaire du dossier de l’image lors de sa première utilisation.
  • Sur les systèmes utilisant SELinux, les montages de liaison peuvent nécessiter une étiquette :z ou :Z.

Évitez la tentation de chmod 777, comme l’explique notre guide des commandes Linux.

Lequel devriez-vous utiliser ?

Situation Utiliser
Données de la base de données Volume nommé
Code source d’édition en direct Lier le support
Un fichier de configuration de votre référentiel Montage de liaison en lecture seule
Partage de données entre conteneurs Volume nommé
Cache temporaire ou fichiers de travail tmpfs
Base de données de tests jetables tmpfs, ou pas de montage
Code d’application en production Intégrez-le à l’image

Cette dernière ligne compte. En production, le code appartient à l’image, de sorte que ce que vous avez testé correspond à ce que vous exécutez. Dans les clusters, le stockage des données fonctionne encore différemment, via des volumes persistants, qui sont traités dans la documentation plus large de Kubernetes. Notre guide Docker vs Kubernetes explique la relation entre les deux.

Erreurs courantes

  • Montage sur le mauvais chemin. Les données résident toujours dans la couche conteneur et disparaissent plus tard.
  • Exécuter down -v avec désinvolture. Cela supprime vos volumes nommés.
  • Utilisation de chemins relatifs avec -v. Des formulaires comme -v data:/x créent un volume plutôt qu’un mappage de dossiers.
  • Mettre les secrets dans des montages de liaison inscriptibles. Montez-les en lecture seule ou utilisez une fonctionnalité de secrets.
  • Pointage de deux conteneurs de base de données sur un seul volume. Cela peut corrompre les données.
  • N’avoir aucune sauvegarde. Un volume n’est pas une sauvegarde. Il vit sur le même disque.

Pour conclure

La règle générale est courte : des volumes nommés pour les données, des montages de liaison pour le code que vous modifiez et des tmpfs pour les choses qui ne devraient pas durer. Essayez-le sur une base de données jetable. Créez un volume nommé, ajoutez une ligne, supprimez le conteneur, démarrez-en un nouveau et confirmez que votre ligne a survécu. Pratiquez ensuite une sauvegarde et une restauration avant d’en avoir besoin.

Questions fréquentes

Quelle est la différence entre un volume Docker et un montage lié ?

Un volume est géré par Docker et stocké dans sa propre zone. Un montage de liaison mappe un chemin d’hôte spécifique que vous contrôlez, directement dans le conteneur.

L’arrêt d’un conteneur supprime-t-il ses données ?

Non. Les données de la couche inscriptible survivent à un arrêt et un redémarrage. Il est perdu lorsque le conteneur est supprimé, sauf s’il est stocké dans un volume ou dans un montage lié.

Les volumes Docker persistent-ils après la composition de Docker ?

Oui, les volumes nommés restent après la composition de Docker. L’ajout de l’indicateur -v les supprime, ainsi que toutes les données qu’ils contiennent.

Où sont stockés les volumes Docker ?

Sous Linux, généralement sous /var/lib/docker/volumes. Sur Docker Desktop, ils vivent dans une machine virtuelle. Utilisez Docker Volume Inspect pour voir l’emplacement.

Plusieurs conteneurs peuvent-ils partager un volume ?

Oui, plusieurs conteneurs peuvent monter un volume. L’application doit gérer les accès simultanés en toute sécurité et les bases de données ne doivent généralement pas partager des fichiers de données de cette manière.

Continuez à apprendre

Travailler avec Stack Quora

Besoin d’aide pour les tests, WordPress ou le référencement ?

Nous aidons les équipes à proposer de meilleurs logiciels et à développer leurs sites. Dites-nous sur quoi vous travaillez et nous vous proposerons une prochaine étape claire.

Continuez à lire

Plus de guides sur tests, IA et développement moderne

Vous avez apprécié cet article ? Choisissez un sujet et accédez directement à nos nouveaux didacticiels.

Intelligence artificielle

Les hallucinations de l'IA expliquées : pourquoi les modèles de langage inventent les choses et comment les réduire

Les hallucinations de l'IA ont expliqué : ce qu'elles sont, pourquoi les modèles de langage les produisent, les types courants, comment les réduire …

Lire l'article →
DevOps

Variables d'environnement expliquées : fichiers .env, secrets et configuration correctement effectués

Variables d'environnement expliquées avec des exemples Python que nous avons exécutés : lecture et définition, pourquoi chaque valeur est une chaîne…

Lire l'article →
Développement logiciel

Limitation du débit de l'API expliquée : algorithmes, en-têtes et gestion des erreurs 429

Limitation du débit de l'API expliquée avec une simulation que nous avons exécutée : compartiment de jetons, fenêtre fixe, fenêtre glissante, 429 ré…

Lire l'article →
Automatisation des tests

Se moquer en Python : unittest.mock, patch et les erreurs qui font mentir les tests

Moquerie en Python avec unittest.mock, testée : Mock et return_value, side_effect, correctifs où un nom est utilisé, spec et autospec, dates moqueus…

Lire l'article →
Tests logiciels

Couverture du code expliquée : couverture des lignes par rapport aux branches et ce que signifie réellement 100 %

Couverture du code expliquée avec une véritable exécution de cover.py : couverture des lignes, des branches et des conditions, lecture d'un rapport,…

Lire l'article →
Bases de données et SQL

DELETE vs TRUNCATE vs DROP dans SQL : différences, restauration et quand les utiliser

DELETE vs TRUNCATE vs DROP expliqué avec SQL testé : ce que chacun supprime, restauration, déclencheurs, réinitialisation d'identité, vitesse et en …

Lire l'article →
Bases de données et SQL

Vues SQL expliquées : créez, utilisez et évitez les pièges, avec des exemples

Vues SQL expliquées avec les requêtes que nous avons exécutées : création d'une vue, résultats en direct, masquage des colonnes, performances, vues …

Lire l'article →
Développement logiciel

Interface TypeScript vs Type : différences réelles, testées avec le compilateur

Interface TypeScript vs type, vérifiée avec le vrai compilateur : ce que les deux peuvent faire, ce qu'un seul peut faire, la fusion des déclaration…

Lire l'article →
Développement logiciel

Python *args et **kwargs expliqués : fonctions flexibles avec des exemples clairs

Python *args et **kwargs expliqués avec le code que nous avons exécuté : emballage et déballage, ordre des paramètres, arguments de mot-clé uniqueme…

Lire l'article →
Développement logiciel

Fonctions Python Lambda : syntaxe, utilisations réelles et quand ne pas les utiliser

Fonctions Python lambda expliquées avec le code que nous avons exécuté : syntaxe, tri avec clé, carte et filtre, fermetures, piège de liaison tardiv…

Lire l'article →
Intelligence artificielle

Que sont les agents IA ? Comment ils fonctionnent, avec une simple boucle d'agent que vous pouvez exécuter

Que sont les agents IA ? Un guide simple sur la boucle d'agent, les outils, la mémoire et les garde-fous, avec une petite boucle Python que nous avo…

Lire l'article →
DevOps

Surveillance vs observabilité : la vraie différence, avec les journaux, les métriques et les traces

Surveillance et observabilité expliquées : échecs connus et inconnus, journaux, métriques et traces, présentation pas à pas des incidents de paiemen…

Lire l'article →
DevOps

Volumes Docker vs montages Bind : conserver les données du conteneur de la bonne manière

Volumes Docker et montages de liaison expliqués : pourquoi les données du conteneur disparaissent, volumes nommés, montages de liaison, tmpfs, exemp…

Lire l'article →
Automatisation des tests

TDD vs BDD : principales différences, une fonctionnalité conçue dans les deux sens et quand les utiliser

TDD vs BDD expliqué avec une fonctionnalité de remise construite dans les deux sens : refactor rouge-vert avec le code que nous avons exécuté, scéna…

Lire l'article →
Développement logiciel

Git merge vs rebase : différences, exemples et quand utiliser chacun

Git merge vs rebase expliqué avec de vraies sorties de log, un tableau comparatif, la règle d'or du rebase et un flux de travail sûr pour les équipes.

Lire l'article →
Développement logiciel

List comprehension Python : syntaxe, exemples et cas à éviter

La list comprehension Python expliquée : syntaxe, filtres, if-else, boucles imbriquées, temps mesurés et cas où une boucle for classique est préféra…

Lire l'article →
Bases de données et SQL

Jointures SQL expliquées avec exemples (Inner, Left, Right, Full)

Comprenez les jointures SQL pas à pas avec des tables et requêtes d'exemple : INNER, LEFT, RIGHT, FULL, CROSS et SELF, plus erreurs courantes et con…

Lire l'article →