Comparaison des montages Docker : Volume vs Bind Mount — guide de choix (avec tests de performance)

La première fois avec Docker, le montage de données est souvent le plus déroutant. Un jour, un conteneur de test redémarre — page blanche. La base de données ? Vide. On apprend vite : un redémarrage de conteneur peut faire disparaître les données.
Vous avez peut-être déjà vécu ça :
- Vous montez un répertoire avec
-vsans savoir où vont les données - Sur Mac,
npm installtraîne interminablement - Vous voyez
--mount type=volumechez d’autres sans comprendre la différence avec-v - Vous hésitez entre Volume et Bind Mount
Tout cela vient d’une compréhension insuffisante des trois montages Docker. Aujourd’hui, comparons Volume, Bind Mount et tmpfs, avec un arbre de décision et des scénarios réels pour choisir en quelques minutes.
Bases de la gestion des données Docker
Pourquoi les données disparaissent au redémarrage ?
Fait brutal : un conteneur n’est pas fait pour stocker des données.
Imaginez un conteneur comme une boîte jetable. On jette la boîte, le contenu part avec. Même sans suppression, un simple redémarrage peut faire perdre certaines données.
D’où la persistance : placer les données importantes hors du conteneur, qui va et vient, tandis que les données restent.
-v vs --mount : quelle différence ?
Au début, ces deux paramètres me donnaient mal à la tête. Ils font à peu près la même chose, mais la syntaxe diffère.
Exemple : monter un volume sur /data :
# Méthode 1 : -v (concis, mais ambigu)
docker run -v myvolume:/data nginx
# Méthode 2 : --mount (verbeux, mais clair)
docker run --mount type=volume,source=myvolume,target=/data nginx
-v : un seul :, source à gauche, cible à droite. Simple — mais impossible de savoir si c’est un Volume ou un Bind Mount.
--mount indique explicitement type=volume. Chaque paramètre est lisible. Plus long à taper, mais six mois plus tard, la commande se comprend d’un coup d’œil.
Mon conseil : --mount en production, -v pour bricoler.
| Critère | -v | --mount |
|---|---|---|
| Syntaxe | -v source:target:options | --mount type=xxx,source=xxx,target=xxx |
| Lisibilité | 🤨 Concis mais flou | ✅ Clair |
| Volume | -v myvolume:/data | --mount type=volume,source=myvolume,target=/data |
| Bind Mount | -v /host/path:/data | --mount type=bind,source=/host/path,target=/data |
| Recommandation | Compatibilité anciennes versions | ✅ Nouveaux projets |
[Image : schéma comparatif des commandes]
Prompt : terminal screen showing docker run commands with -v and —mount side by side, modern tech style, blue and green colors, high quality
Comparaison approfondie des trois montages
Docker propose trois montages : Volume, Bind Mount et tmpfs. Chacun a son tempérament — le bon choix simplifie la vie, le mauvais crée des pièges.
Volume : laissez Docker gérer
Un Volume, c’est comme un majordome. Vous lui confiez vos données, il les range dans un endroit dédié (sous Linux : /var/lib/docker/volumes/), sans que vous ayez à vous soucier des détails.
Ce que j’apprécie : performances stables cross-plateforme. Linux, Mac ou Windows — le comportement reste similaire. Idéal en équipe, sans le classique « chez moi ça marche ».
Les Volumes se gèrent aussi via Docker :
# Créer un Volume
docker volume create my-data
# Lister tous les Volumes
docker volume ls
# Détails (où sont les données)
docker volume inspect my-data
# Sauvegarder (très simple)
docker run --rm -v my-data:/data -v $(pwd):/backup alpine tar czf /backup/backup.tar.gz /data
Quand utiliser un Volume ?
- Bases MySQL, PostgreSQL (sécurité des données)
- Données partagées entre conteneurs (répertoire d’upload)
- Données persistantes en production (sauvegarde et migration faciles)
[Image : schéma du fonctionnement d’un Volume]
Prompt : Docker volume management diagram, Docker managing storage volumes, clean infographic style, blue and white colors, high quality
Bind Mount : vous gardez la main
Le Bind Mount monte directement un répertoire de l’hôte dans le conteneur. Vous choisissez le chemin, Docker n’intervient pas.
Avantage majeur : synchronisation en temps réel. Vous modifiez le code localement, le conteneur voit le changement immédiatement. En dev, c’est idéal — modifier, rafraîchir, voir le résultat sans rebuild.
Attention Mac et Windows.
Paolo Mainardi a testé en 2025 : sur Mac, npm install via Bind Mount est 3,5× plus lent qu’avec un Volume. Pourquoi ? Docker Desktop sur Mac/Windows passe par une couche de virtualisation ; chaque accès Bind Mount traverse cette frontière — surcoût énorme.
# Bind Mount (monter le répertoire courant)
docker run -d \
--name my-app \
--mount type=bind,source=$(pwd),target=/app \
node:18
# Ou avec -v (même effet)
docker run -d --name my-app -v $(pwd):/app node:18
Quand utiliser un Bind Mount ?
- Environnement de dev local (voir les changements de code en direct)
- Fichiers de config (nginx.conf, .env)
- Logs sur l’hôte pour consultation facile
Quand l’éviter ?
- Sur Mac/Windows : ne pas monter
node_modules,vendor, etc. en Bind Mount (catastrophe de performance) - Production : prudence (forte dépendance aux chemins)
tmpfs : le post-it en mémoire
tmpfs stocke les données en RAM. Le conteneur s’arrête, tout disparaît. Utile pourtant dans certains cas.
La RAM est des dizaines à centaines de fois plus rapide que le disque. Données temporaires (cache Redis, token, session) ? Autant utiliser le stockage le plus rapide.
# tmpfs (100 Mo en mémoire)
docker run -d \
--name fast-cache \
--mount type=tmpfs,target=/cache,tmpfs-size=100M \
redis:7
Quand utiliser tmpfs ?
- Cache temporaire (pas besoin de persistance)
- Données sensibles éphémères (RAM effacée à l’arrêt)
- Exigences de performance extrêmes (analyse de logs temps réel)
Note : tmpfs fonctionne sur les conteneurs Linux ; Docker Desktop Mac/Windows ne le supporte pas.
Tableau comparatif
| Caractéristique | Volume | Bind Mount | tmpfs |
|---|---|---|---|
| Gestion | Docker | Utilisateur | Mémoire |
| Emplacement | /var/lib/docker/volumes/ | Chemin hôte libre | RAM |
| Perf. (Linux) | Élevée | Élevée | Très élevée |
| Perf. (Mac/Win) | Élevée | Faible (×3,5 plus lent) | Très élevée |
| Cross-plateforme | ✅ Parfait | ⚠️ Dépend des chemins | ⚠️ Linux seulement |
| Persistance | ✅ Oui | ✅ Oui | ❌ Temporaire |
| Sauvegarde | ✅ Simple | ⚠️ Variable | ❌ Impossible |
| Sync temps réel | ❌ Non | ✅ Oui | - |
| Cas d’usage | BDD, production | Dev, config | Cache, temporaire |
Guide de choix par scénario
Encore hésitant ? Voici un arbre de décision en trois questions :
Arbre de décision rapide
Question 1️⃣ : Les données doivent-elles persister ?
├─ Non (cache, fichiers temporaires) → tmpfs
└─ Oui → Question 2️⃣
Question 2️⃣ : Dev ou production ?
├─ Production → Volume
└─ Dev → Question 3️⃣
Question 3️⃣ : Modifications de fichiers en temps réel (code) ?
├─ Oui → Bind Mount
│ └─ Mac/Windows ? → Volume pour node_modules, etc.
└─ Non → Volume
Trop abstrait ? Quelques scénarios concrets.
Scénario 1 : base MySQL
Une base de données — perdre les données serait fatal. Volume sans hésiter.
# Conteneur MySQL (recommandé)
docker run -d \
--name mysql \
--mount type=volume,source=mysql-data,target=/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=my-secret-pw \
mysql:8.0
# Infos du Volume
docker volume inspect mysql-data
Pourquoi Volume ?
- ✅ Données sécurisées, gérées par Docker
- ✅ Sauvegarde simple (une commande)
- ✅ Performances cohérentes cross-plateforme
- ✅ Migration facile vers un autre serveur
[Image : schéma MySQL + Volume]
Prompt : MySQL database with Docker volume storage, data persistence visualization, professional tech illustration, blue and orange colors, high quality
Scénario 2 : dev Node.js (Mac)
Cas classique : voir le code en direct sur Mac, sans npm install interminable.
Approche mixte : code en Bind Mount, dépendances en Volume.
# Conteneur Node.js de dev
docker run -d \
--name my-node-app \
--mount type=bind,source=$(pwd)/src,target=/app/src \
--mount type=bind,source=$(pwd)/package.json,target=/app/package.json \
--mount type=volume,source=node-modules-cache,target=/app/node_modules \
-p 3000:3000 \
node:18 \
npm run dev
srcen Bind Mount → changements de code immédiatspackage.jsonen Bind Mount → voir les changements de dépendancesnode_modulesen Volume → éviter le piège Mac
Première exécution, installer les dépendances :
docker exec my-node-app npm install
Résultat : npm install peut être 3× plus rapide. Chez moi : 2 minutes → 40 secondes.
Scénario 3 : configuration Nginx
Modifier la config Nginx, redémarrer le conteneur — config perdue ? Bind Mount avec readonly.
# Config Nginx (lecture seule)
docker run -d \
--name nginx \
--mount type=bind,source=$(pwd)/nginx.conf,target=/etc/nginx/nginx.conf,readonly \
-p 80:80 \
nginx:latest
# Recharger sans redémarrer
docker exec nginx nginx -s reload
Pourquoi Bind Mount ?
- ✅ Config modifiée = effet immédiat
- ✅ Fichier sur l’hôte, facile à gérer
- ✅
readonlyempêche le conteneur de modifier la config
Scénario 4 : cache Redis temporaire
Redis en cache — les données sont jetables. tmpfs convient parfaitement.
# Redis avec tmpfs
docker run -d \
--name redis-cache \
--mount type=tmpfs,target=/data,tmpfs-size=512M \
-p 6379:6379 \
redis:7 \
redis-server --save ""
# --save "" désactive la persistance RDB
Pourquoi tmpfs ?
- ✅ Vitesse mémoire maximale
- ✅ Pas besoin de persistance pour un cache
- ✅ Redémarrage = vidage automatique, sémantique de cache
Attention : tmpfs Linux seulement. Docker Desktop Mac ne le supporte pas.
Scénario 5 : collecte de logs
Voir les logs sans docker logs à répétition ? Monter le répertoire de logs sur l’hôte.
docker run -d \
--name my-app \
--mount type=bind,source=$(pwd)/logs,target=/app/logs \
my-app:latest
# Consulter en temps réel sur l'hôte
tail -f logs/app.log
Logs locaux : VSCode, grep, plateforme d’analyse — à vous de choisir.
Optimisation et pièges courants
Pièges que j’ai moi-même rencontrés — les connaître à l’avance fait gagner du temps.
Piège 1 : catastrophe de performance Mac/Windows
Rappel : sur Mac, Bind Mount est 3,5× plus lent qu’un Volume. npm install en 40 s peut passer à 2 minutes.
Pourquoi ?
Docker sur Mac/Windows tourne dans une VM. Chaque lecture/écriture Bind Mount traverse la frontière VM — surcoût énorme pour node_modules et ses milliers de petits fichiers.
Solutions :
# Méthode 1 : dépendances en Volume, code en Bind Mount (recommandé)
docker run -d \
--mount type=bind,source=$(pwd)/src,target=/app/src \
--mount type=volume,source=deps,target=/app/node_modules \
node:18
# Méthode 2 : Bind Mount obligatoire → option :cached (Docker Desktop)
docker run -d -v $(pwd):/app:cached node:18
:cached indique à Docker : l’hôte fait autorité, le conteneur peut synchroniser avec retard. Moins efficace qu’un Volume pur.
Piège 2 : permissions (écriture impossible)
Très fréquent : « Permission denied » dans le conteneur.
Cause : UID du conteneur ≠ UID de l’hôte.
Vous (UID 1000) créez un répertoire monté ; le processus dans le conteneur tourne en UID 0 ou 999 — conflit de permissions.
Solutions :
# Méthode 1 : lancer avec votre UID
docker run --user $(id -u):$(id -g) \
--mount type=bind,source=$(pwd),target=/app \
node:18
# Méthode 2 : définir l'utilisateur dans le Dockerfile
FROM node:18
RUN useradd -m -u 1000 appuser
USER appuser
WORKDIR /app
Je privilégie la méthode 1. La 2 convient aux images à distribuer.
Piège 3 : chemins Windows
Sous Windows, C:\Users\... dans une commande Docker provoque des erreurs.
Syntaxe correcte :
# PowerShell (recommandé)
docker run -v ${PWD}:/app node:18
# CMD
docker run -v %cd%:/app node:18
# Git Bash
docker run -v /c/Users/yourname/project:/app node:18
# Ou double slash
docker run -v //c/Users/yourname/project:/app node:18
Perdu ? docker-compose gère souvent les chemins automatiquement.
Piège 4 : Volumes qui s’accumulent
Conteneur supprimé, Volume conservé. /var/lib/docker/volumes/ peut saturer le disque.
Nettoyage régulier :
docker volume ls
docker volume ls -f dangling=true
docker volume prune
docker system prune -a --volumes
Mon habitude : docker volume prune chaque semaine.
Piège 5 : où sont les données Volume ?
docker volume inspect my-data
# Chercher "Mountpoint" : /var/lib/docker/volumes/my-data/_data
Évitez d’éditer ce répertoire directement (permissions). Sauvegarde via Docker :
# Sauvegarder en tar
docker run --rm \
-v my-data:/source \
-v $(pwd):/backup \
alpine \
tar czf /backup/my-data-backup.tar.gz -C /source .
# Restaurer sur un nouveau Volume
docker run --rm \
-v new-data:/target \
-v $(pwd):/backup \
alpine \
tar xzf /backup/my-data-backup.tar.gz -C /target
Utile pour migrer une base de production.
[Image : flux de sauvegarde Volume]
Prompt : Docker volume backup workflow diagram, tar archive process, clean technical illustration, green and blue colors, high quality
Bonnes pratiques docker-compose
En projet réel, docker-compose est souvent préféré à docker run. Exemple complet couvrant les trois montages.
Exemple docker-compose.yml complet
Architecture type : frontend Node.js + API + PostgreSQL + Redis.
version: '3.8'
services:
# Application web (dev)
web:
image: node:18
container_name: my-web-app
working_dir: /app
command: npm run dev
ports:
- "3000:3000"
volumes:
# Code source : Bind Mount
- type: bind
source: ./src
target: /app/src
- type: bind
source: ./package.json
target: /app/package.json
# node_modules : Volume (évite le piège Mac)
- type: volume
source: node-modules
target: /app/node_modules
environment:
- NODE_ENV=development
depends_on:
- db
- cache
# Base de données
db:
image: postgres:15
container_name: postgres-db
ports:
- "5432:5432"
volumes:
- type: volume
source: postgres-data
target: /var/lib/postgresql/data
- type: bind
source: ./init.sql
target: /docker-entrypoint-initdb.d/init.sql
read_only: true
environment:
- POSTGRES_USER=myuser
- POSTGRES_PASSWORD=mypassword
- POSTGRES_DB=mydb
# Cache Redis
cache:
image: redis:7
container_name: redis-cache
ports:
- "6379:6379"
volumes:
- type: tmpfs
target: /data
tmpfs:
size: 100M
command: redis-server --save ""
# Nginx reverse proxy
nginx:
image: nginx:latest
container_name: nginx-proxy
ports:
- "80:80"
volumes:
- type: bind
source: ./nginx.conf
target: /etc/nginx/nginx.conf
read_only: true
- type: bind
source: ./logs/nginx
target: /var/log/nginx
depends_on:
- web
volumes:
node-modules:
driver: local
postgres-data:
driver: local
Points clés
Web :
srcen Bind Mount : hot reload immédiatnode_modulesen Volume : indispensable sur Macpackage.jsonen Bind Mount :npm installdans le conteneur après changement de dépendances
Base de données :
- Données en Volume : persistance production
- Script d’init en Bind Mount +
read_only: exécuté à la création uniquement
Redis :
- tmpfs : pas de persistance, vitesse mémoire
size: 100M: limite la consommation RAM
Nginx :
- Config en
read_only - Logs en Bind Mount pour
tail -fsur l’hôte
Commandes utiles
docker-compose up -d
docker-compose exec web ls -la /app/node_modules
docker-compose exec web npm install
docker-compose exec nginx nginx -s reload
docker run --rm \
-v blog-write-agent_postgres-data:/source \
-v $(pwd):/backup \
alpine tar czf /backup/db-backup.tar.gz -C /source .
docker-compose down
docker-compose down -v # supprime aussi les Volumes — attention !
Optimisation Mac/Windows
volumes:
- ./src:/app/src:cached
:cached : l’hôte prioritaire, sync différée côté conteneur. Gain de 20 à 30 %.
[Image : architecture docker-compose]
Prompt : Docker compose multi-container architecture, web app database redis nginx, professional system diagram, blue and purple gradient, high quality
Résumé
Trois montages, trois outils :
- Volume : Docker gère — fiable, stable, cross-plateforme
- Bind Mount : vous gérez — flexible, temps réel, attention aux perfs
- tmpfs : en mémoire — ultra-rapide, éphémère
Trois règles :
- Production → Volume (BDD, fichiers persistants)
- Dev → Bind Mount (modifications temps réel, hot reload)
- Temporaire → tmpfs (cache, données sensibles)
Mac/Windows :
node_modules,vendor: jamais en Bind Mount — Volume 3× plus rapide ou plus- Bind Mount obligatoire : option
:cached
Action : prenez un projet en cours, passez de docker run à docker-compose.yml, testez les trois montages. Le bon choix améliore les performances et clarifie la structure.
Des questions ? Commentez — j’ai aussi appris en trébuchant.
Guide complet pour choisir un montage Docker
Comparez Volume, Bind Mount et tmpfs, et résolvez npm install 3× plus lent sur Mac
⏱️ Estimated time: 30 min
- 1
Step 1: Comprendre les trois montages
Comparaison des trois montages :
Volume
• Géré par Docker, stocké dans le répertoire de données Docker
• Adapté à la production, npm install ×3 plus rapide sur Mac
• Bonnes performances, haute sécurité
Bind Mount
• Monte directement un répertoire de l'hôte
• Adapté au dev, modifications en temps réel
• Mais surcoût de performance sur Mac
tmpfs
• Montage en mémoire, données temporaires
• Très rapide mais perdu à la suppression du conteneur - 2
Step 2: Performance et optimisations Mac/Windows
Problème de performance :
• npm install 3× plus lent sur Mac car Bind Mount a un surcoût
• Volume peut être 3× plus rapide ou plus
• Ne montez jamais node_modules, vendor, etc. en Bind Mount
Attention Mac/Windows :
• node_modules, vendor — jamais en Bind Mount
• Volume peut être 3× plus rapide ou plus
• Si Bind Mount obligatoire, ajoutez l'option :cached
Recommandations :
• Données de prod → Volume
• Code de dev → Bind Mount
• Données temporaires → tmpfs - 3
Step 3: Arbre de décision et bonnes pratiques
Arbre de décision :
• Données de prod → Volume (persistance, sécurité)
• Code de dev → Bind Mount (modifications temps réel, hot reload)
• Données temporaires → tmpfs (cache, infos sensibles)
Bonnes pratiques :
• Données de prod → Volume
• Code de dev → Bind Mount
• Données temporaires → tmpfs
• Attention aux performances sur Mac/Windows
Action : prenez un projet en cours, convertissez docker run en docker-compose.yml, testez Volume, Bind Mount et tmpfs — le bon choix améliore les perfs et clarifie la structure.
FAQ
Quels sont les trois montages Docker et leurs caractéristiques ?
Volume :
• Géré par Docker, stocké dans le répertoire de données Docker
• Adapté à la production, npm install ×3 plus rapide sur Mac
• Bonnes performances, haute sécurité
Bind Mount :
• Monte directement un répertoire de l'hôte
• Adapté au dev, modifications en temps réel
• Mais surcoût de performance sur Mac
tmpfs :
• Montage en mémoire, données temporaires
• Très rapide mais perdu à la suppression du conteneur
Pourquoi npm install est-il 3× plus lent sur Mac ? Comment optimiser ?
• npm install 3× plus lent sur Mac car Bind Mount a un surcoût
• Volume peut être 3× plus rapide ou plus
• Ne montez jamais node_modules, vendor, etc. en Bind Mount
Attention Mac/Windows :
• node_modules, vendor — jamais en Bind Mount
• Volume peut être 3× plus rapide ou plus
• Si Bind Mount obligatoire, ajoutez l'option :cached
Recommandations :
• Données de prod → Volume
• Code de dev → Bind Mount
• Données temporaires → tmpfs
Comment choisir le montage adapté ?
• Données de prod → Volume (persistance, sécurité)
• Code de dev → Bind Mount (modifications temps réel, hot reload)
• Données temporaires → tmpfs (cache, infos sensibles)
Bonnes pratiques :
• Données de prod → Volume
• Code de dev → Bind Mount
• Données temporaires → tmpfs
• Attention aux performances sur Mac/Windows
Action : convertissez docker run en docker-compose.yml, testez les trois montages — le bon choix améliore les perfs et clarifie la structure.
11 min de lecture · Publié le: 17 déc. 2025 · Mis à jour le: 27 juil. 2026
Guide pratique Docker
Si vous arrivez depuis la recherche, le plus rapide est de passer à l’article précédent ou suivant de cette série.
Précédent
Sauvegarde et migration des volumes Docker : guide pratique en 3 méthodes
Trois méthodes de sauvegarde des volumes Docker : tar, docker cp et outils automatisés. Points d'attention pour les bases de données, flux complet de migration serveur et pièges à éviter.
Partie 15 sur 38
Suivant
Permissions Docker des répertoires montés : guide complet avec 5 solutions du diagnostic à la pratique
Impossible de supprimer les fichiers générés par le conteneur ? Permission denied à répétition ? Ce guide explique la cause profonde des problèmes de permissions Docker, propose 5 solutions, couvre les différences Linux/Mac/Windows et 5 cas réels. Maîtrisez 3 commandes de diagnostic.
Partie 17 sur 38



Commentaires
Connectez-vous avec GitHub pour laisser un commentaire