Volumes
Les volumes sont des magasins de données persistants pour les conteneurs, créés et gérés par
Docker. Vous pouvez créer un volume explicitement en utilisant la commande docker volume create
,
ou Docker peut créer un volume pendant la création du conteneur ou du service.
Lorsque vous créez un volume, il est stocké dans un répertoire sur l'hôte Docker. Lorsque vous montez le volume dans un conteneur, ce répertoire est ce qui est monté dans le conteneur. Ceci est similaire à la façon dont fonctionnent les montages bind, sauf que les volumes sont gérés par Docker et sont isolés de la fonctionnalité centrale de la machine hôte.
Quand utiliser les volumes
Les volumes sont le mécanisme préféré pour persister les données générées par et utilisées par les conteneurs Docker. Bien que les montages bind dépendent de la structure de répertoire et du système d'exploitation de la machine hôte, les volumes sont complètement gérés par Docker. Les volumes sont un bon choix pour les cas d'usage suivants :
- Les volumes sont plus faciles à sauvegarder ou migrer que les montages bind.
- Vous pouvez gérer les volumes en utilisant les commandes CLI Docker ou l'API Docker.
- Les volumes fonctionnent sur les conteneurs Linux et Windows.
- Les volumes peuvent être partagés plus sûrement entre plusieurs conteneurs.
- Les nouveaux volumes peuvent avoir leur contenu pré-rempli par un conteneur ou une construction.
- Lorsque votre application nécessite des E/S haute performance.
Les volumes ne sont pas un bon choix si vous devez accéder aux fichiers depuis l'hôte, car le volume est complètement géré par Docker. Utilisez les montages bind si vous devez accéder aux fichiers ou répertoires depuis les conteneurs et l'hôte.
Les volumes sont souvent un meilleur choix que l'écriture de données directement dans un conteneur, car un volume n'augmente pas la taille des conteneurs qui l'utilisent. L'utilisation d'un volume est également plus rapide ; l'écriture dans la couche modifiable d'un conteneur nécessite un pilote de stockage pour gérer le système de fichiers. Le pilote de stockage fournit un système de fichiers union, utilisant le noyau Linux. Cette abstraction supplémentaire réduit les performances par rapport à l'utilisation des volumes, qui écrivent directement dans le système de fichiers de l'hôte.
Si votre conteneur génère des données d'état non persistantes, envisagez d'utiliser un montage tmpfs pour éviter de stocker les données de manière permanente, et pour augmenter les performances du conteneur en évitant d'écrire dans la couche modifiable du conteneur.
Les volumes utilisent la propagation de liaison rprivate
(privée récursive), et la propagation de liaison n'est
pas configurable pour les volumes.
Cycle de vie d'un volume
Le contenu d'un volume existe en dehors du cycle de vie d'un conteneur donné. Lorsqu'un conteneur est détruit, la couche modifiable est détruite avec lui. L'utilisation d'un volume assure que les données persistent même si le conteneur qui l'utilise est supprimé.
Un volume donné peut être monté dans plusieurs conteneurs simultanément. Lorsqu'aucun
conteneur en cours d'exécution n'utilise un volume, le volume est toujours disponible pour Docker
et n'est pas supprimé automatiquement. Vous pouvez supprimer les volumes inutilisés en utilisant docker volume prune
.
Montage d'un volume sur des données existantes
Si vous montez un volume non vide dans un répertoire du conteneur dans lequel
des fichiers ou répertoires existent, les fichiers préexistants sont obscurcis par le montage.
Ceci est similaire à si vous deviez enregistrer des fichiers dans /mnt
sur un hôte Linux, et
ensuite monter une clé USB dans /mnt
. Le contenu de /mnt
serait obscurci
par le contenu de la clé USB jusqu'à ce que la clé USB soit démontée.
Avec les conteneurs, il n'y a pas de moyen simple de supprimer un montage pour révéler les fichiers obscurcis à nouveau. Votre meilleure option est de recréer le conteneur sans le montage.
Si vous montez un volume vide dans un répertoire du conteneur dans lequel des fichiers ou répertoires existent, ces fichiers ou répertoires sont propagés (copiés) dans le volume par défaut. De même, si vous démarrez un conteneur et spécifiez un volume qui n'existe pas déjà, un volume vide est créé pour vous. C'est un bon moyen de pré-remplir des données dont un autre conteneur a besoin.
Pour empêcher Docker de copier les fichiers préexistants d'un conteneur dans un volume
vide, utilisez l'option volume-nocopy
, voir Options pour --mount.
Volumes nommés et anonymes
Un volume peut être nommé ou anonyme. Les volumes anonymes reçoivent un nom aléatoire
qui est garanti être unique dans un hôte Docker donné. Tout comme les volumes
nommés, les volumes anonymes persistent même si vous supprimez le conteneur qui les utilise,
sauf si vous utilisez le drapeau --rm
lors de la création du conteneur, auquel
cas le volume anonyme associé au conteneur est détruit. Voir
Supprimer les volumes anonymes.
Si vous créez plusieurs conteneurs consécutivement qui utilisent chacun des volumes anonymes, chaque conteneur crée son propre volume. Les volumes anonymes ne sont pas réutilisés ou partagés entre conteneurs automatiquement. Pour partager un volume anonyme entre deux ou plusieurs conteneurs, vous devez monter le volume anonyme en utilisant l'ID de volume aléatoire.
Syntaxe
Pour monter un volume avec la commande docker run
, vous pouvez utiliser soit le
drapeau --mount
soit --volume
.
$ docker run --mount type=volume,src=<nom-volume>,dst=<chemin-montage>
$ docker run --volume <nom-volume>:<chemin-montage>
En général, --mount
est préféré. La principale différence est que le drapeau --mount
est plus explicite et prend en charge toutes les options disponibles.
Vous devez utiliser --mount
si vous voulez :
- Spécifier options de pilote de volume
- Monter un sous-répertoire de volume
- Monter un volume dans un service Swarm
Options pour --mount
Le drapeau --mount
se compose de plusieurs paires clé-valeur, séparées par des virgules
et chacune constituée d'un tuple <clé>=<valeur>
. L'ordre des clés n'est pas
significatif.
$ docker run --mount type=volume[,src=<nom-volume>],dst=<chemin-montage>[,<clé>=<valeur>...]
Les options valides pour --mount type=volume
incluent :
Option | Description |
---|---|
source , src |
La source du montage. Pour les volumes nommés, c'est le nom du volume. Pour les volumes anonymes, ce champ est omis. |
destination , dst , target |
Le chemin où le fichier ou répertoire est monté dans le conteneur. |
volume-subpath |
Un chemin vers un sous-répertoire dans le volume à monter dans le conteneur. Le sous-répertoire doit exister dans le volume avant que le volume soit monté dans un conteneur. Voir Monter un sous-répertoire de volume. |
readonly , ro |
Si présent, fait que le volume est monté dans le conteneur en lecture seule. |
volume-nocopy |
Si présent, les données à la destination ne sont pas copiées dans le volume si le volume est vide. Par défaut, le contenu à la destination cible est copié dans un volume monté s'il est vide. |
volume-opt |
Peut être spécifié plus d'une fois, prend une paire clé-valeur constituée du nom de l'option et de sa valeur. |
$ docker run --mount type=volume,src=monvolume,dst=/data,ro,volume-subpath=/foo
Options pour --volume
Le drapeau --volume
ou -v
se compose de trois champs, séparés par des caractères
deux-points (:
). Les champs doivent être dans le bon ordre.
$ docker run -v [<nom-volume>:]<chemin-montage>[:opts]
Dans le cas des volumes nommés, le premier champ est le nom du volume, et est unique sur une machine hôte donnée. Pour les volumes anonymes, le premier champ est omis. Le deuxième champ est le chemin où le fichier ou répertoire est monté dans le conteneur.
Le troisième champ est optionnel, et est une liste d'options séparées par des virgules. Les
options valides pour --volume
avec un volume de données incluent :
Option | Description |
---|---|
readonly , ro |
Si présent, fait que le volume est monté dans le conteneur en lecture seule. |
volume-nocopy |
Si présent, les données à la destination ne sont pas copiées dans le volume si le volume est vide. Par défaut, le contenu à la destination cible est copié dans un volume monté s'il est vide. |
$ docker run -v monvolume:/data:ro
Créer et gérer des volumes
Contrairement à un montage bind, vous pouvez créer et gérer des volumes en dehors de la portée de tout conteneur.
Créer un volume :
$ docker volume create my-vol
Lister les volumes :
$ docker volume ls
local my-vol
Inspecter un volume :
$ docker volume inspect my-vol
[
{
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
"Name": "my-vol",
"Options": {},
"Scope": "local"
}
]
Supprimer un volume :
$ docker volume rm my-vol
Démarrer un conteneur avec un volume
Si vous démarrez un conteneur avec un volume qui n'existe pas encore, Docker crée
le volume pour vous. L'exemple suivant monte le volume myvol2
dans
/app/
dans le conteneur.
Les exemples -v
et --mount
suivants produisent le même résultat. Vous ne pouvez pas
les exécuter tous les deux à moins de supprimer le conteneur devtest
et le volume myvol2
après avoir exécuté le premier.
$ docker run -d \
--name devtest \
--mount source=myvol2,target=/app \
nginx:latest
$ docker run -d \
--name devtest \
-v myvol2:/app \
nginx:latest
Utilisez docker inspect devtest
pour vérifier que Docker a créé le volume et qu'il est monté
correctement. Regardez la section Mounts
:
"Mounts": [
{
"Type": "volume",
"Name": "myvol2",
"Source": "/var/lib/docker/volumes/myvol2/_data",
"Destination": "/app",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
Cela montre que le montage est un volume, cela montre la source et la destination correctes, et que le montage est en lecture-écriture.
Arrêtez le conteneur et supprimez le volume. Notez que la suppression du volume est une étape séparée.
$ docker container stop devtest
$ docker container rm devtest
$ docker volume rm myvol2
Utiliser un volume avec Docker Compose
L'exemple suivant montre un seul service Docker Compose avec un volume :
services:
frontend:
image: node:lts
volumes:
- myapp:/home/node/app
volumes:
myapp:
Exécuter docker compose up
pour la première fois crée un volume. Docker réutilise le même volume lorsque vous exécutez la commande par la suite.
Vous pouvez créer un volume directement en dehors de Compose en utilisant docker volume create
et
ensuite le référencer dans compose.yaml
comme suit :
services:
frontend:
image: node:lts
volumes:
- myapp:/home/node/app
volumes:
myapp:
external: true
Pour plus d'informations sur l'utilisation des volumes avec Compose, consultez la section Volumes dans la spécification Compose.
Démarrer un service avec des volumes
Lorsque vous démarrez un service et définissez un volume, chaque conteneur de service utilise son propre
volume local. Aucun des conteneurs ne peut partager ces données si vous utilisez le pilote de
volume local
. Cependant, certains pilotes de volume supportent le stockage partagé.
L'exemple suivant démarre un service nginx
avec quatre répliques, chacune utilisant
un volume local appelé myvol2
.
$ docker service create -d \
--replicas=4 \
--name devtest-service \
--mount source=myvol2,target=/app \
nginx:latest
Utilisez docker service ps devtest-service
pour vérifier que le service fonctionne :
$ docker service ps devtest-service
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
4d7oz1j85wwn devtest-service.1 nginx:latest moby Running Running 14 seconds ago
Vous pouvez supprimer le service pour arrêter les tâches en cours d'exécution :
$ docker service rm devtest-service
Supprimer le service ne supprime aucun volume créé par le service. La suppression de volume est une étape séparée.
Peupler un volume en utilisant un conteneur
Si vous démarrez un conteneur qui crée un nouveau volume, et que le conteneur
a des fichiers ou répertoires dans le répertoire à monter tel que /app/
,
Docker copie le contenu du répertoire dans le volume. Le conteneur monte ensuite
et utilise le volume, et les autres conteneurs qui utilisent le volume ont également
accès au contenu pré-rempli.
Pour le démontrer, l'exemple suivant démarre un conteneur nginx
et
peuple le nouveau volume nginx-vol
avec le contenu du répertoire
/usr/share/nginx/html
du conteneur. C'est là que Nginx stocke son contenu HTML
par défaut.
Les exemples --mount
et -v
ont le même résultat final.
$ docker run -d \
--name=nginxtest \
--mount source=nginx-vol,destination=/usr/share/nginx/html \
nginx:latest
$ docker run -d \
--name=nginxtest \
-v nginx-vol:/usr/share/nginx/html \
nginx:latest
Après avoir exécuté l'un de ces exemples, exécutez les commandes suivantes pour nettoyer les conteneurs et volumes. Notez que la suppression de volume est une étape séparée.
$ docker container stop nginxtest
$ docker container rm nginxtest
$ docker volume rm nginx-vol
Utiliser un volume en lecture seule
Pour certaines applications de développement, le conteneur doit écrire dans le montage
bind afin que les changements soient propagés vers l'hôte Docker. À d'autres moments,
le conteneur n'a besoin que d'un accès en lecture aux données. Plusieurs
conteneurs peuvent monter le même volume. Vous pouvez simultanément monter un
seul volume en lecture-écriture
pour certains conteneurs et en lecture seule
pour d'autres.
L'exemple suivant modifie le précédent. Il monte le répertoire comme un volume
en lecture seule, en ajoutant ro
à la liste d'options (vide par défaut), après le
point de montage dans le conteneur. Lorsque plusieurs options sont présentes, vous pouvez les séparer
en utilisant des virgules.
Les exemples --mount
et -v
ont le même résultat.
$ docker run -d \
--name=nginxtest \
--mount source=nginx-vol,destination=/usr/share/nginx/html,readonly \
nginx:latest
$ docker run -d \
--name=nginxtest \
-v nginx-vol:/usr/share/nginx/html:ro \
nginx:latest
Use docker inspect nginxtest
to verify that Docker created the read-only mount
correctly. Look for the Mounts
section:
"Mounts": [
{
"Type": "volume",
"Name": "nginx-vol",
"Source": "/var/lib/docker/volumes/nginx-vol/_data",
"Destination": "/usr/share/nginx/html",
"Driver": "local",
"Mode": "",
"RW": false,
"Propagation": ""
}
],
Stop and remove the container, and remove the volume. Volume removal is a separate step.
$ docker container stop nginxtest
$ docker container rm nginxtest
$ docker volume rm nginx-vol
Mount a volume subdirectory
When you mount a volume to a container, you can specify a subdirectory of the
volume to use, with the volume-subpath
parameter for the --mount
flag. The
subdirectory that you specify must exist in the volume before you attempt to
mount it into a container; if it doesn't exist, the mount fails.
Specifying volume-subpath
is useful if you only want to share a specific
portion of a volume with a container. Say for example that you have multiple
containers running and you want to store logs from each container in a shared
volume. You can create a subdirectory for each container in the shared volume,
and mount the subdirectory to the container.
The following example creates a logs
volume and initiates the subdirectories
app1
and app2
in the volume. It then starts two containers and mounts one
of the subdirectories of the logs
volume to each container. This example
assumes that the processes in the containers write their logs to
/var/log/app1
and /var/log/app2
.
$ docker volume create logs
$ docker run --rm \
--mount src=logs,dst=/logs \
alpine mkdir -p /logs/app1 /logs/app2
$ docker run -d \
--name=app1 \
--mount src=logs,dst=/var/log/app1,volume-subpath=app1 \
app1:latest
$ docker run -d \
--name=app2 \
--mount src=logs,dst=/var/log/app2,volume-subpath=app2 \
app2:latest
With this setup, the containers write their logs to separate subdirectories of
the logs
volume. The containers can't access the other container's logs.
Share data between machines
When building fault-tolerant applications, you may need to configure multiple replicas of the same service to have access to the same files.


There are several ways to achieve this when developing your applications. One is to add logic to your application to store files on a cloud object storage system like Amazon S3. Another is to create volumes with a driver that supports writing files to an external storage system like NFS or Amazon S3.
Volume drivers let you abstract the underlying storage system from the application logic. For example, if your services use a volume with an NFS driver, you can update the services to use a different driver. For example, to store data in the cloud, without changing the application logic.
Use a volume driver
When you create a volume using docker volume create
, or when you start a
container which uses a not-yet-created volume, you can specify a volume driver.
The following examples use the rclone/docker-volume-rclone
volume driver, first when creating
a standalone volume, and then when starting a container which creates a new
volume.
NoteIf your volume driver accepts a comma-separated list as an option, you must escape the value from the outer CSV parser. To escape a
volume-opt
, surround it with double quotes ("
) and surround the entire mount parameter with single quotes ('
).For example, the
local
driver accepts mount options as a comma-separated list in theo
parameter. This example shows the correct way to escape the list.$ docker service create \ --mount 'type=volume,src=<VOLUME-NAME>,dst=<CONTAINER-PATH>,volume-driver=local,volume-opt=type=nfs,volume-opt=device=<nfs-server>:<nfs-path>,"volume-opt=o=addr=<nfs-address>,vers=4,soft,timeo=180,bg,tcp,rw"' --name myservice \ <IMAGE>
Initial setup
The following example assumes that you have two nodes, the first of which is a Docker host and can connect to the second node using SSH.
On the Docker host, install the rclone/docker-volume-rclone
plugin:
$ docker plugin install --grant-all-permissions rclone/docker-volume-rclone --aliases rclone
Create a volume using a volume driver
This example mounts the /remote
directory on host 1.2.3.4
into a
volume named rclonevolume
. Each volume driver may have zero or more
configurable options, you specify each of them using an -o
flag.
$ docker volume create \
-d rclone \
--name rclonevolume \
-o type=sftp \
-o path=remote \
-o sftp-host=1.2.3.4 \
-o sftp-user=user \
-o "sftp-password=$(cat file_containing_password_for_remote_host)"
This volume can now be mounted into containers.
Start a container which creates a volume using a volume driver
NoteIf the volume driver requires you to pass any options, you must use the
--mount
flag to mount the volume, and not-v
.
$ docker run -d \
--name rclone-container \
--mount type=volume,volume-driver=rclone,src=rclonevolume,target=/app,volume-opt=type=sftp,volume-opt=path=remote, volume-opt=sftp-host=1.2.3.4,volume-opt=sftp-user=user,volume-opt=-o "sftp-password=$(cat file_containing_password_for_remote_host)" \
nginx:latest
Create a service which creates an NFS volume
The following example shows how you can create an NFS volume when creating a service.
It uses 10.0.0.10
as the NFS server and /var/docker-nfs
as the exported directory on the NFS server.
Note that the volume driver specified is local
.
NFSv3
$ docker service create -d \
--name nfs-service \
--mount 'type=volume,source=nfsvolume,target=/app,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/var/docker-nfs,volume-opt=o=addr=10.0.0.10' \
nginx:latest
NFSv4
$ docker service create -d \
--name nfs-service \
--mount 'type=volume,source=nfsvolume,target=/app,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/var/docker-nfs,"volume-opt=o=addr=10.0.0.10,rw,nfsvers=4,async"' \
nginx:latest
Create CIFS/Samba volumes
You can mount a Samba share directly in Docker without configuring a mount point on your host.
$ docker volume create \
--driver local \
--opt type=cifs \
--opt device=//uxxxxx.your-server.de/backup \
--opt o=addr=uxxxxx.your-server.de,username=uxxxxxxx,password=*****,file_mode=0777,dir_mode=0777 \
--name cif-volume
The addr
option is required if you specify a hostname instead of an IP.
This lets Docker perform the hostname lookup.
Block storage devices
You can mount a block storage device, such as an external drive or a drive partition, to a container. The following example shows how to create and use a file as a block storage device, and how to mount the block device as a container volume.
ImportantThe following procedure is only an example. The solution illustrated here isn't recommended as a general practice. Don't attempt this approach unless you're confident about what you're doing.
How mounting block devices works
Under the hood, the --mount
flag using the local
storage driver invokes the
Linux mount
syscall and forwards the options you pass to it unaltered.
Docker doesn't implement any additional functionality on top of the native mount features supported by the Linux kernel.
If you're familiar with the
Linux mount
command,
you can think of the --mount
options as forwarded to the mount
command in the following manner:
$ mount -t <mount.volume-opt.type> <mount.volume-opt.device> <mount.dst> -o <mount.volume-opts.o>
To explain this further, consider the following mount
command example.
This command mounts the /dev/loop5
device to the path /external-drive
on the system.
$ mount -t ext4 /dev/loop5 /external-drive
The following docker run
command achieves a similar result, from the point of view of the container being run.
Running a container with this --mount
option sets up the mount in the same way as if you had executed the
mount
command from the previous example.
$ docker run \
--mount='type=volume,dst=/external-drive,volume-driver=local,volume-opt=device=/dev/loop5,volume-opt=type=ext4'
You can't run the mount
command inside the container directly,
because the container is unable to access the /dev/loop5
device.
That's why the docker run
command uses the --mount
option.
Example: Mounting a block device in a container
The following steps create an ext4
filesystem and mounts it into a container.
The filesystem support of your system depends on the version of the Linux kernel you are using.
-
Create a file and allocate some space to it:
$ fallocate -l 1G disk.raw
-
Build a filesystem onto the
disk.raw
file:$ mkfs.ext4 disk.raw
-
Create a loop device:
$ losetup -f --show disk.raw /dev/loop5
Notelosetup
creates an ephemeral loop device that's removed after system reboot, or manually removed withlosetup -d
. -
Run a container that mounts the loop device as a volume:
$ docker run -it --rm \ --mount='type=volume,dst=/external-drive,volume-driver=local,volume-opt=device=/dev/loop5,volume-opt=type=ext4' \ ubuntu bash
When the container starts, the path
/external-drive
mounts thedisk.raw
file from the host filesystem as a block device. -
When you're done, and the device is unmounted from the container, detach the loop device to remove the device from the host system:
$ losetup -d /dev/loop5
Back up, restore, or migrate data volumes
Volumes are useful for backups, restores, and migrations.
Use the --volumes-from
flag to create a new container that mounts that volume.
Back up a volume
For example, create a new container named dbstore
:
$ docker run -v /dbdata --name dbstore ubuntu /bin/bash
In the next command:
- Launch a new container and mount the volume from the
dbstore
container - Mount a local host directory as
/backup
- Pass a command that tars the contents of the
dbdata
volume to abackup.tar
file inside the/backup
directory.
$ docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
When the command completes and the container stops, it creates a backup of
the dbdata
volume.
Restore volume from a backup
With the backup just created, you can restore it to the same container, or to another container that you created elsewhere.
For example, create a new container named dbstore2
:
$ docker run -v /dbdata --name dbstore2 ubuntu /bin/bash
Then, un-tar the backup file in the new container's data volume:
$ docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"
You can use these techniques to automate backup, migration, and restore testing using your preferred tools.
Supprimer les volumes
Un volume de données Docker persiste après la suppression d'un conteneur. Il y a deux types de volumes à considérer :
- Les volumes nommés ont une source spécifique depuis l'extérieur du conteneur, par exemple,
awesome:/bar
. - Les volumes anonymes n'ont pas de source spécifique. Par conséquent, lorsque le conteneur est supprimé, vous pouvez demander au démon Docker Engine de les supprimer.
Supprimer les volumes anonymes
Pour supprimer automatiquement les volumes anonymes, utilisez l'option --rm
. Par exemple,
cette commande crée un volume anonyme /foo
. Lorsque vous supprimez le conteneur,
Docker Engine supprime le volume /foo
mais pas le volume awesome
.
$ docker run --rm -v /foo -v awesome:/bar busybox top
NoteSi un autre conteneur lie les volumes avec
--volumes-from
, les définitions de volume sont copiées et le volume anonyme reste également après la suppression du premier conteneur.
Supprimer tous les volumes
Pour supprimer tous les volumes inutilisés et libérer de l'espace :
$ docker volume prune
Étapes suivantes
- En savoir plus sur les montages bind.
- En savoir plus sur les montages tmpfs.
- En savoir plus sur les pilotes de stockage.
- En savoir plus sur les plugins de pilote de volume tiers.