Backup & Restore
The backup pattern
Section titled “The backup pattern”Docker volumes live inside Docker’s managed storage area. You cannot simply cp them from the host. The idiomatic way to back up a volume is to spin up a throwaway container that mounts both the source volume and a bind-mounted backup directory, then uses tar to archive the volume contents.
docker run --rm \ -v mydata:/data \ -v $(pwd):/backup \ alpine \ tar czf /backup/mydata-backup.tgz -C /data .Breaking this down:
| Part | Meaning |
|---|---|
--rm | Remove the container immediately after it exits |
-v mydata:/data | Mount the volume to back up at /data |
-v $(pwd):/backup | Mount the current host directory at /backup (the archive lands here) |
alpine | Minimal image — no extra dependencies needed |
tar czf /backup/mydata-backup.tgz -C /data . | Create a compressed archive of everything in /data |
After the command, mydata-backup.tgz exists on your host in the current directory.
Restoring a volume
Section titled “Restoring a volume”To restore from the archive into a volume (creating the volume if it does not exist):
# Create a fresh (or existing) volume to restore intodocker volume create mydata-restored
# Unpack the archive into the volumedocker run --rm \ -v mydata-restored:/data \ -v $(pwd):/backup \ alpine \ tar xzf /backup/mydata-backup.tgz -C /datatar xzf extracts the archive. -C /data changes into /data before extracting, so the files land directly in the volume root.
Migrating a volume to another host
Section titled “Migrating a volume to another host”Volume migration is backup + copy + restore:
- Back up on the source host (command above — produces
mydata-backup.tgz). - Copy the archive to the target host:
scp mydata-backup.tgz user@target:/home/user/. - Restore on the target host using the restore command above.
The target does not need to know anything about the source host’s Docker setup. The volume is just a tar archive at transfer time.
Backing up a running container’s volume safely
Section titled “Backing up a running container’s volume safely”If possible, stop the container before backing up to avoid a mid-write inconsistency:
docker stop myappdocker run --rm -v myapp-data:/data -v $(pwd):/backup alpine tar czf /backup/myapp-data.tgz -C /data .docker start myappFor databases with their own backup tools (e.g., pg_dump, mysqldump), prefer the database-native dump over a raw volume tar — it produces a consistent snapshot regardless of buffered writes.
Hands-on practice
Section titled “Hands-on practice”The snippet below creates a volume, writes data to it, backs it up to a tar archive, creates a new empty volume, restores the archive into it, and verifies the data is intact.
# 1. Create a source volume and populate it
docker volume create source-vol
docker run --rm -v source-vol:/data alpine sh -c "echo 'important data' > /data/record.txt && echo 'more data' > /data/extra.txt"
# 2. Back up the volume to the current directory
docker run --rm -v source-vol:/data -v $(pwd):/backup alpine tar czf /backup/source-vol.tgz -C /data .
# 3. Verify the archive exists on the host
ls -lh source-vol.tgz
# 4. Create a new volume and restore into it
docker volume create restored-vol
docker run --rm -v restored-vol:/data -v $(pwd):/backup alpine tar xzf /backup/source-vol.tgz -C /data
# 5. Verify restored data
docker run --rm -v restored-vol:/data alpine ls /data
docker run --rm -v restored-vol:/data alpine cat /data/record.txt
# 6. Clean up
docker volume rm source-vol restored-vol
rm source-vol.tgz