Gestion Persistante des Données : Choisir le Bon Type de Volume Docker
Comparez les volumes nommés Docker, les montages bind et les montages tmpfs pour le stockage persistant des données, le développement et le stockage temporaire.
Gestion Persistante des Données : Choisir le Bon Type de Volume Docker
Les conteneurs Docker sont conçus pour être remplaçables. Les données écrites dans la couche inscriptible du conteneur peuvent survivre à un simple arrêt/démarrage, mais elles sont liées à ce conteneur. Supprimez ou recréez le conteneur et ces données disparaissent avec lui. C'est un mauvais endroit pour les fichiers de base de données, les actifs téléchargés, les files d'attente ou tout ce que vous seriez contrarié de perdre.
Docker vous offre trois choix de montage courants : les volumes nommés, les montages bind et les montages tmpfs. Ils résolvent différents problèmes. Un conteneur Postgres de production, un conteneur de développement Node.js local et un répertoire temporaire pour les secrets temporaires ne devraient pas tous utiliser le même modèle de stockage.
Le Paysage des Mécanismes de Stockage Docker
Docker peut utiliser des pilotes de volume pour le stockage distant, mais la plupart des décisions quotidiennes se résument à ces trois types de montage gérés par le moteur Docker ou le noyau hôte.
1. Volumes Nommés : Le Standard de Production
Les volumes nommés sont le mécanisme préféré pour le stockage persistant des données dans la plupart des environnements de production. Ils sont entièrement gérés par le moteur Docker, abstraisant le chemin du système de fichiers hôte sous-jacent de l'utilisateur.
Caractéristiques et Avantages
- Persistance : Les données persistent même si le conteneur qui les a créées est supprimé.
- Portabilité : La définition du conteneur ne dépend pas d'un chemin hôte codé en dur, ce qui facilite le déplacement des déploiements entre machines.
- Gestion : Les données sont stockées dans la zone de volume de Docker, généralement sous
/var/lib/docker/volumes/sur Linux. Vous les gérez avecdocker volume ls,docker volume inspectet des tâches de sauvegarde. - Sauvegarde et Migration : Les volumes nommés sont simples à sauvegarder si vous utilisez un conteneur auxiliaire, un instantané du système de fichiers ou une sauvegarde au niveau du stockage. Pour les bases de données, préférez les outils de sauvegarde adaptés aux bases de données lorsque la cohérence est importante.
Cas d'Utilisation
- Bases de données, lorsque vous disposez également d'un véritable processus de sauvegarde et de restauration.
- État de l'application et fichiers de configuration critiques.
- Données qui doivent être partagées entre conteneurs sur le même hôte.
Exemple Pratique : Création et Attachement d'un Volume Nommé
# 1. Créer le volume
docker volume create db_storage
# 2. Exécuter un conteneur, en montant le volume sur le chemin nécessaire
docker run -d \
--name postgres_db \
-e POSTGRES_PASSWORD=securepass \
--mount source=db_storage,target=/var/lib/postgresql/data \
postgres:16
# 3. Inspecter les détails du volume
docker volume inspect db_storage
2. Montages Bind : Développement Local et Interaction avec l'Hôte
Les montages bind vous permettent de mapper un fichier ou un répertoire arbitraire depuis la machine hôte dans un conteneur. Contrairement aux volumes nommés, les montages bind reposent entièrement sur la structure de répertoire exacte de la machine hôte.
Caractéristiques et Limitations
- Mises à Jour Instantanées : Le principal avantage est la synchronisation en temps réel. Les modifications apportées sur l'hôte (par exemple, la mise à jour du code dans votre IDE) sont instantanément reflétées à l'intérieur du conteneur en cours d'exécution, ce qui les rend idéales pour les flux de travail de développement.
- Non-Portabilité : Les montages bind dépendent de l'hôte. Si le chemin hôte spécifié n'existe pas sur une autre machine, Docker peut échouer ou créer un répertoire en fonction de la syntaxe et du contexte.
- Problèmes de Permissions : La propriété et les permissions (UID/GID) causent souvent des frictions, en particulier lors de l'exécution de conteneurs en tant qu'utilisateurs non root. L'utilisateur du conteneur doit avoir les permissions de lire/écrire sur le chemin hôte.
- Risque de Sécurité : Exposer des répertoires hôtes peut être dangereux si le processus du conteneur est compromis ou si le montage est inscriptible par erreur.
Cas d'Utilisation
- Développement Local : Montage du code source pour le débogage en direct ou le rechargement à chaud.
- Fichiers de Configuration : Injection de configuration ou d'informations d'identification spécifiques de l'hôte (par exemple,
/etc/timezone). - Accès aux Ressources de l'Hôte : Montage d'un répertoire local pour la journalisation ou le diagnostic.
Exemple Pratique : Flux de Travail de Développement
Montage du répertoire de travail actuel ($(pwd)) vers le chemin source de l'application à l'intérieur du conteneur, et le définir en lecture seule pour les fichiers de configuration.
# Monter le répertoire actuel pour le développement
docker run -it --rm \
--name dev_server \
--mount type=bind,source=$(pwd)/src,target=/app/src \
--mount type=bind,source=$(pwd)/config/app.conf,target=/etc/app/app.conf,readonly \
node:22
Astuce : Utilisez toujours la syntaxe
--mount(type=bind, source=..., target=...) pour plus de clarté, surtout lorsque vous mélangez des types de volume, bien que la syntaxe plus courte-v(/chemin/hôte:/chemin/conteneur) soit encore courante pour les montages bind simples.
3. Montages Tmpfs : Stockage Haute Vitesse et Non Persistant
Les montages tmpfs stockent les données dans un stockage basé sur la mémoire. Ils sont rapides pour de nombreuses charges de travail temporaires, mais les données ne sont pas persistées sur le disque. Lorsque le conteneur s'arrête ou que le système hôte redémarre, les données sont perdues.
Caractéristiques et Limitations
- Vitesse : Généralement rapide car les données résident dans un stockage basé sur la mémoire.
- Non-Persistance : Les données sont complètement volatiles. Utile pour les données hautement sensibles qui ne doivent pas rester sur le disque.
- Limitation des Ressources : Limité par la mémoire disponible de l'hôte. Ne convient pas aux grands ensembles de données.
- Portée de la Plateforme :
tmpfsest une fonctionnalité Linux. Docker Desktop peut exécuter des conteneurs Linux dans une VM, donc le comportement n'est pas le même qu'un hôte Linux natif.
Cas d'Utilisation
- Fichiers de session temporaires ou fichiers cache qui peuvent disparaître en toute sécurité.
- Mécanismes de mise en cache (par exemple, fichiers temporaires Redis).
- Opérations sensibles à la sécurité où les artefacts doivent être détruits immédiatement après l'exécution.
Exemple Pratique : Mise en Cache de Fichiers Temporaires
# Exécuter un conteneur utilisant tmpfs pour le répertoire /app/cache
docker run -d \
--name fast_cache \
--mount type=tmpfs,destination=/app/cache,tmpfs-size=512m \
my_web_server:latest
Résumé Comparatif et Matrice de Décision
Le choix du type de volume correct dépend entièrement des besoins de persistance, de portabilité et d'accès requis.
| Caractéristique | Volumes Nommés | Montages Bind | Montages Tmpfs |
|---|---|---|---|
| Persistance | Élevée (Géré par Docker) | Élevée (Dépend du FS hôte) | Aucune (Volatile, RAM uniquement) |
| Portabilité | Excellente | Mauvaise (Dépend du chemin hôte) | N/A (Hôtes Linux uniquement) |
| Performance | Généralement bonne, dépend du stockage sous-jacent | Variable, dépend du chemin hôte et du partage du système de fichiers | Généralement la plus rapide pour les E/S temporaires |
| Emplacement des Données | Répertoire interne Docker | Répertoire hôte spécifique | Mémoire hôte (RAM) |
| Gestion | Outils CLI Docker (docker volume) |
Géré par l'OS hôte | Automatique |
| Cas d'Utilisation Principal | Données de production, bases de données, stockage partagé | Développement local, injection de configuration | Mise en cache, gestion de session, données temporaires sécurisées |
Meilleures Pratiques pour la Gestion des Données
Standardisation du Stockage Persistant
Pour la plupart des conteneurs de production mono-hôte nécessitant une persistance, les volumes nommés sont la valeur par défaut propre. Ils évitent les chemins hôtes codés en dur et facilitent la réutilisation des définitions de conteneurs. Dans les environnements orchestrés, utilisez le système de volume persistant de la plateforme au lieu de supposer qu'un volume Docker local est suffisant.
Gestion des Permissions de Fichiers
Lors de l'utilisation de montages bind, les décalages de permissions sont un casse-tête courant. Si l'utilisateur à l'intérieur du conteneur tente d'écrire sur un chemin de volume qui appartient à un utilisateur/groupe différent sur l'hôte, l'opération échouera.
Faites correspondre l'utilisateur à l'intérieur du conteneur avec la propriété des fichiers montés, ou ajustez délibérément le répertoire hôte. Évitez de résoudre tous les problèmes de permissions avec un conteneur root ; cela fonctionne jusqu'à ce qu'il crée des artefacts de construction appartenant à root sur toute une machine de développeur.
Utiliser des Montages en Lecture Seule pour la Sécurité
Si vous montez des fichiers de configuration, des ressources statiques ou des informations d'identification que le conteneur ne doit pas modifier, spécifiez toujours le volume en lecture seule. Cela empêche la suppression ou la modification accidentelle de fichiers critiques.
# Exemple de montage en lecture seule
docker run -d \
--mount type=bind,source=/etc/my_key.pem,target=/app/key.pem,readonly \
my_app
Éviter les Montages Bind Racine de l'Hôte
Il est fortement recommandé d'éviter de lier des répertoires racine sensibles ou volumineux (par exemple, -v /:/host). Cette pratique crée des vulnérabilités de sécurité importantes et peut rendre la gestion des conteneurs instable en raison d'effets secondaires imprévus.
Nettoyage des Volumes
Docker ne supprime pas automatiquement les volumes nommés lorsque les conteneurs sont supprimés. Les volumes anonymes peuvent également s'accumuler lorsque les conteneurs sont recréés à plusieurs reprises. Inspectez avant de nettoyer, en particulier sur les hôtes partagés :
docker volume ls
docker system df -v
# Supprimer les volumes locaux inutilisés après avoir vérifié qu'ils ne sont pas nécessaires
docker volume prune
La Sauvegarde et la Restauration Devraient Guider le Choix
Le type de montage n'est que la moitié de la décision. L'autre moitié est la façon dont vous restaurerez les données un mauvais jour.
Pour un volume nommé qui stocke des fichiers ordinaires, un conteneur auxiliaire peut créer une archive tar :
docker run --rm \
--mount source=db_storage,target=/data,readonly \
--mount type=bind,source=$(pwd),target=/backup \
alpine:3.20 \
tar -czf /backup/db_storage.tar.gz -C /data .
Ce modèle est acceptable pour les fichiers statiques ou les services arrêtés. Il n'est pas suffisant pour une base de données en direct à moins que la base de données ne soit dans un état cohérent. Pour Postgres, MySQL, MongoDB et systèmes similaires, utilisez des outils de sauvegarde natifs de la base de données ou des instantanés de stockage coordonnés avec la base de données. Une archive tar d'un répertoire de base de données en cours d'exécution peut ressembler à une sauvegarde et échouer lors de la restauration.
La restauration d'un volume nommé est l'idée inverse :
docker volume create db_storage_restored
docker run --rm \
--mount source=db_storage_restored,target=/data \
--mount type=bind,source=$(pwd),target=/backup,readonly \
alpine:3.20 \
tar -xzf /backup/db_storage.tar.gz -C /data
Testez cela avant d'en avoir besoin. Une stratégie de volume qui n'a jamais été restaurée n'est pas une stratégie ; c'est une supposition.
Exemples Compose pour des Projets Réels
Dans Compose, les volumes nommés sont simples et lisibles :
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: example
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
Pour le développement local, les montages bind sont généralement meilleurs car vous souhaitez que les modifications de source sur l'hôte apparaissent à l'intérieur du conteneur :
services:
app:
image: node:22
working_dir: /app
command: npm run dev
volumes:
- ./src:/app/src
- ./package.json:/app/package.json:ro
Remarquez le drapeau en lecture seule sur package.json. C'est une petite habitude, mais elle empêche un conteneur de réécrire des fichiers qu'il ne devrait que lire.
Pour tmpfs dans Compose :
services:
worker:
image: my-worker:latest
tmpfs:
- /run/secrets:size=64m
Utilisez ceci pour les données temporaires, pas pour quoi que ce soit que vous prévoyez d'inspecter après un crash.
Modes de Défaillance Courants
L'échec de stockage Docker le plus courant est le montage du mauvais chemin. Si l'application écrit dans /var/lib/mysql mais que l'image attend /var/lib/mysql/data, le conteneur fonctionne toujours et les données disparaissent toujours lorsque vous le recréez. Confirmez toujours la documentation de l'image et inspectez le conteneur en cours d'exécution :
docker inspect my_container --format '{{json .Mounts}}'
Un autre échec courant est de confondre les volumes anonymes avec les volumes nommés. Si une image déclare un VOLUME et que vous ne fournissez pas de volume nommé, Docker peut en créer un anonyme. Les données persistent, mais le nom n'est pas significatif, donc les gens les manquent lors du nettoyage ou de la migration.
Les permissions sont le prochain casse-tête. Si un répertoire monté par bind appartient à l'UID 501 sur macOS ou à l'UID 1000 sur Linux, mais que le processus du conteneur s'exécute en tant qu'UID 999, les écritures peuvent échouer. Les volumes nommés évitent souvent la confusion du chemin hôte, mais la propriété à l'intérieur du volume compte toujours. Initialisez la propriété délibérément au lieu de modifier les permissions jusqu'à ce que l'erreur disparaisse.
Enfin, rappelez-vous que les volumes Docker locaux sont locaux. Ils ne suivent pas un conteneur vers un autre hôte par eux-mêmes. Dans Swarm, Kubernetes, Nomad ou les plates-formes de conteneurs cloud, le stockage persistant nécessite des volumes adaptés à la plateforme, un stockage distant ou un service de base de données conçu pour cet environnement.
Étiquetez les volumes importants lorsque vos outils le permettent, et documentez quel service possède chacun. Une propriété claire empêche les scripts de nettoyage de supprimer des données qui semblent simplement inutilisées.
Une Règle de Décision Simple
Lorsque vous n'êtes pas sûr, demandez qui possède les données. Si Docker les possède et que le chemin hôte n'est pas significatif, utilisez un volume nommé. Si un humain ou un outil externe sur l'hôte les possède, utilisez un montage bind. Si personne ne devrait les posséder après la sortie du conteneur, utilisez tmpfs.
Cette règle couvre la plupart des cas. Un répertoire de base de données appartient au conteneur, donc un volume nommé convient. Le code source appartient au développeur, donc un montage bind convient. Un répertoire de déchiffrement temporaire pour un seul travail devrait disparaître, donc tmpfs convient. Les cas déroutants sont les téléchargements partagés, les journaux et les rapports générés. Pour ceux-ci, décidez si la plateforme de conteneurs, l'hôte ou un service de stockage externe est le véritable propriétaire avant de choisir le type de montage.
La version courte est : utilisez des volumes nommés pour les données persistantes appartenant au conteneur, des montages bind lorsque le chemin hôte lui-même fait partie du flux de travail, et tmpfs pour les données qui doivent être rapides et jetables. Ensuite, notez comment chaque volume important est sauvegardé et restauré. La persistance sans test de restauration n'est qu'un espoir avec un point de montage.