mirror of https://github.com/docker/docs.git
Improve data persistence documentation (#4018)
This commit is contained in:
parent
85d70ff7d8
commit
a7d070ca2c
|
@ -164,8 +164,6 @@ guides:
|
||||||
section:
|
section:
|
||||||
- path: /engine/tutorials/networkingcontainers/
|
- path: /engine/tutorials/networkingcontainers/
|
||||||
title: Network containers
|
title: Network containers
|
||||||
- path: /engine/tutorials/dockervolumes/
|
|
||||||
title: Manage data in containers
|
|
||||||
- path: /engine/docker-overview/
|
- path: /engine/docker-overview/
|
||||||
title: Docker overview
|
title: Docker overview
|
||||||
- sectiontitle: User guide
|
- sectiontitle: User guide
|
||||||
|
@ -305,6 +303,19 @@ guides:
|
||||||
title: Runtime metrics
|
title: Runtime metrics
|
||||||
- path: /engine/admin/ambassador_pattern_linking/
|
- path: /engine/admin/ambassador_pattern_linking/
|
||||||
title: Link via an ambassador container
|
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
|
- sectiontitle: Troubleshoot Docker Engine
|
||||||
section:
|
section:
|
||||||
- path: /engine/admin/troubleshooting_volume_errors/
|
- path: /engine/admin/troubleshooting_volume_errors/
|
||||||
|
|
|
@ -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).
|
|
@ -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.
|
|
@ -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)
|
|
@ -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).
|
|
@ -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.
|
|
Loading…
Reference in New Issue