Docker Volumes
Chapter objectivesβ
- Understand data persistence in Docker
- Master the different volume types
- Manage volumes effectively
- Share data between containers
1 - Why volumes?β
The ephemerality problemβ
By default, a container's data is lost when it is deleted:
# CrΓ©er un fichier dans un conteneur
docker run -it --name test ubuntu bash
echo "Hello" > /data.txt
exit
# RedΓ©marrer le conteneur - fichier prΓ©sent
docker start -i test
cat /data.txt # Hello
# Supprimer le conteneur - fichier perdu !
docker rm test
docker run -it ubuntu cat /data.txt # Erreur !
The solutionsβ
ββββββββββββββββββββββββββββββββββββββββββββββββ βββββββββββββββ
β Options de stockage β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββ βββββββββββββββ βββββββββββββββββββββββ β
β β Volumes β β Bind Mounts β β tmpfs β β
β β (GΓ©rΓ© par β β (Dossier β β (MΓ©moire RAM) β β
β β Docker) β β hΓ΄te) β β β β
β βββββββββββββββ βββββββββββββββ βββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2 - Storage typesβ
Comparisonβ
| Type | Location | Management | Usage |
|---|---|---|---|
| Volume | /var/lib/docker/volumes/ | Docker | Production, persistent data |
| Bind mount | Anywhere on the host | User | Development, configs |
| tmpfs | RAM memory | Docker | Sensitive temporary data |
Diagramβ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Conteneur β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β /app/data β β
β ββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββΌββββββββββββββββββββ
β β β
βΌ βΌ βΌ
βββββββββββββββββ βββββββββββββββββ βββββββββββββββββ
β Volume β β Bind Mount β β tmpfs β
β /var/lib/ β β /home/user/ β β (RAM) β
β docker/vol/ β β project/data β β β
βββββββββββββββββ βββββββββββββββββ βββββββββββββββββ
3 - Docker Volumesβ
Create a volumeβ
# CrΓ©er un volume
docker volume create mon-volume
# CrΓ©er avec options
docker volume create --driver local \
--opt type=none \
--opt device=/path/to/data \
--opt o=bind \
mon-volume
List the volumesβ
# Lister tous les volumes
docker volume ls
# Filtrer
docker volume ls --filter "dangling=true"
docker volume ls --filter "driver=local"
# Format personnalisΓ©
docker volume ls --format "{{.Name}}: {{.Driver}}"
Inspect a volumeβ
# DΓ©tails d'un volume
docker volume inspect mon-volume
# Sortie JSON
{
"Name": "mon-volume",
"Driver": "local",
"Mountpoint": "/var/lib/docker/volumes/mon-volume/_data",
"Labels": {},
"Scope": "local"
}
Delete volumesβ
# Supprimer un volume
docker volume rm mon-volume
# Supprimer plusieurs volumes
docker volume rm vol1 vol2 vol3
# Supprimer les volumes non utilisΓ©s
docker volume prune
# Forcer la suppression
docker volume prune -f
4 - Use volumesβ
Syntax with -vβ
# Volume nommΓ©
docker run -v mon-volume:/app/data nginx
# Volume anonyme
docker run -v /app/data nginx
# Mode lecture seule
docker run -v mon-volume:/app/data:ro nginx
Syntax with --mount (recommended)β
# Volume nommΓ©
docker run --mount source=mon-volume,target=/app/data nginx
# Avec options
docker run --mount type=volume,source=mon-volume,target=/app/data,readonly nginx
# Volume anonyme
docker run --mount type=volume,target=/app/data nginx
Practical examplesβ
# Base de donnΓ©es PostgreSQL avec volume
docker run -d \
--name postgres \
-e POSTGRES_PASSWORD=secret \
--mount source=pg-data,target=/var/lib/postgresql/data \
postgres:15
# Les donnΓ©es survivent Γ la suppression du conteneur
docker rm -f postgres
docker run -d \
--name postgres-new \
-e POSTGRES_PASSWORD=secret \
--mount source=pg-data,target=/var/lib/postgresql/data \
postgres:15
# Les donnΓ©es sont prΓ©servΓ©es !
5 - Bind Mountsβ
Syntaxβ
# Avec -v
docker run -v /chemin/hote:/chemin/conteneur nginx
docker run -v $(pwd)/html:/usr/share/nginx/html nginx
# Avec --mount
docker run --mount type=bind,source=/chemin/hote,target=/chemin/conteneur nginx
# Lecture seule
docker run --mount type=bind,source=$(pwd)/config,target=/etc/nginx,readonly nginx
Use case: developmentβ
# Monter le code source pour le hot-reload
docker run -d \
--name dev-app \
-p 3000:3000 \
-v $(pwd)/src:/app/src \
-v $(pwd)/package.json:/app/package.json \
node:18 npm run dev
# Les modifications du code sont reflΓ©tΓ©es immΓ©diatement
Differences with volumesβ
| Aspect | Volume | Bind Mount |
|---|---|---|
| Location | Managed by Docker | Specified by the user |
| Portability | Excellent | Depends on the host path |
| Performance | Optimized | Variable |
| Backup | Via Docker | Manual |
| Security | Better isolation | Access to the host system |
6 - tmpfs Mountsβ
Usageβ
tmpfs stores data in RAM memory:
# CrΓ©er un tmpfs mount
docker run --mount type=tmpfs,target=/app/temp nginx
# Avec options
docker run --mount type=tmpfs,target=/app/temp,tmpfs-size=100m,tmpfs-mode=1777 nginx
Use casesβ
- Sensitive data (secrets, tokens)
- Temporary cache
- Session files
- Data that should not persist
# Stocker des secrets temporairement
docker run -d \
--name secure-app \
--mount type=tmpfs,target=/run/secrets \
mon-app
7 - Share data between containersβ
Shared volumesβ
# Conteneur 1 : Γ©crit des donnΓ©es
docker run -d \
--name writer \
--mount source=shared-data,target=/data \
alpine sh -c "while true; do date >> /data/log.txt; sleep 1; done"
# Conteneur 2 : lit les donnΓ©es
docker run -it \
--name reader \
--mount source=shared-data,target=/data,readonly \
alpine tail -f /data/log.txt
Volumes-from (legacy)β
# CrΓ©er un conteneur avec des volumes
docker run -d --name data-container -v /data alpine sleep infinity
# Utiliser les volumes d'un autre conteneur
docker run --volumes-from data-container alpine ls /data
8 - Backup and restoreβ
Back up a volumeβ
# MΓ©thode 1 : tar dans un conteneur temporaire
docker run --rm \
-v mon-volume:/source:ro \
-v $(pwd):/backup \
alpine tar cvf /backup/mon-volume-backup.tar -C /source .
# MΓ©thode 2 : docker cp (depuis un conteneur)
docker cp mon-conteneur:/app/data ./backup/
Restore a volumeβ
# CrΓ©er le volume
docker volume create mon-volume-restored
# Restaurer depuis le backup
docker run --rm \
-v mon-volume-restored:/target \
-v $(pwd):/backup \
alpine tar xvf /backup/mon-volume-backup.tar -C /target
Automated backup scriptβ
#!/bin/bash
# backup-volumes.sh
BACKUP_DIR="/backups/docker"
DATE=$(date +%Y%m%d_%H%M%S)
for volume in $(docker volume ls -q); do
echo "Backing up $volume..."
docker run --rm \
-v $volume:/source:ro \
-v $BACKUP_DIR:/backup \
alpine tar cvf /backup/${volume}_${DATE}.tar -C /source .
done
# Nettoyer les backups de plus de 7 jours
find $BACKUP_DIR -name "*.tar" -mtime +7 -delete
9 - Volumes in a Dockerfileβ
The VOLUME instructionβ
FROM node:18
WORKDIR /app
# DΓ©clarer un volume
VOLUME /app/data
VOLUME ["/app/logs", "/app/uploads"]
COPY . .
CMD ["node", "server.js"]
Behaviorβ
# Un volume anonyme est créé automatiquement
docker run mon-app
# Lister les volumes anonymes
docker volume ls
# DRIVER VOLUME NAME
# local abc123def456...
Warning
VOLUME instructions in the Dockerfile create anonymous volumes that are hard to manage. Prefer named volumes at runtime.
10 - Best practicesβ
Namingβ
# β
Bon : noms descriptifs
docker volume create postgres-data
docker volume create app-uploads
docker volume create nginx-logs
# β Mauvais : noms gΓ©nΓ©riques
docker volume create data
docker volume create vol1
Securityβ
# Lecture seule quand possible
docker run --mount source=config,target=/etc/app,readonly mon-app
# Utilisateur non-root
docker run -u 1000:1000 --mount source=data,target=/app/data mon-app
Performanceβ
# Utiliser des volumes pour les donnΓ©es frΓ©quemment accΓ©dΓ©es
# (meilleure performance que bind mounts sur macOS/Windows)
# Pour le dΓ©veloppement sur macOS
docker run -v mycode:/app:cached node:18 npm run dev
Regular cleanupβ
# Identifier les volumes orphelins
docker volume ls -f dangling=true
# Nettoyer
docker volume prune
# VΓ©rifier l'espace utilisΓ©
docker system df -v | grep VOLUME -A 100
Summaryβ
| Command | Description |
|---|---|
docker volume create | Create a volume |
docker volume ls | List the volumes |
docker volume inspect | Volume details |
docker volume rm | Delete a volume |
docker volume prune | Clean up unused volumes |
-v or --mount | Mount a volume |
| Type | Recommended usage |
|---|---|
| Volume | Production data |
| Bind mount | Development |
| tmpfs | Temporary/sensitive data |
Key points
- Volumes persist after containers are deleted
- Use
--mountfor a clear syntax - Name your volumes descriptively
- Regularly back up your critical volumes
Hands-on exercisesβ
- Create a volume and use it with a MySQL container
- Mount a local folder for developing a Node.js app
- Share a volume between two containers
- Perform a backup and restore of a volume