179 lines
6.8 KiB
Markdown
179 lines
6.8 KiB
Markdown
|
page_title: Share Directories via Volumes
|
|||
|
page_description: How to create and share volumes
|
|||
|
page_keywords: Examples, Usage, volume, docker, documentation, examples
|
|||
|
|
|||
|
# Share Directories via Volumes
|
|||
|
|
|||
|
## Introduction
|
|||
|
|
|||
|
A *data volume* is a specially-designated directory within one or more
|
|||
|
containers that bypasses the [*Union File
|
|||
|
System*](../../terms/layer/#ufs-def) to provide several useful features
|
|||
|
for persistent or shared data:
|
|||
|
|
|||
|
- **Data volumes can be shared and reused between containers:**
|
|||
|
This is the feature that makes data volumes so powerful. You can
|
|||
|
use it for anything from hot database upgrades to custom backup or
|
|||
|
replication tools. See the example below.
|
|||
|
- **Changes to a data volume are made directly:**
|
|||
|
Without the overhead of a copy-on-write mechanism. This is good for
|
|||
|
very large files.
|
|||
|
- **Changes to a data volume will not be included at the next commit:**
|
|||
|
Because they are not recorded as regular filesystem changes in the
|
|||
|
top layer of the [*Union File System*](../../terms/layer/#ufs-def)
|
|||
|
- **Volumes persist until no containers use them:**
|
|||
|
As they are a reference counted resource. The container does not need to be
|
|||
|
running to share its volumes, but running it can help protect it
|
|||
|
against accidental removal via `docker rm`.
|
|||
|
|
|||
|
Each container can have zero or more data volumes.
|
|||
|
|
|||
|
New in version v0.3.0.
|
|||
|
|
|||
|
## Getting Started
|
|||
|
|
|||
|
Using data volumes is as simple as adding a `-v`
|
|||
|
parameter to the `docker run` command. The
|
|||
|
`-v` parameter can be used more than once in order
|
|||
|
to create more volumes within the new container. To create a new
|
|||
|
container with two new volumes:
|
|||
|
|
|||
|
$ docker run -v /var/volume1 -v /var/volume2 busybox true
|
|||
|
|
|||
|
This command will create the new container with two new volumes that
|
|||
|
exits instantly (`true` is pretty much the smallest,
|
|||
|
simplest program that you can run). Once created you can mount its
|
|||
|
volumes in any other container using the `--volumes-from`
|
|||
|
option; irrespective of whether the container is running or
|
|||
|
not.
|
|||
|
|
|||
|
Or, you can use the VOLUME instruction in a Dockerfile to add one or
|
|||
|
more new volumes to any container created from that image:
|
|||
|
|
|||
|
# BUILD-USING: docker build -t data .
|
|||
|
# RUN-USING: docker run -name DATA data
|
|||
|
FROM busybox
|
|||
|
VOLUME ["/var/volume1", "/var/volume2"]
|
|||
|
CMD ["/bin/true"]
|
|||
|
|
|||
|
### 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, its best to
|
|||
|
create a named Data Volume Container, and then to mount the data from
|
|||
|
it.
|
|||
|
|
|||
|
Create a named container with volumes to share (`/var/volume1`
|
|||
|
and `/var/volume2`):
|
|||
|
|
|||
|
$ docker run -v /var/volume1 -v /var/volume2 -name DATA busybox true
|
|||
|
|
|||
|
Then mount those data volumes into your application containers:
|
|||
|
|
|||
|
$ docker run -t -i -rm -volumes-from DATA -name client1 ubuntu bash
|
|||
|
|
|||
|
You can use multiple `-volumes-from` parameters to
|
|||
|
bring together multiple data volumes from multiple containers.
|
|||
|
|
|||
|
Interestingly, you can mount the volumes that came from the
|
|||
|
`DATA` container in yet another container via the
|
|||
|
`client1` middleman container:
|
|||
|
|
|||
|
$ docker run -t -i -rm -volumes-from client1 -name client2 ubuntu bash
|
|||
|
|
|||
|
This allows you to abstract the actual data source from users of that
|
|||
|
data, similar to
|
|||
|
[*ambassador\_pattern\_linking*](../ambassador_pattern_linking/#ambassador-pattern-linking).
|
|||
|
|
|||
|
If you remove containers that mount volumes, including the initial DATA
|
|||
|
container, or the middleman, the volumes will not be deleted until there
|
|||
|
are no containers still referencing those volumes. This allows you to
|
|||
|
upgrade, or effectively migrate data volumes between containers.
|
|||
|
|
|||
|
### Mount a Host Directory as a Container Volume:
|
|||
|
|
|||
|
-v=[]: Create a bind mount with: [host-dir]:[container-dir]:[rw|ro].
|
|||
|
|
|||
|
You must specify an absolute path for `host-dir`. If
|
|||
|
`host-dir` is missing from the command, then docker
|
|||
|
creates a new volume. If `host-dir` is present but
|
|||
|
points to a non-existent directory on the host, Docker will
|
|||
|
automatically create this directory and use it as the source of the
|
|||
|
bind-mount.
|
|||
|
|
|||
|
Note that this is not available from a Dockerfile due the portability
|
|||
|
and sharing purpose of it. The `host-dir` volumes
|
|||
|
are entirely host-dependent and might not work on any other machine.
|
|||
|
|
|||
|
For example:
|
|||
|
|
|||
|
sudo docker run -t -i -v /var/logs:/var/host_logs:ro ubuntu bash
|
|||
|
|
|||
|
The command above mounts the host directory `/var/logs`
|
|||
|
into the container with read only permissions as
|
|||
|
`/var/host_logs`.
|
|||
|
|
|||
|
New in version v0.5.0.
|
|||
|
|
|||
|
### Note for OS/X users and remote daemon users:
|
|||
|
|
|||
|
OS/X users run `boot2docker` to create a minimalist
|
|||
|
virtual machine running the docker daemon. That virtual machine then
|
|||
|
launches docker commands on behalf of the OS/X command line. The means
|
|||
|
that `host directories` refer to directories in the
|
|||
|
`boot2docker` virtual machine, not the OS/X
|
|||
|
filesystem.
|
|||
|
|
|||
|
Similarly, anytime when the docker daemon is on a remote machine, the
|
|||
|
`host directories` always refer to directories on
|
|||
|
the daemon’s machine.
|
|||
|
|
|||
|
### Backup, restore, or migrate data volumes
|
|||
|
|
|||
|
You cannot back up volumes using `docker export`,
|
|||
|
`docker save` and `docker cp`
|
|||
|
because they are external to images. Instead you can use
|
|||
|
`--volumes-from` to start a new container that can
|
|||
|
access the data-container’s volume. For example:
|
|||
|
|
|||
|
$ sudo docker run -rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
|
|||
|
|
|||
|
- `-rm` - remove the container when it exits
|
|||
|
- `--volumes-from DATA` - attach to the volumes
|
|||
|
shared by the `DATA` container
|
|||
|
- `-v $(pwd):/backup` - bind mount the current
|
|||
|
directory into the container; to write the tar file to
|
|||
|
- `busybox` - a small simpler image - good for
|
|||
|
quick maintenance
|
|||
|
- `tar cvf /backup/backup.tar /data` - creates an
|
|||
|
uncompressed tar file of all the files in the `/data`
|
|||
|
directory
|
|||
|
|
|||
|
Then to restore to the same container, or another that you’ve made
|
|||
|
elsewhere:
|
|||
|
|
|||
|
# create a new data container
|
|||
|
$ sudo docker run -v /data -name DATA2 busybox true
|
|||
|
# untar the backup files into the new container's data volume
|
|||
|
$ sudo docker run -rm --volumes-from DATA2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
|
|||
|
data/
|
|||
|
data/sven.txt
|
|||
|
# compare to the original container
|
|||
|
$ sudo docker run -rm --volumes-from DATA -v `pwd`:/backup busybox ls /data
|
|||
|
sven.txt
|
|||
|
|
|||
|
You can use the basic techniques above to automate backup, migration and
|
|||
|
restore testing using your preferred tools.
|
|||
|
|
|||
|
## Known Issues
|
|||
|
|
|||
|
- [Issue 2702](https://github.com/dotcloud/docker/issues/2702):
|
|||
|
"lxc-start: Permission denied - failed to mount" could indicate a
|
|||
|
permissions problem with AppArmor. Please see the issue for a
|
|||
|
workaround.
|
|||
|
- [Issue 2528](https://github.com/dotcloud/docker/issues/2528): the
|
|||
|
busybox container is used to make the resulting container as small
|
|||
|
and simple as possible - whenever you need to interact with the data
|
|||
|
in the volume you mount it into another container.
|
|||
|
|