Docker volumes are used to store persistent data separately from your containers. Data that’s kept in a volume remains accessible after your containers stop, allowing you to containerize stateful workloads.
Although volumes outlive containers, this isn’t enough protection for production applications. You should back up your volumes so you can recover them after a disaster. Creating regular volume backups ensures you’re able to restore your environment if your Docker host is compromised or data is accidentally deleted.
Managing Volume Backups
Docker doesn’t have a built-in mechanism for backing up volumes or exporting their contents. You need to set up your own solution to access the volume and copy its data to your backup destination.
Creating a temporary container that mounts the volume you need to back up is usually the easiest way to proceed. Add the --volumes-from
flag to a docker run
command to automatically mount an existing container’s volumes into your backup container. You can then use tools such as tar
and gzip
to deposit an archive of the volume’s content into your working directory.
Here’s a complete example of this technique:
# Create a container that stores data in the "mysql_data" volume
docker run -d
--name mysql
-v mysql_data:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=mysql
mysql:8
# Start a temporary container to back up the "mysql_data" volume
docker run --rm
--volumes-from mysql
-v $PWD:/backup-dir
ubuntu tar cvf /backup-dir/mysql-backup.tar /var/lib/mysql
The --volumes-from
flag means the temporary backup container receives access to the mysql
container’s volumes. The /var/lib/mysql
directory inside the backup container exposes the volume’s content because this is the path used by the mysql
container. Tarring the path will produce an archive of your volume that you can use as a backup. It gets deposited into your working directory because of the bind mount that’s set up by the -v
flag.
The --rm
flag will remove the backup container as soon as the command completes. This leaves the archive in your working directory, ready to be moved to long-term storage. You can automate backup creation by adding the docker run
command as a cron task.
Restoring Your Backup
You can use a similar technique to restore your backup. When you’re replacing the contents of an existing volume, create another temporary container with the volume and a bind mount to your backup archive. Extract the contents of the archive into the volume’s mount path.
$ docker run --rm
--volumes-from mysql
-v $PWD:/backup-dir
bash -c "cd /var/lib/mysql && tar xvf /backup-dir/mysql-backup.tar"
This can be risky if containers are actively using the volume. Overwriting files that are in use could cause errors and unexpected behavior. You can use the docker stop
command to temporarily halt your containers before bringing them back up with docker start
.
$ docker stop mysql
# Restore the backup
# ...
$ docker start mysql
Create the volume before you start your container if you’re restoring a backup to a new host:
$ docker volume create new_volume
Then mount this volume to your temporary container:
docker run --rm
-v new_volume:/var/lib/mysql
-v $PWD:/backup-dir
ubuntu tar cvf /backup-dir/mysql-backup.tar /var/lib/mysql
Starting your application container with the same volume will provide access to the files you’ve restored:
docker run -d
--name mysql
-v new_volume:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=mysql
mysql:8
Testing these procedures lets you check your backups will be usable if you ever face a disaster.
Backing Up Volumes Directly
The procedure outlined above is the recommended way to back up Docker volumes. However some situations could be better served by directly copying content from where volumes are stored on your host’s filesystem.
You’ll usually find the content of your volumes in /var/lib/docker/volumes
. Each volume gets its own subdirectory, such as /var/lib/docker/volumes/mysql
. Within this top-level path you’ll find a _data
folder which contains all the files stored inside the volume.
Archiving the /var/lib/docker/volumes
directory can be a convenient way to quickly backup everything on your host. You’ll need to use sudo
though because everything under this path is owned by root
.
Backing up volumes in this way isn’t recommended for regular use because it’s not portable across installations. Docker’s volume driver system means volume data won’t necessarily be stored on your host’s filesystem – it could be on a network share or another remote location. This technique should only be attempted when you want a quick backup before you run maintenance on a specific machine.
Summary
Docker volumes need to be treated with care because they contain your application’s persistent data. Creating regular back ups will protect you from data loss in case your host is compromised or an errant container process deletes files by mistake.
While you can create backups by archiving Docker’s installation directory, this should be avoided wherever possible. Temporary backup containers may seem cumbersome but they can be easily scripted and provide predictable results across volume drivers.
Once you’ve created a volume backup archive, remember to upload it to remote storage as soon as possible. A backup stored on the machine it originates from will be no help if you lose access or a hardware failure occurs.