06

L'Art de la Persistance (Volumes)

Sauvegarder et partager des données vitales au-delà de la destruction

Règle #1 d'un conteneur : son système de fichier est amnésique (Éphémère). Tout fichier (log, avatar uploader, base de données Postgres) inséré pendant sa vie sera instantanément désintégré lorsque le conteneur sera supprimé ou updaté. La solution : Externaliser la mémoire.

Les 2 types de montage : DEV vs PROD

Il est critique de ne pas confondre un Bind Mount (utilisé exclusivement pour le développement local) et un Named Volume (utilisé en entreprise pour héberger des bases de données). C'est la source principale de pannes temporelles (I/O Lents sur Mac/Windows).

💻 OS Hôte (Votre PC)
C:/Projets/mon_code (Bind Mount)
/var/lib/docker/volumes/ (Named Volume)
Synchronisation Bidirectionnelle Lente
Disque Dur Virtuel Natif & Ultra Rapide
📦 Conteneur Nginx & BDD
/app/src/
/var/lib/mysql/

Comparatif : Les 3 modes de persistance

Type Vitesse (I/O) Sécurité / Portabilité Usage Typique
Bind Mount
(Dossier Utilisateur)
Lent
Faible (dépend de l'OS hôte, chemins en dur) Code source en Développement (Hot Reload instantané).
Named Volume
(Géré par Docker)
Rapide
Excellente (Natifs Linux ext4, portables) Bases de données en Production (PostgreSQL, MongoDB).
tmpfs
(Mémoire Vive / RAM)
Ultra
Totalement volative (Détruit à l'extinction) Stockage temporaire sécurisé (Clés SSH, secrets à ne pas écrire sur disque).

1. Bind Mounts (Développement Local)

On crée un trou de ver (Un pont direct) entre un dossier libre sur votre PC (ex: D:\MonCode) et un dossier dans le conteneur.
L'intérêt Magique : Modifier votre code sur VS Code met à jour le conteneur en temps réel instantanément (Hot Reload). Vous n'avez pas à re-builder une image à chaque Ctrl+S !

Terminal : Hot Reload
# Option Courte (-v hote:conteneur)
# $(pwd) injecte le chemin absolu du dossier de terminal actuel 
docker run -d -p 3000:3000 -v $(pwd):/app mon-app-node

# Syntaxe Longue Moderne (--mount). 
# Beaucoup plus explicite et refuse silencieusement de créer l'hôte s'il n'existe pas.
docker run -d \
  --mount type=bind,source=$(pwd)/src,target=/app/src \
  mon-app-node

Le Bind Mount dépend 100% l'OS système d'exploitation de l'hôte (Windows/Mac). L'IO (lecture fichier réseau vituel) y est très lente pour les milliers de petits fichiers d'une BDD. Ne jamais mettre PostgreSQL dans un Bind Mount sur Mac/Windows, votre site mettra 5 secondes à charger une page.

2. Volumes Nommés (Named Volumes - Production)

Ici, c'est le Docker Daemon lui-même qui gère physiquement l'espace de stockage sur une partition cachée et optimisée du serveur Linux (`/var/lib/docker/volumes`). C'est obligatoire en production et la norme pour les bases de données mêmes locales. Vous n'avez pas le souci de "Droits et permissions Linux" d'un dossier hôte capricieux.

Terminal (Prod Database)
# 1. Je déclare un disque dur virtuel (Le Daemon l'alloue sur l'hôte)
docker volume create bd-postgres-data

# 2. J'ordonne au serveur Postgres de stocker TOUTES ses tables sur ce volume nommé (au lieu de mourir dans son espace amnésique)
# -v nomDuVolume:cheminInterneVital
docker run -d -p 5432:5432 -v bd-postgres-data:/var/lib/postgresql/data postgres:15

# Si le conteneur crash, l'image est updatée postgres:16, ou je 'docker rm -f'
# Le volume SURVIT sur le serveur ! 

# --- La Gestion des orphelins ---
# Lister les volumes
docker volume ls
# Supprimer les volumes nommés n'étant rattachés à *aucun* conteneur vivant ! (DANGER : Purge des BDD)
docker volume prune

Cas Réel : Backup à chaud d'une Base de données

Puisque le volume appartient au bloc root du Docker Daemon protégé, on ne copie pas le dossier à la souris ! L'astuce DevOps (Backup Container Pattern) consiste à lancer un micro-conteneur éphémère d'une seconde. Il s'attache d'un côté à votre `volume nommé` (en lecture seule) et de l'autre à votre `dossier hôte local` pour `tar`/zipper le contenu localement sur votre ordinateur.

Console - 1. Créer une archive locale backup.tar.gz
# Lancement d'un conteneur Linux Alpine "jetable" (--rm)
docker run --rm \
  -v bd-postgres-data:/data:ro \
  -v $(pwd):/backup \
  alpine \
  tar czf /backup/backup.tar.gz /data

Et pour restaurer l'archive dans un nouveau volume vierge ? C'est l'inverse ! On extrait le .tar.gz local vers le dossier interne /data du volume.

Console - 2. Restauration
# On crée d'abord le nouveau volume cible
docker volume create nouveau-volume-bd

# On extrait le backup dedans (z pour gzip, x pour extract)
docker run --rm -v nouveau-volume-bd:/data -v $(pwd):/backup alpine tar xzf /backup/backup.tar.gz -C /