12 KiB
		
	
	
	
	
	
			
		
		
	
	| description | title | keywords | redirect_from | ||
|---|---|---|---|---|---|
| Using volumes | Use volumes | storage, persistence, data persistence, volumes | 
  | 
Volumes are the preferred mechanism for persisting data generated by and used by Docker containers. While bind mounts are dependent on the directory structure of the host machine, volumes are completely managed by Docker. Volumes have several advantages over bind mounts:
- Volumes are easier to back up or migrate than bind mounts.
 - You can manage volumes using Docker CLI commands or the Docker API.
 - Volumes work on both Linux and Windows containers.
 - Volumes can be more safely shared among multiple containers.
 - Volume drivers allow you to store volumes on remote hosts or cloud providers, to encrypt the contents of volumes, or to add other functionality.
 - A new volume's contents can be pre-populated by a container.
 
In addition, volumes are often a better choice than persisting data in a container's writable layer, because using a volume does not increase the size of containers using it, and the volume's contents exist outside the lifecycle of a given container.
If your container generates non-persistent state data, consider using a tmpfs mount to avoid storing the data anywhere permanently, and to increase the container's performance by avoiding writing into the container's writable layer.
Volumes use rprivate bind propagation, and bind propagation is not
configurable for volumes.
Choosing the -v or --mount flag
Originally, the -v or --volume flag was used for standalone containers and
the --mount flag was used for swarm services. However, starting with Docker
17.06, you can also use --mount with standalone containers. In general,
--mount is more explicit and verbose. The biggest difference is that the -v
syntax combines all the options together in one field, while the --mount
syntax separates them. Here is a comparison of the syntax for each flag.
Tip: New users should use the
--mountsyntax. Experienced users may be more familiar with the-vor--volumesyntax, but are encouraged to use--mount, because research has shown it to be easier to use.
If you need to specify volume driver options, you must use --mount.
- 
-vor--volume: Consists of three fields, separated by colon characters (:). The fields must be in the correct order, and the meaning of each field is not immediately obvious.- In the case of named volumes, the first field is the name of the volume, and is unique on a given host machine. For anonymous volumes, the first field is omitted.
 - The second field is the path where the file or directory will be mounted in the container.
 - The third field is optional, and is a comma-separated list of options, such
as 
ro. These options are discussed below. 
 - 
--mount: Consists of multiple key-value pairs, separated by commas and each consisting of a<key>=<value>tuple. The--mountsyntax is more verbose than-vor--volume, but the order of the keys is not significant, and the value of the flag is easier to understand.- The 
typeof the mount, which can bebind,volume, ortmpfs. This topic discusses volumes, so the type will always bevolume. - The 
sourceof the mount. For named volumes, this is the name of the volume. For anonymous volumes, this field is omitted. May be specified assourceorsrc. - The 
destinationtakes as its value the path where the file or directory will be mounted in the container. May be specified asdestination,dst, ortarget. - The 
readonlyoption, if present, causes the bind mount to be mounted into the container as read-only. - The 
volume-optoption, which can be specified more than once, takes a key-value pair consisting of the option name and its value. 
 - The 
 
The examples below show both the --mount and -v syntax where possible, and
--mount is presented first.
Differences between -v and --mount behavior
As opposed to bind mounts, all options for volumes are available for both
--mount and -v flags.
Create and manage volumes
Unlike a bind mount, you can create and manage volumes outside the scope of any container.
Create a volume:
$ docker volume create my-vol
List volumes:
$ docker volume ls
local               my-vol
Inspect a volume:
$ docker volume inspect my-vol
[
    {
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
        "Name": "my-vol",
        "Options": {},
        "Scope": "local"
    }
]
Remove a volume:
$ docker volume rm my-vol
Start a container with a volume
If you start a container with a volume that does not yet exist, Docker creates
the volume for you. The following example mounts the volume myvol2 into
/app/ in the container.
The -v and --mount examples below produce the same result. You can't run
them both unless you remove the devtest container and the myvol2 volume
after running the first one.
--mount-v
$ docker run -d \
  -it \
  --name devtest \
  --mount source=myvol2,target=/app \
  nginx:latest
$ docker run -d \
  -it \
  --name devtest \
  -v myvol2:/app \
  nginx:latest
Use docker inspect devtest to verify that the volume was created and mounted
correctly. Look for the Mounts section:
"Mounts": [
    {
        "Type": "volume",
        "Name": "myvol2",
        "Source": "/var/lib/docker/volumes/myvol2/_data",
        "Destination": "/app",
        "Driver": "local",
        "Mode": "",
        "RW": true,
        "Propagation": ""
    }
],
This shows that the mount is a volume, it shows the correct source and destination, and that the mount is read-write.
Stop the container and remove the volume.
$ docker container stop devtest
$ docker container rm devtest
$ docker volume rm myvol2
Syntax differences for services
The docker service create command does not support the -v or --volume flag.
When mounting a volume into a service's containers, you must use the --mount
flag.
Populating a volume using a container
If you start a container which creates a new volume, as above, and the container
has files or directories in the directory to be mounted (such as /app/ above),
the directory's contents will be copied into the volume. The container will then
mount and use the volume, and other containers which use the volume will also
have access to the pre-populated content.
To illustrate this, this example starts an nginx container and populates the
new volume nginx-vol with the contents of the container's
/usr/share/nginx/html directory, which is where Nginx stores its default HTML
content.
The --mount and -v examples have the same end result.
--mount-v
$ docker run -d \
  -it \
  --name=nginxtest \
  --mount source=nginx-vol,destination=/usr/share/nginx/html \
  nginx:latest
$ docker run -d \
  -it \
  --name=nginxtest \
  -v nginx-vol:/usr/share/nginx/html \
  nginx:latest
After running either of these examples, run the following commands to clean up the containers and volumes.
$ docker container stop devtest
$ docker container rm devtest
$ docker volume rm nginx-vol
Use a read-only volume
For some development applications, it is useful for the container to be able to write into the bind mount, in order for changes to be propagated back to the Docker host. At other times, the container should only be able to read the data and not modify it. Remember that multiple containers can mount the same volume, and it can be mounted read-write for some of them and read-only for others, simultaneously.
This example modifies the one above but mounts the directory as a read-only
volume, by adding ro to the (empty by default) list of options, after the
mount point within the container. Where multiple options are present, separate
them by commas.
The --mount and -v examples have the same result.
--mount-v
$ docker run -d \
  -it \
  --name=nginxtest \
  --mount source=nginx-vol,destination=/usr/share/nginx/html,readonly \
  nginx:latest
$ docker run -d \
  -it \
  --name=nginxtest \
  -v nginx-vol:/usr/share/nginx/html:ro \
  nginx:latest
Use docker inspect nginxtest to verify that the bind mount was created
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:
$ docker container stop devtest
$ docker container rm devtest
$ docker volume rm nginx-vol
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 vieux/sshfs volume driver, first when creating
a standalone volume, and then when starting a container which will create a new
volume.
Initial set-up
This example assumes that you have two nodes, the first of which is a Docker host and can connect to the second using SSH.
On the Docker host, install the vieux/sshfs plugin:
$ docker plugin install --grant-all-permissions vieux/sshfs
Create a volume using a volume driver
This example specifies a SSH password, but if the two hosts have shared keys
configured, you can omit the password. Each volume driver may have zero or more
configurable options, each of which is specified using an -o flag.
$ docker volume create --driver vieux/sshfs \
  -o sshcmd=test@node2:/home/test \
  -o password=testpassword \
  sshvolume
Start a container which creates a volume using a volume driver
This example specifies a SSH password, but if the two hosts have shared keys
configured, you can omit the password. Each volume driver may have zero or more
configurable options. If the volume driver requires you to pass options, you
must use the --mount flag to mount the volume, rather than -v.
$ docker run -d \
  --it \
  --name sshfs-container \
  --volume-driver vieux/sshfs \
  --mount src=sshvolume,target=/app,volume-opt=sshcmd=test@node2:/home/test,volume-opt=password=testpassword \
  nginx:latest
Next steps
- Learn about bind mounts.
 - Learn about tmpfs mounts.
 - Learn about storage drivers.