Kennisbank › Docker › Créer et lier un volume
docker starter 09 September 2026

Créer et lier un volume

Un conteneur, c'est un peu comme une session SSH : quand elle se termine, tout ce qu'elle contenait disparaît. Sauf que pour un conteneur, « tout ce qu'elle

Un conteneur, c'est un peu comme une session SSH : quand elle se termine, tout ce qu'elle contenait disparaît. Sauf que pour un conteneur, « tout ce qu'elle contenait » peut être une base de données entière.

C'est exactement le problème que résout `docker volume`. Un volume, c'est un espace de stockage géré par le démon Docker, qui survit à la suppression du conteneur qui l'utilise. La couche d'écriture d'un conteneur est jetable par conception — c'est ce qui rend les conteneurs si pratiques à recréer. Mais une base de données qui s'évapore au premier `docker rm`, ça n'a rien de pratique.

Ce guide s'adresse à ceux qui déploient des conteneurs en production ou qui veulent comprendre pourquoi leurs données disparaissent. On va parcourir les commandes de gestion, les différences entre les flags `--volume` et `--mount`, et la façon dont Docker Compose (version 2.x) gère la persistance.

Prérequis

  • Docker Engine 24.0 ou plus récent, avec le plugin Compose v2
  • Accès shell à la machine hôte
  • Droits suffisants pour exécuter `docker` (généralement via le groupe `docker`)

Créer et lier un volume

La première chose à comprendre : un volume n'appartient pas à un conteneur. Il est créé indépendamment, puis monté dans un ou plusieurs conteneurs. Cette séparation est ce qui permet à la donnée de survivre.

La commande `docker volume create` crée un volume. Sans nom spécifié, Docker génère un identifiant aléatoire — pratique pour l'automatisation, mais illisible dans `docker volume ls`. En production, nommez toujours vos volumes.

```bash docker volume create data_postgres ```

Un volume nommé `data_postgres` apparaît maintenant dans la liste. Il ne contient rien, il n'est attaché à rien. C'est un espace vide, prêt à l'emploi.

Pour l'utiliser, il faut le monter dans un conteneur. Docker propose deux flags pour ça : `--volume` (ou `-v`) et `--mount`. Le premier est plus court, le second plus explicite.

```bash docker run -d --name postgres \ -v data_postgres:/var/lib/postgresql/data \ -e POSTGRES_PASSWORD=secret \ postgres:16 ```

La syntaxe `-v data_postgres:/var/lib/postgresql/data` se lit : « monte le volume `data_postgres` sur le chemin `/var/lib/postgresql/data` dans le conteneur ». Le chemin à droite du deux-points est celui où PostgreSQL écrit ses données. Si ce chemin correspond à ce que l'application attend, la persistance fonctionne.

Le flag `--mount` fait la même chose, mais avec une syntaxe qui sépare chaque paramètre. Pour des montages simples, `--volume` suffit. Pour des options avancées comme les permissions de lecture seule, `--mount` devient nécessaire.

```bash docker run -d --name postgres \ --mount type=volume,source=data_postgres,target=/var/lib/postgresql/data,readonly \ -e POSTGRES_PASSWORD=secret \ postgres:16 ```

Notez le `readonly` à la fin. Il rend le volume en lecture seule dans ce conteneur — utile pour un conteneur de backup qui doit lire les données sans risquer de les corrompre. Ce niveau de contrôle n'existe pas avec `--volume`.

Vérifier l'état des volumes

`docker volume ls` liste tous les volumes connus du démon. La sortie montre le nom du volume, son driver (généralement `local`) et, si vous en avez défini, ses labels.

```bash docker volume ls ```

La sortie peut devenir longue quand vous accumulez des projets. Les filtres aident à y voir clair. Pour lister uniquement les volumes qui ne sont attachés à aucun conteneur :

```bash docker volume ls --filter dangling=true ```

Ces volumes « dangling » sont les restes de conteneurs supprimés. Le conteneur est parti, le volume est resté. Il prend de la place inutilement.

Pour voir le détail d'un volume précis, `docker volume inspect` affiche tout ce que le démon sait de lui : son point de montage sur l'hôte, son driver, ses labels, sa date de création.

```bash docker volume inspect data_postgres ```

La sortie JSON indique notamment le `Mountpoint`. C'est le chemin réel sur le système de fichiers de l'hôte où Docker stocke les données. Vous pouvez y accéder directement avec `sudo ls` pour vérifier que les fichiers sont bien là — pratique pour confirmer qu'une base de données écrit effectivement dans le volume.

Supprimer les volumes inutilisés

Un volume qui n'est plus référencé par aucun conteneur ne disparaît pas tout seul. Il reste sur le disque, silencieusement. `docker volume prune` supprime tous les volumes dangling d'un coup.

```bash docker volume prune ```

La commande demande une confirmation avant d'agir. Ajoutez `--force` pour la supprimer dans les scripts.

```bash docker volume prune --force ```

Attention à ce que vous faites. `prune` ne touche qu'aux volumes non utilisés, mais « non utilisé » signifie « non référencé par un conteneur existant ». Si vous avez supprimé un conteneur dont le volume contenait des données dont vous aviez encore besoin, `prune` les effacera définitivement. Il n'y a pas de corbeille pour les volumes Docker.

Pour supprimer un volume précis, `docker volume rm` fait le travail. Mais seulement si le volume n'est pas utilisé par un conteneur actif ou arrêté.

```bash docker volume rm data_postgres ```

Si un conteneur utilise encore le volume, Docker refuse avec un message d'erreur. C'est une protection contre la suppression accidentelle de données. Le flag `--force` contourne cette protection — à n'utiliser que si vous savez précisément ce que vous faites, car il peut laisser des conteneurs dans un état incohérent.

Volumes dans Docker Compose

Docker Compose ajoute une couche de déclarativité. Au lieu d'enchaîner des commandes `docker run`, on décrit l'ensemble dans un fichier `docker-compose.yml`. Les volumes s'y déclarent de la même façon.

Voici un exemple minimal avec une base PostgreSQL et un service de backup qui partage le même volume :

```yaml services: db: image: postgres:16 volumes: - db_data:/var/lib/postgresql/data environment: POSTGRES_PASSWORD: secret

backup: image: alpine:3.19 volumes: - db_data:/backup command: tar czf /backup/backup-$(date +%Y%m%d).tar.gz -C /var/lib/postgresql/data .

volumes: db_data: ```

La section `volumes:` en bas du fichier déclare le volume `db_data`. Les services `db` et `backup` le montent chacun à un endroit différent. Le service `db` écrit ses données dans `/var/lib/postgresql/data` ; le service `backup` lit le même volume monté sur `/backup`.

Lancez l'ensemble avec :

```bash docker compose up -d ```

Compose crée le volume `db_data` automatiquement s'il n'existe pas. C'est pratique, mais ça peut créer des volumes dont vous ne vouliez pas si vous faites une faute de frappe dans le nom. Pour les environnements de production, créez les volumes explicitement avec `docker volume create` avant de lancer `docker compose up`. Vous gardez ainsi le contrôle sur ce qui existe et ce qui n'existe pas.

Le piège des permissions

Un volume monté dans un conteneur appartient à l'utilisateur root de l'hôte par défaut. Si l'application dans le conteneur tourne avec un utilisateur non-root — ce qui est une bonne pratique de sécurité — elle peut ne pas avoir les droits d'écriture sur le volume.

C'est un problème classique avec les images officielles comme `postgres` ou `mysql` qui créent un utilisateur dédié. La solution la plus simple consiste à définir l'utilisateur du conteneur pour qu'il corresponde au propriétaire du volume sur l'hôte. Concrètement, si le volume appartient à l'UID 1000 sur l'hôte, lancez le conteneur avec cet UID :

```bash docker run -d --name postgres \ --user 1000:1000 \ -v data_postgres:/var/lib/postgresql/data \ -e POSTGRES_PASSWORD=secret \ postgres:16 ```

Trouver le bon UID demande parfois un peu de recherche. `docker volume inspect` indique le mountpoint sur l'hôte ; un `sudo ls -n` sur ce chemin révèle le propriétaire actuel. C'est moins élégant qu'un fichier de configuration, mais ça fonctionne.

Ce que les volumes ne sont pas

Les volumes ne sont pas des bind mounts. Un bind mount référence directement un chemin du système de fichiers hôte :

```bash docker run -d --name nginx -v /var/www/html:/usr/share/nginx/html nginx:1.25 ```

Ici, le dossier `/var/www/html` de l'hôte est monté tel quel dans le conteneur. Pas de gestion par Docker, pas d'abstraction. Ça fonctionne, mais ça lie votre conteneur à une structure de répertoires spécifique de la machine hôte. Sur une autre machine, le chemin n'existe peut-être pas, et votre conteneur ne démarrera pas.

Les volumes, eux, sont gérés par Docker. Leur emplacement sur l'hôte est décidé par le démon, pas par vous. C'est moins transparent, mais beaucoup plus portable : un volume suit son conteneur, où qu'il soit déployé.

Le nettoyage régulier

Les volumes s'accumulent. Chaque `docker compose down` sans `-v` laisse les volumes derrière lui. Chaque conteneur supprimé sans suppression de volume laisse un volume dangling.

Mettez en place une routine. Une fois par semaine, listez les volumes dangling et décidez ce qui mérite de rester :

```bash docker volume ls --filter dangling=true ```

Si la liste est vide, tout va bien. Si elle contient des volumes dont vous ne reconnaissez pas les noms, vérifiez leur contenu avant de les supprimer. Un volume de base de données de production ressemble à n'importe quel autre volume au premier coup d'œil.

← Terug naar kennisbank
← Terug naar kennisbank