Improve data persistence documentation (#4018)

This commit is contained in:
Misty Stanley-Jones 2017-08-09 15:12:59 -07:00 committed by GitHub
parent 85d70ff7d8
commit a7d070ca2c
6 changed files with 1151 additions and 396 deletions

View File

@ -164,8 +164,6 @@ guides:
section:
- path: /engine/tutorials/networkingcontainers/
title: Network containers
- path: /engine/tutorials/dockervolumes/
title: Manage data in containers
- path: /engine/docker-overview/
title: Docker overview
- sectiontitle: User guide
@ -305,6 +303,19 @@ guides:
title: Runtime metrics
- path: /engine/admin/ambassador_pattern_linking/
title: Link via an ambassador container
- sectiontitle: Manage application data
section:
- path: /engine/admin/volumes/
title: Storage overview
- path: /engine/admin/volumes/volumes/
title: Volumes
- path: /engine/admin/volumes/bind-mounts/
title: Bind mounts
- path: /engine/admin/volumes/tmpfs/
title: tmpfs mounts
- path: /engine/userguide/storagedriver/
title: Container storage drivers
nosync: true
- sectiontitle: Troubleshoot Docker Engine
section:
- path: /engine/admin/troubleshooting_volume_errors/

View File

@ -0,0 +1,435 @@
---
description: Using bind mounts
title: Use bind mounts
keywords: storage, persistence, data persistence, mounts, bind mounts
---
Bind mounts have been around since the early days of Docker. Bind mounts have
limited functionality compared to [volumes](volumes.md). When you use a bind
mount, a file or directory on the _host machine_ is mounted into a container.
The file or directory is referenced by its full or relative path on the host
machine. By contrast, when you use a volume, a new directory is created within
Docker's storage directory on the host machine, and Docker manages that
directory's contents.
The file or directory does not need to exist on the Docker host already. It is
created on demand if it does not yet exist. Bind mounts are very performant, but
they rely on the host machine's filesystem having a specific directory structure
available. If you are developing new Docker applications, consider using [named
volumes](volumes.md) instead. You can't use Docker CLI commands to directly
manage bind mounts.
## 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 `--mount` syntax. Experienced users may
> be more familiar with the `-v` or `--volume` syntax, but are encouraged to
> use `--mount`, because research has shown it to be easier to use.
- **`-v` or `--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 bind mounts, the first field is the path to the file or
directory on the **host machine**.
- 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`, `consistent`, `delegated`, `cached`, `z`, and `Z`. These options
are discussed below.
- **`--mount`**: Consists of multiple key-value pairs, separated by commas and each
consisting of a `<key>=<value>` tuple. The `--mount` syntax is more verbose
than `-v` or `--volume`, but the order of the keys is not significant, and
the value of the flag is easier to understand.
- The `type` of the mount, which can be `bind`, `volume`, or `tmpfs`. This
topic discusses bind mounts, so the type will always be `bind`.
- The `source` of the mount. For bind mounts, this is the path to the file
or directory on the Docker daemon host. May be specified as `source` or
`src`.
- The `destination` takes as its value the path where the file or directory
will be mounted in the container. May be specified as `destination`, `dst`,
or `target`.
- The `readonly` option, if present, causes the bind mount to be [mounted into
the container as read-only](#use-a-read-only-bind-mount).
- The `bind-propagation` option, if present, changes the
[bind propagation](#configure-bind-propagation). May be one of `rprivate`,
`private`, `rshared`, `shared`, `rslave`, `slave`.
- The [`consistency`](#configure-mount-consistency-for-macos) option, if
present, may be one of `consistent`, `delegated`, or `cached`. This setting
only applies to Docker for Mac, and is ignored on all other platforms.
- The `--mount` flag does not support `z` or `Z` options for modifying
selinux labels.
The examples below show both the `--mount` and `-v` syntax where possible, and
`--mount` is presented first.
### Differences between `-v` and `--mount` behavior
Because the `-v` and `--volume` flags have been a part of Docker for a long
time, their behavior cannot be changed. This means that **there is one behavior
that is different between `-v` and `--mount`.**
If you use `-v` or `--volume` to bind-mount a file or directory that does not
yet exist on the Docker host, `-v` will create the endpoint for you. **It is
always created as a directory.**
If you use `--mount` to bind-mount a file or directory that does not
yet exist on the Docker host, Docker does **not** automatically create it for
you, but generates an error.
## Start a container with a bind mount
Consider a case where you have a directory `source` and that when you build the
source code, the artifacts are saved into another directory `source/target/`.
You want the artifacts to be available to the container at `/app/`, and you
want the container to get access to a new build each time you build the source
on your development host. Use the following command to bind-mount the `target/`
directory into your container at `/app/`. Run the command from within the
`source` directory. The `$(pwd)` sub-command expands to the current working
directory on Linux or macOS hosts.
The `--mount` and `-v` examples below produce the same result. You
can't run them both unless you remove the `devtest` container after running the
first one.
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" data-group="mount" data-target="#mount-run"><code>--mount</code></a></li>
<li><a data-toggle="tab" data-group="volume" data-target="#v-run"><code>-v</code></a></li>
</ul>
<div class="tab-content">
<div id="mount-run" class="tab-pane fade in active" markdown="1">
```bash
$ docker run -d \
-it \
--name devtest \
--mount source=$(pwd)/target,target=/app \
nginx:latest
```
</div><!--mount-->
<div id="v-run" class="tab-pane fade" markdown="1">
```bash
$ docker run -d \
-it \
--name devtest \
-v $(pwd)/target:/app \
nginx:latest
```
</div><!--volume-->
</div><!--tab-content-->
Use `docker inspect devtest` to verify that the bind mount was created
correctly. Look for the `Mounts` section:
```json
"Mounts": [
{
"Type": "bind",
"Source": "/tmp/source/target",
"Destination": "/app",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
```
This shows that the mount is a `bind` mount, it shows the correct source and
destination, it shows that the mount is read-write, and that the propagation is
set to `rprivate`.
Stop the container:
```bash
$ docker container stop devtest
$ docker container rm devtest
```
### Mounting into a non-empty directory on the container
If you bind-mount into a non-empty directory on the container, the directory's
existing contents will be obscured by the bind mount. This can be beneficial,
such as when you want to test a new version of your application without
building a new image. However, it can also be surprising and this behavior
differs from that of [docker volumes](volumes.md).
This example is contrived to be extreme, but will replace the contents of the
container's `/usr/` directory with the `/tmp/` directory on the host machine. In
most cases, this would result in a non-functioning container.
The `--mount` and `-v` examples have the same end result.
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" data-group="mount" data-target="#mount-empty-run"><code>--mount</code></a></li>
<li><a data-toggle="tab" data-group="volume" data-target="#v-empty-run"><code>-v</code></a></li>
</ul>
<div class="tab-content">
<div id="mount-empty-run" class="tab-pane fade in active" markdown="1">
```bash
$ docker run -d \
-it \
--name broken-container \
--mount source=/tmp,target=/usr \
nginx:latest
docker: Error response from daemon: oci runtime error: container_linux.go:262:
starting container process caused "exec: \"nginx\": executable file not found in $PATH".
```
</div><!--mount-->
<div id="v-empty-run" class="tab-pane fade" markdown="1">
```bash
$ docker run -d \
-it \
--name broken-container \
-v /tmp:/usr \
nginx:latest
docker: Error response from daemon: oci runtime error: container_linux.go:262:
starting container process caused "exec: \"nginx\": executable file not found in $PATH".
```
</div><!--volume-->
</div><!--tab-content-->
The container is created but does not start. Remove it:
```bash
$ docker container rm broken-container
```
## Use a read-only bind mount
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.
This example modifies the one above but mounts the directory as a read-only
bind mount, 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.
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" data-group="mount" data-target="#mount-readonly"><code>--mount</code></a></li>
<li><a data-toggle="tab" data-group="volume" data-target="#v-readonly"><code>-v</code></a></li>
</ul>
<div class="tab-content">
<div id="mount-readonly" class="tab-pane fade in active" markdown="1">
```bash
$ docker run -d \
-it \
--name devtest \
--mount source=$(pwd)/target,target=/app,readonly \
nginx:latest
```
</div><!--mount-->
<div id="v-readonly" class="tab-pane fade" markdown="1">
```bash
$ docker run -d \
-it \
--name devtest \
-v $(pwd)/target:/app:ro \
nginx:latest
```
</div><!--volume-->
</div><!--tab-content-->
Use `docker inspect devtest` to verify that the bind mount was created
correctly. Look for the `Mounts` section:
```json
"Mounts": [
{
"Type": "bind",
"Source": "/tmp/source/target",
"Destination": "/app",
"Mode": "ro",
"RW": false,
"Propagation": "rprivate"
}
],
```
Stop the container:
```bash
$ docker container stop devtest
$ docker container rm devtest
```
## Configure bind propagation
Bind propagation defaults to `rprivate` for both bind mounts and volumes. It is
only configurable for bind mounts, and only on Linux host machines. Bind
propagation is an advanced topic and many users never need to configure it.
Bind propagation refers to whether or not mounts created within a given
bind-mount or named volume can be propagated to replicas of that mount. Consider
a mount point `/mnt`, which is also mounted on `/tmp`. The propagation settings
control whether a mount on `/tmp/a` would also be available on `/mnt/a`. Each
propagation setting has a recursive counterpoint. In the case of recursion,
consider that `/tmp/a` is also mounted as `/foo`. The propagation settings
control whether `/mnt/a` and/or `/tmp/a` would exist.
| Propagation setting | Description |
|:--------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `shared` | Sub-mounts of the original mount are exposed to replica mounts, and sub-mounts of replica mounts are also propagated to the original mount. |
| `slave` | similar to a shared mount, but only in one direction. If the original mount exposes a sub-mount, the replica mount can see it. However, if the replica mount exposes a sub-mount, the original mount cannot see it. |
| `private` | The mount is private. Sub-mounts within it are not exposed to replica mounts, and sub-mounts of replica mounts are not exposed to the original mount. |
| `rshared` | The same as shared, but the propagation also extends to and from mount points nested within any of the original or replica mount points. |
| `rslave` | The same as slave, but the propagation also extends to and from mount points nested within any of the original or replica mount points. |
| `rprivate` | The default. The same as private, meaning that no mount points anywhere within the original or replica mount points propagate in either direction. |
Before you can set bind propagation on a mount point, the host filesystem needs
to already support bind propagation.
For more information about bind propagation, see the
[Linux kernel documentation for shared subtree](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt){: target="_blank" class="_"}.
The following example mounts the `target/` directory into the container twice,
and the second mount sets both the `ro` option and the `rslave` bind propagation
option.
The `--mount` and `-v` examples have the same result.
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" data-group="mount" data-target="#mount-propagation"><code>--mount</code></a></li>
<li><a data-toggle="tab" data-group="volume" data-target="#v-propagation"><code>-v</code></a></li>
</ul>
<div class="tab-content">
<div id="mount-propagation" class="tab-pane fade in active" markdown="1">
```bash
$ docker run -d \
-it \
--name devtest \
--mount source=$(pwd)/target,target=/app \
--mount source=$(pwd)/target,target=/app2,readonly,bind-propagation=rslave \
nginx:latest
```
</div><!--mount-->
<div id="v-propagation" class="tab-pane fade" markdown="1">
```bash
$ docker run -d \
-it \
--name devtest \
-v $(pwd)/target:/app \
-v $(pwd)/target:/app2:ro,rslave \
nginx:latest
```
</div><!--volume-->
</div><!--tab-content-->
Now if you create `/app/foo/`, `/app2/foo/` will also exist.
## Configure the selinux label
If you use `selinux` you can add the `z` or `Z` options to modify the selinux
label of the **host file or directory** being mounted into the container. This
affects the file or directory on the host machine itself and can have
consequences outside of the scope of Docker.
- The `z` option indicates that the bind mount content is shared among multiple
containers.
- The `Z` option indicates that the bind mount content is private and unshared.
Use **extreme** caution with these options. Bind-mounting a system directory
such as `/home` or `/usr` with the `Z` option will render your host machine
inoperable and you may need to relabel the host machine files by hand.
This example sets the `z` option to specify that multiple containers can share
the bind mount's contents:
It is not possible to modify the selinux label using the `--mount` flag.
```bash
$ docker run -d \
-it \
--name devtest \
-v $(pwd)/target:/app:z \
nginx:latest
```
## Configure mount consistency for macOS
Docker for Mac uses `osxfs` to propagate directories and files shared from macOS
to the Linux VM. This propagation makes these directories and files available to
Docker containers running on Docker for Mac.
By default, these shares are fully-consistent, meaning that every time a write
happens on the macOS host or through a mount in a container, the changes are
flushed to disk so that all participants in the share have a fully-consistent
view. Full consistency can severely impact performance in some cases. Docker
17.05 and higher introduce options to tune the consistency setting on a
per-mount, per-container basis. The following options are available:
- `consistent` or `default`: The default setting with full consistency, as
described above.
- `delegated`: The container runtime's view of the mount is authoritative. There
may be delays before updates made in a container are visible on the host.
- `cached`: The macOS host's view of the mount is authoritative. There may be
delays before updates made on the host are visible within a container.
These options are completely ignored on all host operating systems except macOS.
The `--mount` and `-v` examples have the same result.
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" data-group="mount" data-target="#mount-consistency"><code>--mount</code></a></li>
<li><a data-toggle="tab" data-group="volume" data-target="#v-consistency"><code>-v</code></a></li>
</ul>
<div class="tab-content">
<div id="mount-consistency" class="tab-pane fade in active" markdown="1">
```bash
$ docker run -d \
-it \
--name devtest \
--mount source=$(pwd)/target,destination=/app,consistency=cached \
nginx:latest
```
</div><!--mount-->
<div id="v-consistency" class="tab-pane fade" markdown="1">
```bash
$ docker run -d \
-it \
--name devtest \
-v $(pwd)/target:/app:cached \
nginx:latest
```
</div><!--volume-->
</div><!--tab-content-->
## Next steps
- Learn about [volumes](volumes.md).
- Learn about [tmpfs mounts](tmpfs.md).
- Learn about [storage drivers](/engine/userguide/storagedriver.md).

View File

@ -0,0 +1,175 @@
---
description: Overview of persisting data in containers
title: Manage data in Docker
keywords: storage, persistence, data persistence, volumes, mounts, bind mounts
---
It is possible to store data within the writable layer of a container, but there
are some downsides:
- The data won't persist when that container is no longer running, and it can be
difficult to get the data out of the container if another process needs it.
- A container's writable layer is tightly coupled to the host machine
where the container is running. You can't easily move the data somewhere else.
- Writing into a container's writable layer requires a
[storage driver](/engine/userguide/storagedriver.md) to manage the
filesystem. The storage driver provides a union filesystem, using the Linux
kernel. This extra abstraction reduces performance as compared to using
_data volumes_, which write directly to the host filesystem.
Docker offers three different ways to mount data into a container from the
Docker host: _volumes_, _bind mounts_, or _`tmpfs` volumes_. When in doubt,
volumes are almost always the right choice. Keep reading for more information
about each mechanism for mounting data into containers.
## Choose the right type of mount
No matter which type of mount you choose to use, the data looks the same from
within the container. It is exposed as either a directory or an individual file
in the container's filesystem.
An easy way to visualize the difference among volumes, bind mounts, and `tmpfs`
mounts is to think about where the data lives on the Docker host:
- **Volumes** are stored in a part of the host filesystem which is _managed by
Docker_ (`/var/lib/docker/volumes/` on Linux). Non-Docker processes should not
modify this part of the filesystem. Volumes are the best way to persist data
in Docker.
- **Bind mounts** may be stored *anywhere* on the host system. They may even be
important system files or directories. Non-Docker processes on the Docker host
or a Docker container can modify them at any time.
- **`tmpfs` mounts** are stored in the host system's memory only, and are never
written to the host system's filesystem.
### More details about mount types
- **[Volumes](volumes.md)**: Created and managed by Docker. You can create a
volume explicitly using the `docker volume create` command, or Docker can
create a volume during container or service creation.
When you create a volume, it is stored within a a directory on the Docker
host. When you mount the volume into a container, this directory is what is
mounted into the container. This is similar to the way that bind mounts work,
except that volumes are managed by Docker and are isolated from the core
functionality of the host machine.
A given volume can be mounted into multiple containers simultaneously. When no
running container is using a volume, the volume is still available to Docker
and is not removed automatically. You can remove unused volumes using `docker
volume prune`.
When you mount a volume, it may be **named** or **anonymous**. Anonymous
volumes are not given an explicit name when they are first mounted into a
container, so Docker gives them a random name that is guaranteed to be unique
within a given Docker host. Besides the name, named and anonymous volumes
behave in the same ways.
Volumes also support the use of _volume drivers_, which allow you to store
your data on remote hosts or cloud providers, among other possibilities.
- **[Bind mounts](bind-mounts.md)**: Available since the early days of Docker.
Bind mounts have limited functionality compared to volumes. When you use a
bind mount, a file or directory on the _host machine_ is mounted into a
container. The file or directory is referenced by its full path on the host
machine. The file or directory does not need to exist on the Docker host
already. It is created on demand if it does not yet exist. Bind mounts are
very performant, but they rely on the host machine's filesystem having a
specific directory structure available. If you are developing new Docker
applications, consider using named volumes instead. You can't use
Docker CLI commands to directly manage bind mounts.
> **Warning**: One side effect of using bind mounts, for better or for worse,
> is that you can change the **host** filesystem via processes running in a
> **container**, including creating, modifying, or deleting important system
> files or directories. This is a powerful ability which can have security
> implications, including impacting non-Docker processes on the host system.
{: .warning }
- **[tmpfs mounts](tmpfs.md)**: A `tmpfs` mount is not persisted on disk, either
on the Docker host or within a container. It can be used by a container during
the lifetime of the container, to store non-persistent state or sensitive
information. For instance, internally, swarm services use `tmpfs` mounts to
mount [secrets](/engine/swarm/secrets.md) into a service's containers.
Bind mounts and volumes can both mounted into containers using the `-v` or
`--volume` flag, but the syntax for each is slightly different. For `tmpfs`
mounts, you can use the `--tmpfs` flag. However, in Docker 17.06 and higher,
we recommend using the `--mount` flag for both containers and services, for
bind mounts, volumes, or `tmpfs` mounts, as the syntax is more clear.
## Good use cases for volumes
Volumes are the preferred way to persist data in Docker containers and services.
Some use cases for volumes include:
- Sharing data among multiple running containers. If you don't explicitly create
it, a volume is created the first time it is mounted into a container. When
that container stops or is removed, the volume still exists. Multiple
containers can mount the same volume simultaneously, either read-write or
read-only. Volumes are only removed when you explicitly remove them.
- When the Docker host is not guaranteed to have a given directory or file
structure. Volumes help you decouple the configuration of the Docker host
from the container runtime.
- When you want to store your container's data on a remote host or a cloud
provider, rather than locally.
- When you need to be able to back up, restore, or migrate data from one Docker
host to another, volumes are a better choice. You can stop containers using
the volume, then back up the volume's directory
(such as `/var/lib/docker/volumes/<volume-name>`).
## Good use cases for bind mounts
In general, you should use volumes where possible. Bind mounts are appropriate
for the following types of use case:
- Sharing configuration files from the host machine to containers. This is how
Docker provides DNS resolution to containers by default, by mounting
`/etc/resolv.conf` from the host machine into each container.
- Sharing source code or build artifacts between a development environment on
the Docker host and a container. For instance, you may mount a Maven `target/`
directory into a container, and each time you build the Maven project on the
Docker host, the container gets access to the rebuilt artifacts.
If you use Docker for development this way, your production Dockerfile would
copy the production-ready artifacts directly into the image, rather than
relying on a bind mount.
- When the file or directory structure of the Docker host is guaranteed to be
consistent with the bind mounts the containers require.
## Good use cases for tmpfs mounts
`tmpfs` mounts are best used for cases when you do not want the data to persist
either on the host machine or within the container. This may be for security
reasons or to protect the performance of the container when your application
needs to write a large volume of non-persistent state data.
## Tips for using bind mounts or volumes
If you use either bind mounts or volumes, keep the following in mind:
- If the container's image contains data at the mount point, this data will be
propagated into the bind mount or volume. This is a good way to pre-populate
data that the Docker host needs (in the case of bind mounts) or that another
container needs (in the case of volumes).
- If you mount a bind mount or volume into a directory in the container in which
files or directories have already been written, these files or directories are
obscured by the mount, just as if you saved files into `/mnt` on a Linux host
and then mounted a USB drive into `/mnt`. The contents of `/mnt` would be
obscured by the contents of the USB drive until the USB drive were unmounted.
## Next steps
- Learn more about [volumes](volumes.md).
- Learn more about [bind mounts](bind-mounts.md).
- Learn more about [tmpfs mounts](tmpfs.md).
- Learn more about [storage drivers](/engine/userguide/storagedriver.md), which
are not related to bind mounts or volumes, but allow you to store data in a
container's writable layer.

View File

@ -0,0 +1,144 @@
---
description: Using tmpfs mounts
title: Use tmpfs mounts
keywords: storage, persistence, data persistence, tmpfs
---
[Volumes](volumes.md) and [bind mounts](bind-mounts.md) are mounted into the
container's filesystem by default, and their contents are stored on on the host
machine.
There may be cases where you do not want to store a container's data on the host
machine, but you also don't want to write the data into the container's writable
layer, for performance or security reasons, or if the data relates to
non-persistent application state. An example might be a temporary one-time
password that the container's application creates and uses as-needed.
To give the container access to the data without writing it anywhere
permanently, you can use a `tmpfs` mount, which is only stored in the host
machine's memory (or swap, if memory is low). When the container stops, the
`tmpfs` mount is removed. If a container is committed, the `tmpfs` mount is not
saved.
## Choosing the --tmpfs or --mount flag
Originally, the `--tmpfs` 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
`--tmpfs` flag does not support any configurable options.
> **Tip**: New users should use the `--mount` syntax. Experienced users may
> be more familiar with the `--tmpfs` syntax, but are encouraged to
> use `--mount`, because research has shown it to be easier to use.
- **`--tmpfs`**: Mounts a `tmpfs` mount without allowing you to specify any
configurable options, and can only be used with standalone containers.
- **`--mount`**: Consists of multiple key-value pairs, separated by commas and each
consisting of a `<key>=<value>` tuple. The `--mount` syntax is more verbose
than `-v` or `--volume`, but the order of the keys is not significant, and
the value of the flag is easier to understand.
- The `type` of the mount, which can be [`bind`](bind-mounts-md), `volume`, or
[`tmpfs`](tmpfs.md). This topic discusses `tmpfs`, so the type will always
be `tmpfs`.
- The `destination` takes as its value the path where the `tmpfs` mount
will be mounted in the container. May be specified as `destination`, `dst`,
or `target`.
- The `tmpfs-type` and `tmpfs-mode` options. See
[tmpfs options](#tmpfs-options).
The examples below show both the `--mount` and `--tmpfs` syntax where possible,
and `--mount` is presented first.
### Differences between `--tmpfs` and `--mount` behavior
- The `--tmpfs` flag does not allow you to specify any configurable options.
- The `--tmpfs` flag cannot be used with swarm services. You must use `--mount`.
## Limitations of tmpfs containers
- `tmpfs` mounts cannot be shared among containers.
- `tmpfs` mounts only work on Linux containers, and not on Windows containers.
## Use a tmpfs mount in a container
To use a `tmpfs` mount in a container, use the `--tmpfs` flag, or use the
`--mount` flag with `type=tmpfs` and `destination` options. There is no
`source` for `tmpfs` mounts. The following example creates a `tmpfs` mount at
`/app` in a Nginx container. The first example uses the `--mount` flag and the
second uses the `--tmpfs` flag.
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" data-group="mount" data-target="#mount-run"><code>--mount</code></a></li>
<li><a data-toggle="tab" data-group="volume" data-target="#tmpfs-run"><code>--tmpfs</code></a></li>
</ul>
<div class="tab-content">
<div id="mount-run" class="tab-pane fade in active" markdown="1">
```bash
$ docker run -d \
-it \
--name tmptest \
--mount type=tmpfs,destination=/app \
nginx:latest
```
</div><!--mount-->
<div id="tmpfs-run" class="tab-pane fade" markdown="1">
```bash
$ docker run -d \
-it \
--name tmptest \
--tmpfs /app \
nginx:latest
```
</div><!--volume-->
</div><!--tab-content-->
Verify that the mount is a `tmpfs` mount by running `docker container inspect
tmptest` and looking for the `Mounts` section:
```json
"Tmpfs": {
"/app": ""
},
```
Remove the container:
```bash
$ docker container stop tmptest
$ Docker container rm tmptest
```
### Specify tmpfs options
`tmpfs` mounts allow for two configuration options, neither of which is
required. If you need to specify these options, you must use the `--mount` flag,
as the `--tmpfs` flag does not support them.
| Option | Description |
|:-------------|:------------------------------------------------------------------------------------------------------|
| `tmpfs-size` | Size of the tmpfs mount in bytes. Unlimited by default. |
| `tmpfs-mode` | File mode of the tmpfs in octal. For instance, `700` or `0770`. Defaults to `1777` or world-writable. |
The following example sets the `tmpfs-mode` to `1770`, so that it is not
world-readable within the container.
```bash
docker run -d \
-it \
--name tmptest \
--mount type=tmpfs,destination=/app,tmpfs-mode=1770 \
nginx:latest
```
## Next steps
- Learn about [volumes](volumes.md)
- Learn about [bind mounts](bind-mounts.md)
- Learn about [storage drivers](/engine/userguide/storagedriver.md)

View File

@ -0,0 +1,384 @@
---
description: Using volumes
title: Use volumes
keywords: storage, persistence, data persistence, volumes
redirect_from:
- engine/tutorials/dockervolumes/
---
Volumes are the preferred mechanism for persisting data generated by and used
by Docker containers. While [bind mounts](bind-mounts.md) 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](tmpfs.md) 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 `--mount` syntax. Experienced users may
> be more familiar with the `-v` or `--volume` syntax, 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`.
- **`-v` or `--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 `--mount` syntax is more verbose
than `-v` or `--volume`, but the order of the keys is not significant, and
the value of the flag is easier to understand.
- The `type` of the mount, which can be [`bind`](bind-mounts-md), `volume`, or
[`tmpfs`](tmpfs.md). This topic discusses volumes, so the type will always
be `volume`.
- The `source` of the mount. For named volumes, this is the name of the volume.
For anonymous volumes, this field is omitted. May be specified as `source`
or `src`.
- The `destination` takes as its value the path where the file or directory
will be mounted in the container. May be specified as `destination`, `dst`,
or `target`.
- The `readonly` option, if present, causes the bind mount to be [mounted into
the container as read-only](#use-a-read-only-bind-mount).
- The `volume-opt` option, which can be specified more than once, takes a
key-value pair consisting of the option name and its value.
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**:
```bash
$ docker volume create my-vol
```
**List volumes**:
```bash
$ docker volume ls
local my-vol
```
**Inspect a volume**:
```bash
$ 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**:
```bash
$ 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.
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" data-group="mount" data-target="#mount-run"><code>--mount</code></a></li>
<li><a data-toggle="tab" data-group="volume" data-target="#v-run"><code>-v</code></a></li>
</ul>
<div class="tab-content">
<div id="mount-run" class="tab-pane fade in active" markdown="1">
```bash
$ docker run -d \
-it \
--name devtest \
--mount source=myvol2,target=/app \
nginx:latest
```
</div><!--mount-->
<div id="v-run" class="tab-pane fade" markdown="1">
```bash
$ docker run -d \
-it \
--name devtest \
-v myvol2:/app \
nginx:latest
```
</div><!--volume-->
</div><!--tab-content-->
Use `docker inspect devtest` to verify that the volume was created and mounted
correctly. Look for the `Mounts` section:
```json
"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.
```bash
$ 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.
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" data-group="mount" data-target="#mount-empty-run"><code>--mount</code></a></li>
<li><a data-toggle="tab" data-group="volume" data-target="#v-empty-run"><code>-v</code></a></li>
</ul>
<div class="tab-content">
<div id="mount-empty-run" class="tab-pane fade in active" markdown="1">
```bash
$ docker run -d \
-it \
--name=nginxtest \
--mount source=nginx-vol,destination=/usr/share/nginx/html \
nginx:latest
```
</div><!--mount-->
<div id="v-empty-run" class="tab-pane fade" markdown="1">
```bash
$ docker run -d \
-it \
--name=nginxtest \
-v nginx-vol:/usr/share/nginx/html \
nginx:latest
```
</div><!--volume-->
</div><!--tab-content-->
After running either of these examples, run the following commands to clean up the
containers and volumes.
```bash
$ 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.
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" data-group="mount" data-target="#mount-readonly"><code>--mount</code></a></li>
<li><a data-toggle="tab" data-group="volume" data-target="#v-readonly"><code>-v</code></a></li>
</ul>
<div class="tab-content">
<div id="mount-readonly" class="tab-pane fade in active" markdown="1">
```bash
$ docker run -d \
-it \
--name=nginxtest \
--mount source=nginx-vol,destination=/usr/share/nginx/html,readonly \
nginx:latest
```
</div><!--mount-->
<div id="v-readonly" class="tab-pane fade" markdown="1">
```bash
$ docker run -d \
-it \
--name=nginxtest \
-v nginx-vol:/usr/share/nginx/html:ro \
nginx:latest
```
</div><!--volume-->
</div><!--tab-content-->
Use `docker inspect nginxtest` to verify that the bind mount was created
correctly. Look for the `Mounts` section:
```json
"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:
```bash
$ 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:
```bash
$ 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.
```bash
$ 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`.**
```bash
$ 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](bind-mounts.md).
- Learn about [tmpfs mounts](tmpfs.md).
- Learn about [storage drivers](/engine/userguide/storagedriver.md).

View File

@ -1,394 +0,0 @@
---
description: How to manage data inside your Docker containers.
keywords: Examples, Usage, volume, docker, documentation, user guide, data, volumes
redirect_from:
- /engine/userguide/containers/dockervolumes/
- /engine/userguide/dockervolumes/
- /userguide/dockervolumes/
title: Manage data in containers
---
In this section you're going to learn how you can manage data inside and between
your Docker containers.
You're going to look at the two primary ways you can manage data with
Docker Engine.
* Data volumes
* Data volume containers
## Data volumes
A *data volume* is a specially-designated directory within one or more
containers that bypasses the [*Union File System*](/glossary/?term=Union file system).
Data volumes provide several useful features for persistent or shared data:
- Volumes are initialized when a container is created. If the container's
parent image contains data at the specified mount point, that existing data is
copied into the new volume upon volume initialization. (Note that this does
not apply when [mounting a host directory](#mount-a-host-file-as-a-data-volume).)
- Data volumes can be shared and reused among containers.
- Changes to a data volume are made directly.
- Changes to a data volume will not be included when you update an image.
- Data volumes persist even if the container itself is deleted.
Data volumes are designed to persist data, independent of the container's lifecycle.
Docker therefore *never* automatically deletes volumes when you remove
a container, nor will it "garbage collect" volumes that are no longer
referenced by a container.
### Add a data volume
You can add a data volume to a container using the `-v` flag with the
`docker create` and `docker run` command. You can use the `-v` multiple times
to mount multiple data volumes. Now, mount a single volume in your web
application container.
```bash
$ docker run -d -P --name web -v /webapp training/webapp python app.py
```
This will create a new volume inside a container at `/webapp`.
> **Note**:
> You can also use the `VOLUME` instruction in a `Dockerfile` to add one or
> more new volumes to any container created from that image.
### Locate a volume
You can locate the volume on the host by utilizing the `docker inspect` command.
```bash
$ docker inspect web
```
The output will provide details on the container configurations including the
volumes. The output should look something similar to the following:
```json
...
"Mounts": [
{
"Name": "fac362...80535",
"Source": "/var/lib/docker/volumes/fac362...80535/_data",
"Destination": "/webapp",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
]
...
```
You will notice in the above `Source` is specifying the location on the host and
`Destination` is specifying the volume location inside the container. `RW` shows
if the volume is read/write.
### Mount a host directory as a data volume
In addition to creating a volume using the `-v` flag you can also mount a
directory from your Docker engine's host into a container.
```bash
$ docker run -d -P --name web -v /src/webapp:/webapp training/webapp python app.py
```
This command mounts the host directory, `/src/webapp`, into the container at
`/webapp`. If the path `/webapp` already exists inside the container's
image, the `/src/webapp` mount overlays but does not remove the pre-existing
content. Once the mount is removed, the content is accessible again. This is
consistent with the expected behavior of the `mount` command.
The `container-dir` must always be an absolute path such as `/src/docs`.
The `host-dir` can either be an absolute path such as `/dst/docs` on Linux
or `C:\dst\docs` on Windows, or a `name` value. If you
supply an absolute path for the `host-dir`, Docker bind-mounts to the path
you specify. If you supply a `name`, Docker creates a named volume by that `name`.
A `name` value must start with an alphanumeric character,
followed by `a-z0-9`, `_` (underscore), `.` (period) or `-` (hyphen).
An absolute path starts with a `/` (forward slash).
For example, you can specify either `/foo` or `foo` for a `host-dir` value.
If you supply the `/foo` value, the Docker Engine creates a bind-mount. If you supply
the `foo` specification, the Docker Engine creates a named volume.
If you are using Docker Machine on Mac or Windows, your Docker Engine daemon has only
limited access to your macOS or Windows filesystem. Docker Machine tries to
auto-share your `/Users` (macOS) or `C:\Users` (Windows) directory. So, you can
mount files or directories on macOS using.
```bash
docker run -v /Users/<path>:/<container path> ...
```
On Windows, mount directories using:
```bash
docker run -v c:\<path>:c:\<container path>
```
All other paths come from your virtual machine's filesystem, so if you want
to make some other host folder available for sharing, you need to do
additional work. In the case of VirtualBox you need to make the host folder
available as a shared folder in VirtualBox. Then, you can mount it using the
Docker `-v` flag.
Mounting a host directory can be useful for testing. For example, you can mount
source code inside a container. Then, change the source code and see its effect
on the application in real time. The directory on the host must be specified as
an absolute path and if the directory doesn't exist the Docker Engine daemon
automatically creates it for you.
Docker volumes default to mount in read-write mode, but you can also set it to
be mounted read-only.
```bash
$ docker run -d -P --name web -v /src/webapp:/webapp:ro training/webapp python app.py
```
Here you've mounted the same `/src/webapp` directory but you've added the `ro`
option to specify that the mount should be read-only.
You can also relax the consistency requirements of a mounted directory
to improve performance by adding the `cached` option:
```bash
$ docker run -d -P --name web -v /src/webapp:/webapp:cached training/webapp python app.py
```
The `cached` option typically improves the performance of read-heavy workloads
on Docker for Mac, at the cost of some temporary inconsistency between the host
and the container. On other platforms, `cached` currently has no effect. The
article [User-guided caching in Docker for
Mac](https://blog.docker.com/2017/05/user-guided-caching-in-docker-for-mac/)
gives more details about the behavior of `cached` on macOS.
>**Note**: The host directory is, by its nature, host-dependent. For this
>reason, you can't mount a host directory from `Dockerfile`, the `VOLUME`
instruction does not support passing a `host-dir`, because built images
>should be portable. A host directory wouldn't be available on all potential
>hosts.
### Mount a shared-storage volume as a data volume
In addition to mounting a host directory in your container, some Docker
[volume plugins](/engine/extend/plugins_volume.md) allow you to
provision and mount shared storage, such as iSCSI, NFS, or FC.
A benefit of using shared volumes is that they are host-independent. This
means that a volume can be made available on any host that a container is
started on as long as it has access to the shared storage backend, and has
the plugin installed.
One way to use volume drivers is through the `docker run` command.
Volume drivers create volumes by name, instead of by path like in
the other examples.
The following command creates a named volume, called `my-named-volume`,
using the `convoy` volume driver (`convoy` is a plugin for a variety of storage back-ends)
and makes it available within the container at `/webapp`. Before running the command,
[install and configure convoy](https://github.com/rancher/convoy#quick-start-guide).
If you do not want to install `convoy`, replace `convoy` with `local` in the example commands
below to use the `local` driver.
```bash
$ docker run -d -P \
--volume-driver=convoy \
-v my-named-volume:/webapp \
--name web training/webapp python app.py
```
You may also use the `docker volume create` command, to create a volume before
using it in a container.
The following example also creates the `my-named-volume` volume, this time
using the `docker volume create` command. Options are specified as key-value
pairs in the format `o=<key>=<value>`.
```bash
$ docker volume create -d convoy --opt o=size=20GB my-named-volume
$ docker run -d -P \
-v my-named-volume:/webapp \
--name web training/webapp python app.py
```
A list of available plugins, including volume plugins, is available
[here](/engine/extend/legacy_plugins.md).
### Volume labels
Labeling systems like SELinux require that proper labels are placed on volume
content mounted into a container. Without a label, the security system might
prevent the processes running inside the container from using the content. By
default, Docker does not change the labels set by the OS.
To change a label in the container context, you can add either of two suffixes
`:z` or `:Z` to the volume mount. These suffixes tell Docker to relabel file
objects on the shared volumes. The `z` option tells Docker that two containers
share the volume content. As a result, Docker labels the content with a shared
content label. Shared volume labels allow all containers to read/write content.
The `Z` option tells Docker to label the content with a private unshared label.
Only the current container can use a private volume.
### Mount a host file as a data volume
The `-v` flag can also be used to mount a single file - instead of *just*
directories - from the host machine.
```bash
$ docker run --rm -it -v ~/.bash_history:/root/.bash_history ubuntu /bin/bash
```
This will drop you into a bash shell in a new container, you will have your bash
history from the host and when you exit the container, the host will have the
history of the commands typed while in the container.
> **Note**:
> Many tools used to edit files including `vi` and `sed --in-place` may result
> in an inode change. Since Docker v1.1.0, this will produce an error such as
> "*sed: cannot rename ./sedKdJ9Dy: Device or resource busy*". In the case where
> you want to edit the mounted file, it is often easiest to instead mount the
> parent directory.
## Creating and mounting a data volume container
If you have some persistent data that you want to share between
containers, or want to use from non-persistent containers, it's best to
create a named Data Volume Container, and then to mount the data from
it.
Let's create a new named container with a volume to share.
While this container doesn't run an application, it reuses the `training/postgres`
image so that all containers are using layers in common, saving disk space.
```bash
$ docker create -v /dbdata --name dbstore training/postgres /bin/true
```
You can then use the `--volumes-from` flag to mount the `/dbdata` volume in another container.
```bash
$ docker run -d --volumes-from dbstore --name db1 training/postgres
```
And another:
```bash
$ docker run -d --volumes-from dbstore --name db2 training/postgres
```
In this case, if the `postgres` image contained a directory called `/dbdata`
then mounting the volumes from the `dbstore` container hides the
`/dbdata` files from the `postgres` image. The result is only the files
from the `dbstore` container are visible.
You can use multiple `--volumes-from` parameters to combine data volumes from
several containers. To find detailed information about `--volumes-from` see the
[Mount volumes from container](/engine/reference/commandline/run.md#mount-volumes-from-container-volumes-from)
in the `run` command reference.
You can also extend the chain by mounting the volume that came from the
`dbstore` container in yet another container via the `db1` or `db2` containers.
```bash
$ docker run -d --name db3 --volumes-from db1 training/postgres
```
If you remove containers that mount volumes, including the initial `dbstore`
container, or the subsequent containers `db1` and `db2`, the volumes will not
be deleted. To delete the volume from disk, you must explicitly call
`docker rm -v` against the last container with a reference to the volume. This
allows you to upgrade, or effectively migrate data volumes between containers.
> **Note**: Docker will not warn you when removing a container *without*
> providing the `-v` option to delete its volumes. If you remove containers
> without using the `-v` option, you may end up with "dangling" volumes;
> volumes that are no longer referenced by a container.
> You can use `docker volume ls -f dangling=true` to find dangling volumes,
> and use `docker volume rm <volume name>` to remove a volume that's
> no longer needed.
## Backup, restore, or migrate data volumes
Another useful function we can perform with volumes is use them for
backups, restores or migrations. You do this by using the
`--volumes-from` flag to create a new container that mounts that volume,
like so:
```bash
$ docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
```
Here you've launched a new container and mounted the volume from the
`dbstore` container. You've then mounted a local host directory as
`/backup`. Finally, you've passed a command that uses `tar` to backup the
contents of the `dbdata` volume to a `backup.tar` file inside our
`/backup` directory. When the command completes and the container stops
we'll be left with a backup of our `dbdata` volume.
You could then restore it to the same container, or another that you've made
elsewhere. Create a new container.
```bash
$ docker run -v /dbdata --name dbstore2 ubuntu /bin/bash
```
Then un-tar the backup file in the new container`s data volume.
```bash
$ docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"
```
You can use the techniques above to automate backup, migration and
restore testing using your preferred tools.
## List all volumes
You can list all existing volumes using `docker volume ls`.
```bash
$ docker volume ls
DRIVER VOLUME NAME
local ec75c47aa8b8c61fdabcf37f89dad44266841b99dc4b48261a4757e70357ec06
local f73e499de345187639cdf3c865d97f241216c2382fe5fa67555c64f258892128
local tmp_data
```
## Remove volumes
A Docker data volume persists after a container is deleted. You can create named
or anonymous volumes. Named volumes have a specific source form outside the
container, for example `awesome:/bar`. Anonymous volumes have no specific
source. When the container is deleted, you should instruct the Docker Engine daemon
to clean up anonymous volumes. To do this, use the `--rm` option, for example:
```bash
$ docker run --rm -v /foo -v awesome:/bar busybox top
```
This command creates an anonymous `/foo` volume. When the container is removed,
the Docker Engine removes the `/foo` volume but not the `awesome` volume.
To remove all unused volumes and free up space,
```bash
$ docker volume prune
```
it will remove all unused volumes which are not associated with any container.
## Important tips on using shared volumes
Multiple containers can also share one or more data volumes. However, multiple
containers writing to a single shared volume can cause data corruption. Make
sure your applications are designed to write to shared data stores.
Data volumes are directly accessible from the Docker host. This means you can
read and write to them with normal Linux tools. In most cases you should not do
this as it can cause data corruption if your containers and applications are
unaware of your direct access.