2014-05-21 17:05:19 -04:00
|
|
|
page_title: Managing Data in Containers
|
|
|
|
page_description: How to manage data inside your Docker containers.
|
|
|
|
page_keywords: Examples, Usage, volume, docker, documentation, user guide, data, volumes
|
|
|
|
|
|
|
|
# Managing Data in Containers
|
|
|
|
|
2014-06-16 03:52:23 -04:00
|
|
|
So far we've been introduced to some [basic Docker
|
2014-05-21 17:05:19 -04:00
|
|
|
concepts](/userguide/usingdocker/), seen how to work with [Docker
|
|
|
|
images](/userguide/dockerimages/) as well as learned about [networking
|
|
|
|
and links between containers](/userguide/dockerlinks/). In this section
|
|
|
|
we're going to discuss how you can manage data inside and between your
|
|
|
|
Docker containers.
|
|
|
|
|
|
|
|
We're going to look at the two primary ways you can manage data in
|
|
|
|
Docker.
|
|
|
|
|
|
|
|
* Data volumes, and
|
|
|
|
* Data volume containers.
|
|
|
|
|
|
|
|
## Data volumes
|
|
|
|
|
|
|
|
A *data volume* is a specially-designated directory within one or more
|
|
|
|
containers that bypasses the [*Union File
|
2015-03-06 09:36:23 -05:00
|
|
|
System*](/terms/layer/#union-file-system). Data volumes provide several
|
|
|
|
useful features for persistent or shared data:
|
2014-05-21 17:05:19 -04:00
|
|
|
|
2015-03-06 09:36:23 -05:00
|
|
|
- Volumes are initialized when a container is created. If the container's
|
|
|
|
base image contains data at the specified mount point, that data is
|
|
|
|
copied into the new 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.
|
2015-02-12 19:17:33 -05:00
|
|
|
|
|
|
|
Data volumes are designed to persist data, independent of the container's life
|
2015-03-06 09:36:23 -05:00
|
|
|
cycle. Docker therefore *never* automatically delete volumes when you remove
|
|
|
|
a container, nor will it "garbage collect" volumes that are no longer
|
|
|
|
referenced by a container.
|
2014-05-21 17:05:19 -04:00
|
|
|
|
|
|
|
### Adding a data volume
|
|
|
|
|
|
|
|
You can add a data volume to a container using the `-v` flag with the
|
2014-12-04 23:31:54 -05:00
|
|
|
`docker create` and `docker run` command. You can use the `-v` multiple times
|
|
|
|
to mount multiple data volumes. Let's mount a single volume now in our web
|
|
|
|
application container.
|
2014-05-21 17:05:19 -04:00
|
|
|
|
|
|
|
$ sudo 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.
|
|
|
|
|
|
|
|
### Mount a Host Directory as a Data Volume
|
|
|
|
|
|
|
|
In addition to creating a volume using the `-v` flag you can also mount a
|
2014-12-03 20:12:16 -05:00
|
|
|
directory from your Docker daemon's host into a container.
|
|
|
|
|
|
|
|
> **Note:**
|
|
|
|
> If you are using Boot2Docker, your Docker daemon only has limited access to
|
|
|
|
> your OSX/Windows filesystem. Boot2Docker tries to auto-share your `/Users`
|
|
|
|
> (OSX) or `C:\Users` (Windows) directory - and so you can mount files or directories
|
|
|
|
> using `docker run -v /Users/<path>:/<container path> ...` (OSX) or
|
|
|
|
> `docker run -v /c/Users/<path>:/<container path ...` (Windows). All other paths
|
|
|
|
> come from the Boot2Docker virtual machine's filesystem.
|
2014-05-21 17:05:19 -04:00
|
|
|
|
|
|
|
$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py
|
|
|
|
|
2014-11-25 02:41:49 -05:00
|
|
|
This will mount the host directory, `/src/webapp`, into the container at
|
|
|
|
`/opt/webapp`.
|
|
|
|
|
|
|
|
> **Note:**
|
2015-01-30 12:31:41 -05:00
|
|
|
> If the path `/opt/webapp` already exists inside the container's image, its
|
2014-11-25 02:41:49 -05:00
|
|
|
> contents will be replaced by the contents of `/src/webapp` on the host to stay
|
|
|
|
> consistent with the expected behavior of `mount`
|
|
|
|
|
|
|
|
This is very useful for testing, for example we can
|
2014-05-21 17:05:19 -04:00
|
|
|
mount our source code inside the container and see our application at work as
|
|
|
|
we change the source code. The directory on the host must be specified as an
|
|
|
|
absolute path and if the directory doesn't exist Docker will automatically
|
|
|
|
create it for you.
|
|
|
|
|
2014-06-08 14:31:10 -04:00
|
|
|
> **Note:**
|
2014-07-20 20:05:37 -04:00
|
|
|
> This is not available from a `Dockerfile` due to the portability
|
2014-12-03 20:12:16 -05:00
|
|
|
> and sharing purpose of built images. The host directory is, by its nature,
|
|
|
|
> host-dependent, so a host directory specified in a `Dockerfile` probably
|
2014-07-20 20:05:37 -04:00
|
|
|
> wouldn't work on all hosts.
|
2014-05-21 17:05:19 -04:00
|
|
|
|
|
|
|
Docker defaults to a read-write volume but we can also mount a directory
|
|
|
|
read-only.
|
|
|
|
|
|
|
|
$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp:ro training/webapp python app.py
|
|
|
|
|
|
|
|
Here we've mounted the same `/src/webapp` directory but we've added the `ro`
|
|
|
|
option to specify that the mount should be read-only.
|
|
|
|
|
2014-07-04 13:52:10 -04:00
|
|
|
### Mount a Host File as a Data Volume
|
|
|
|
|
2014-07-09 03:21:31 -04:00
|
|
|
The `-v` flag can also be used to mount a single file - instead of *just*
|
|
|
|
directories - from the host machine.
|
2014-07-04 13:52:10 -04:00
|
|
|
|
|
|
|
$ sudo docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
|
|
|
|
|
2014-07-07 07:01:04 -04:00
|
|
|
This will drop you into a bash shell in a new container, you will have your bash
|
2014-07-09 03:21:31 -04:00
|
|
|
history from the host and when you exit the container, the host will have the
|
2014-07-07 07:01:04 -04:00
|
|
|
history of the commands typed while in the container.
|
2014-07-04 13:52:10 -04:00
|
|
|
|
|
|
|
> **Note:**
|
2014-07-07 07:01:04 -04:00
|
|
|
> Many tools used to edit files including `vi` and `sed --in-place` may result
|
2014-07-09 03:21:31 -04:00
|
|
|
> in an inode change. Since Docker v1.1.0, this will produce an error such as
|
2014-07-07 07:01:04 -04:00
|
|
|
> "*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.
|
2014-07-04 13:52:10 -04:00
|
|
|
|
2014-05-21 17:05:19 -04:00
|
|
|
## 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.
|
2014-12-04 23:31:54 -05:00
|
|
|
While this container doesn't run an application, it reuses the `training/postgres`
|
2015-01-31 11:02:11 -05:00
|
|
|
image so that all containers are using layers in common, saving disk space.
|
2014-05-21 17:05:19 -04:00
|
|
|
|
2015-03-06 15:26:28 -05:00
|
|
|
$ sudo docker create -v /dbdata --name dbdata training/postgres /bin/true
|
2014-05-21 17:05:19 -04:00
|
|
|
|
|
|
|
You can then use the `--volumes-from` flag to mount the `/dbdata` volume in another container.
|
|
|
|
|
2014-06-24 05:24:45 -04:00
|
|
|
$ sudo docker run -d --volumes-from dbdata --name db1 training/postgres
|
2014-05-21 17:05:19 -04:00
|
|
|
|
|
|
|
And another:
|
|
|
|
|
2014-06-24 05:24:45 -04:00
|
|
|
$ sudo docker run -d --volumes-from dbdata --name db2 training/postgres
|
2014-05-21 17:05:19 -04:00
|
|
|
|
2015-03-06 09:36:23 -05:00
|
|
|
In this case, if the `postgres` image contained a directory called `/dbdata`
|
|
|
|
then mounting the volumes from the `dbdata` container hides the
|
|
|
|
`/dbdata` files from the `postgres` image. The result is only the files
|
|
|
|
from the `dbdata` container are visible.
|
|
|
|
|
2014-06-23 11:08:34 -04:00
|
|
|
You can use multiple `--volumes-from` parameters to bring together multiple data
|
2014-05-21 17:05:19 -04:00
|
|
|
volumes from multiple containers.
|
|
|
|
|
|
|
|
You can also extend the chain by mounting the volume that came from the
|
|
|
|
`dbdata` container in yet another container via the `db1` or `db2` containers.
|
|
|
|
|
2014-06-24 05:24:45 -04:00
|
|
|
$ sudo docker run -d --name db3 --volumes-from db1 training/postgres
|
2014-05-21 17:05:19 -04:00
|
|
|
|
|
|
|
If you remove containers that mount volumes, including the initial `dbdata`
|
|
|
|
container, or the subsequent containers `db1` and `db2`, the volumes will not
|
2014-08-28 16:41:17 -04:00
|
|
|
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
|
2014-05-21 17:05:19 -04:00
|
|
|
allows you to upgrade, or effectively migrate data volumes between containers.
|
|
|
|
|
2015-02-12 19:17:33 -05:00
|
|
|
> **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.
|
|
|
|
> Dangling volumes are difficult to get rid of and can take up a large amount
|
|
|
|
> of disk space. We're working on improving volume management and you can check
|
|
|
|
> progress on this in [pull request #8484](https://github.com/docker/docker/pull/8484)
|
|
|
|
|
2014-05-21 17:05:19 -04:00
|
|
|
## Backup, restore, or migrate data volumes
|
|
|
|
|
|
|
|
Another useful function we can perform with volumes is use them for
|
|
|
|
backups, restores or migrations. We do this by using the
|
|
|
|
`--volumes-from` flag to create a new container that mounts that volume,
|
|
|
|
like so:
|
|
|
|
|
|
|
|
$ sudo docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
|
|
|
|
|
2014-07-28 16:39:17 -04:00
|
|
|
Here we've launched a new container and mounted the volume from the
|
2014-05-21 17:05:19 -04:00
|
|
|
`dbdata` container. We've then mounted a local host directory as
|
|
|
|
`/backup`. Finally, we'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.
|
|
|
|
|
2014-07-25 03:06:38 -04:00
|
|
|
You could then restore it to the same container, or another that you've made
|
2014-05-21 17:05:19 -04:00
|
|
|
elsewhere. Create a new container.
|
|
|
|
|
2014-06-25 01:53:59 -04:00
|
|
|
$ sudo docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
|
2014-05-21 17:05:19 -04:00
|
|
|
|
|
|
|
Then un-tar the backup file in the new container's data volume.
|
|
|
|
|
|
|
|
$ sudo docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
|
|
|
|
|
2014-09-11 02:55:45 -04:00
|
|
|
You can use the techniques above to automate backup, migration and
|
2014-05-21 17:05:19 -04:00
|
|
|
restore testing using your preferred tools.
|
|
|
|
|
|
|
|
# Next steps
|
|
|
|
|
|
|
|
Now we've learned a bit more about how to use Docker we're going to see how to
|
|
|
|
combine Docker with the services available on
|
2014-06-01 16:48:04 -04:00
|
|
|
[Docker Hub](https://hub.docker.com) including Automated Builds and private
|
2014-05-21 17:05:19 -04:00
|
|
|
repositories.
|
|
|
|
|
2014-06-01 16:48:04 -04:00
|
|
|
Go to [Working with Docker Hub](/userguide/dockerrepos).
|
2014-05-21 17:05:19 -04:00
|
|
|
|