24

I'm using Docker to deploy some services on a CentOS 6.4 server, and I'm trying to figure out how to properly backup data they generate.

For example, one of the services is a web application where users can upload files. For this container, I have a /files volume which I want to backup. Host mounts looks like they are somewhat frowned upon, because such mount is in no way portable — as said in this blog post and the docker documentation for volumes.

I know from the same blog post that I don't need a host mount to access the files in a volume, I can use docker inspect to find out where the files are.

But here's my problem: I was thinking about backing up just the dockerfiles needed to build the containers and the volumes associated with them. In the likely event that I have to restore everything from the backup, how would I go about knowing which volume directory corresponds to which container? Rebuilding the container causes the id and the volume path to change, so I would need some extra information to match them. What else, if anything, should I backup to be able to actually restore everything?

fcoelho
  • 343
  • 1
  • 2
  • 6

2 Answers2

25

You're right. Since you can have multiple containers with volumes on their own, you need to keep track which volume corresponds to which container. How to do that depends on your setup: I use the name -data for the data container, so it's obvious to which container a image belongs. That way it can be backed up like this:

VOLUME=`docker inspect $NAME-data | jq '.[0].Volumes["/path/in/container"]'`
tar -C $VOLUME . -czvf $NAME.tar.gz

Now you just need to rebuild your image and recreate your data container:

cat $NAME.tar.gz | docker run -name $NAME-data -v /path/in/container \
                              -i busybox tar -C /path/int/container -xzf -

So this means you need to backup:

  • Dockerfile
  • volume
  • volume path in container
  • name of the container the volume belongs to

Update: In the meanwhile I created a tool to backup containers and their volume(s) (container(s)): https://github.com/discordianfish/docker-backup and a backup image that can create backups and push them to s3: https://github.com/discordianfish/docker-lloyd

  • That's a fair compromise, thanks. Is there a clear advantage of using a separate container for data? – fcoelho Feb 19 '14 at 19:20
  • This again really depends on your setup. It make sense to use a data container because you can easily refer to it by using 'volumes-from' and have all the internals abstracted away: You just attach volumes from container to other containers instead of thinking in terms of path and mount points. – Johannes 'fish' Ziemke Feb 24 '14 at 11:14
  • I have this error invalid option -- z. It seems that the default tar in busybox doesn't support this. – Dzung Nguyen May 18 '14 at 15:24
  • 6
    jq is very cool, but rather than introducing a dependency, why not use `docker inspect`s built in templating like so: `VOLUME=$( docker inspect -f '{{index .Volumes "/path/in/container"}}' "${NAME}-data" )`. It's probably also wise to remind people not to expect to back up files this way while they are actively in use (e.g. databases). – mc0e Jul 29 '15 at 07:52
  • Thanks for teaching me about [jq](http://manpages.ubuntu.com/manpages/trusty/en/man1/jq.1.html)! – jpaugh Nov 03 '16 at 01:27
  • 2
    In Docker 1.8 the format has changed — `Volumes` are gone and there are `Mounts` instead with different structure. We need to do a little bit more work with `range` to find the mount point we are interested in `VOLUME=$(docker inspect --format '{{ range .Mounts }}{{ if eq .Destination "/path/in/container" }}{{ .Source }}{{ end }}{{ end }}' "${NAME}-data")` – Jarek Przygódzki Sep 08 '17 at 10:30
7

In newer Docker (tested in 1.9.1, build 9894698) you can use the cp command.

Here is an example how to copy a directory from the container to the host:

docker cp wordpress:/var/www/html backups/wordpress.`date +"%Y%m%d"`/

Here is an example how to copy a directory from the container to a tar file:

docker cp wordpress:/var/www/html - > backups/wordpress.`date +"%Y%m%d"`.tar

Last but not least an example how to copy a directory from the container to a tar.gz file:

docker cp wordpress:/var/www/html - | gzip > backups/wordpress.`date +"%Y%m%d"`.tar.gz
czerasz
  • 547
  • 1
  • 8
  • 14
  • 2
    `docker cp` sends everything over the network. It's something you want to avoid especially if your Docker volume is already a btrfs volume. – Jarek Przygódzki Sep 08 '17 at 10:34
  • 2
    The question mentions backup and **restore**. A restore example in this answer using `docker cp` would be nice. – MadMike Nov 01 '17 at 10:31