How to Backup and Restore Docker Volumes Between Machines
When working with Docker, persistent data is often stored in volumes. Unlike container filesystems, volumes survive restarts and recreations. But what if you need to move this data from one machine to another?
Here’s a quick and reliable way to back up a Docker volume on one computer and restore it on another.
I find this use case very often when I’m working on a new project that changes the database schema and I need to maintain existing code with old schema.
To keep both the new project and the existing code working, I create a new volume from my backup, attach it to my docker-compose database service and work on the new project. When I need to go back to the existing code for a bug fix or enhancement, it is a one line change in the docker-compose.
Step 1: Back Up the Docker Volume
Let’s say you have a volume named db_data that you want to back up. Run this command from the terminal in your project directory:
docker run --rm \
-v db_data:/source \
-v $(pwd):/backup \
busybox \
tar czf /backup/db_data.tar.gz -C /source .
What it does?
--rm
: Automatically removes the container after it finishes.-v db_data:/source
: Mounts the source Docker volume.-v $(pwd):/backup
: Mounts your current directory to write the backup file.busybox
: A tiny Linux container that includes tar.tar czf
: Creates a compressed tarball of the volume contents.
This will create a file called db_data.tar.gz
in your current directory.
Step 2: Check the Backup Contents
Want to double-check what’s inside the archive?
Use:
tar -tzf db_data.tar.gz | head
This lists the first few files inside the backup, so you know it’s not empty or corrupt.
Step 3: Move the Backup to the New Machine
Transfer db_data.tar.gz
to the new machine. You can use scp, ftp, a USB drive, cloud storage, AirDrop, whatever works for you.
Example:
scp db_data.tar.gz v@mac2:\~/Downloads
Step 4: Restore the Docker Volume
On the new machine, create an empty volume with the same name:
docker volume create db_data
Now restore the backup into that volume:
docker run --rm \
-v db_data:/restore \
-v \~/Downloads:/backup \
busybox \
tar xzf /backup/db_data.tar.gz -C /restore
What it does?
-v db_data:/restore
: Mounts the target volume to write data into.-v ~/Downloads:/backup
: Mounts the directory where the tarball lives.tar xzf
: Extracts the archive into the volume.
Step 5: Verify the Restore
Option 1: Use Docker Desktop, Go to Volumes and explore db_data
visually.
Option 2: Inspect from the terminal:
docker run --rm -v db_data:/data busybox ls /data
This lets you see the contents directly from the CLI.
Bonus: Use the dvbackup
Script
Source code: github.com/vk4s/docker-volume-backup
If you find yourself doing this often, you might want to use the dvbackup
script (I have created it), which simplifies the entire process:
- Install the script: (always check the contents of any script before running it in your system).
curl -O https://raw.githubusercontent.com/vk4s/docker-volume-backup/main/dvbackup
chmod +x dvbackup
./dvbackup install
- Backup volumes:
dvbackup backup ./backups db_data postgres_data
- Restore volumes (with same names):
dvbackup restore ./backups db_data postgres_data
- Restore with new names:
dvbackup restore ./backups new_db=db_data new_pg=postgres_data
The script provides following features:
- Automatic validation of volume names
- Safe handling (won’t overwrite existing volumes)
- Support for multiple volumes in one command
- Cross-platform compatibility (macOS, Linux, Windows Git Bash)
It’s a great tool for developers who frequently need to move Docker volumes between machines or create backups of their data.
Docker Volume Cheatsheet
Basic Volume Operations
# Create a new volume
docker volume create my_volume
# List all volumes
docker volume ls
# Inspect a volume
docker volume inspect my_volume
# Remove a volume
docker volume rm my_volume
# Remove all unused volumes
docker volume prune
Using Volumes with Containers
# Mount a volume to a container
docker run -v my_volume:/data my_image
# Mount a volume with read-only access
docker run -v my_volume:/data:ro my_image
# Mount a specific directory as a volume
docker run -v /host/path:/container/path my_image
# Use a named volume with docker-compose
# volumes:
# my_volume:
# name: my_volume
Volume Backup and Restore
Checkout dvbackup
above.
Volume Management
# Check volume disk usage
docker system df -v
# Backup all volumes in a project
docker-compose down
dvbackup backup ./backups $(docker volume ls -q --filter name=project_name)
# Migrate volumes between hosts
dvbackup backup ./backups volume_name
# Transfer backup file to new host
dvbackup restore ./backups volume_name
Common Volume Patterns
# Database volumes
docker volume create postgres_data
docker run -v postgres_data:/var/lib/postgresql/data postgres
# Application data
docker volume create app_data
docker run -v app_data:/app/data my_app
# Configuration volumes
docker volume create app_config
docker run -v app_config:/app/config my_app
# Cache volumes
docker volume create app_cache
docker run -v app_cache:/app/cache my_app