Aller au contenu principal

Volumes Docker


Objectifs du chapitre

  • Comprendre la persistance des données dans Docker
  • Maîtriser les différents types de volumes
  • Gérer les volumes efficacement
  • Partager des données entre conteneurs

1 - Pourquoi les volumes ?

Le problème de l'éphémérité

Par défaut, les données d'un conteneur sont perdues à sa suppression :

# 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 !

Les solutions

┌─────────────────────────────────────────────────────────────┐
│ Options de stockage │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Volumes │ │ Bind Mounts │ │ tmpfs │ │
│ │ (Géré par │ │ (Dossier │ │ (Mémoire RAM) │ │
│ │ Docker) │ │ hôte) │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

2 - Types de stockage

Comparaison

TypeEmplacementGestionUsage
Volume/var/lib/docker/volumes/DockerProduction, données persistantes
Bind mountN'importe où sur l'hôteUtilisateurDéveloppement, configs
tmpfsMémoire RAMDockerDonnées temporaires sensibles

Schéma

┌─────────────────────────────────────────────────────────────┐
│ Conteneur │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ /app/data │ │
│ └────────────────────────┬────────────────────────────┘ │
└───────────────────────────┼─────────────────────────────────┘

┌───────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ Volume │ │ Bind Mount │ │ tmpfs │
│ /var/lib/ │ │ /home/user/ │ │ (RAM) │
│ docker/vol/ │ │ project/data │ │ │
└───────────────┘ └───────────────┘ └───────────────┘

3 - Volumes Docker

Créer un 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

Lister les 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}}"

Inspecter un 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"
}

Supprimer des 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 - Utiliser les volumes

Syntaxe avec -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

Syntaxe avec --mount (recommandée)

# 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

Exemples pratiques

# 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

Syntaxe

# 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

Cas d'usage : développement

# 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

Différences avec les volumes

AspectVolumeBind Mount
EmplacementGéré par DockerSpécifié par l'utilisateur
PortabilitéExcellentDépend du chemin hôte
PerformanceOptimiséeVariable
BackupVia DockerManuel
SécuritéMeilleure isolationAccès au système hôte

6 - tmpfs Mounts

Usage

Le tmpfs stocke les données en mémoire RAM :

# 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

Cas d'usage

  • Données sensibles (secrets, tokens)
  • Cache temporaire
  • Fichiers de session
  • Données qui ne doivent pas persister
# Stocker des secrets temporairement
docker run -d \
--name secure-app \
--mount type=tmpfs,target=/run/secrets \
mon-app

7 - Partager des données entre conteneurs

Volumes partagés

# 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 et restauration

Sauvegarder un 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/

Restaurer un 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

Script de backup automatisé

#!/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 dans Dockerfile

Instruction VOLUME

FROM node:18

WORKDIR /app

# Déclarer un volume
VOLUME /app/data
VOLUME ["/app/logs", "/app/uploads"]

COPY . .

CMD ["node", "server.js"]

Comportement

# Un volume anonyme est créé automatiquement
docker run mon-app

# Lister les volumes anonymes
docker volume ls
# DRIVER VOLUME NAME
# local abc123def456...
Attention

Les VOLUME dans le Dockerfile créent des volumes anonymes difficiles à gérer. Préférez les volumes nommés au runtime.


10 - Bonnes pratiques

Nommage

# ✅ 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

Sécurité

# 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

Nettoyage régulier

# 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

Résumé

CommandeDescription
docker volume createCréer un volume
docker volume lsLister les volumes
docker volume inspectDétails d'un volume
docker volume rmSupprimer un volume
docker volume pruneNettoyer les volumes inutilisés
-v ou --mountMonter un volume
TypeUsage recommandé
VolumeDonnées de production
Bind mountDéveloppement
tmpfsDonnées temporaires/sensibles
Points clés
  • Les volumes persistent après suppression des conteneurs
  • Utilisez --mount pour une syntaxe claire
  • Nommez vos volumes de manière descriptive
  • Sauvegardez régulièrement vos volumes critiques

Exercices pratiques

  1. Créez un volume et utilisez-le avec un conteneur MySQL
  2. Montez un dossier local pour le développement d'une app Node.js
  3. Partagez un volume entre deux conteneurs
  4. Effectuez un backup et une restauration d'un volume

← Dockerfile | Réseaux Docker →