How do I transfer Docker containers and named volumes between MX Linux hosts or drives
Gemini
To transfer Docker containers and named volumes between MX Linux hosts or external drives, the most effective approach is to separate the data (named volumes) from the container image/state (or Compose files).
Attempting to copy live directories directly out of /var/lib/docker/ can cause permission issues and corruption if the Docker daemon is running. Instead, export the named volumes into standard compressed tarballs and export custom images using standard Docker mechanisms.
1
Export Named Volumes
Data Preservation
Stop the target container to prevent database writes or file corruption during extraction.
Run a temporary, lightweight Alpine container that mounts your volume as read-only and packages its contents into a compressed tarball in your current working directory:
# Stop the container using the volume
docker stop <container_name>
# Export volume data to a .tar.gz archive
docker run --rm \
-v <volume_name>:/source:ro \
-v "$(pwd)":/backup \
alpine tar czf /backup/<volume_name>.tar.gz -C /source .
Verification: Verify the archive was created and contains your data by listing its contents without extracting:
tar -tzf <volume_name>.tar.gz | head -n 10
2
Export Custom Images (Optional)
Image Portability
If you built custom images locally or modified container filesystems that aren't hosted on a public/private registry, export the image directly to a file:
docker save -o <image_name>.tar <image_name>:<tag>
(Note: If you use standard docker-compose.yml files pointing to public images on Docker Hub/GHCR, you can skip this step and let docker compose pull handle image fetching on the target machine.)
3
Transfer Archives to Target MX Linux Machine or Drive
File Movement
Copy the .tar.gz volume archives, image .tar files, and any docker-compose.yml configurations to your target host using rsync, scp, or a formatted USB drive/external mount:
# Example using rsync over SSH:
rsync -avP <volume_name>.tar.gz user@target-host:/home/user/docker-backups/
4
Restore Named Volumes on Target Host
Data Restoration
On the destination MX Linux system, create the target volume and use another temporary container to unpack the archive into it:
# 1. Create the named volume
docker volume create <volume_name>
# 2. Extract contents into the volume
docker run --rm \
-v <volume_name>:/target \
-v "$(pwd)":/backup \
alpine tar xzf /backup/<volume_name>.tar.gz -C /target
Verification: Confirm the contents were extracted properly into the volume space:
docker run --rm -v <volume_name>:/target alpine ls -la /target
5
Load Images and Spin Up Containers
Execution
If you transferred custom .tar images, import them back into the local Docker daemon:
docker load -i <image_name>.tar
Finally, start your containers pointing to the restored volume name (using your docker run command or docker compose up -d).
MX Linux Permission & Path Notes
- Ensure your user is part of the
dockergroup on both MX Linux systems (sudo usermod -aG docker $USER) so you don't needsudofor standard Docker operations. - If restoring database containers (PostgreSQL, MariaDB, SQLite), always ensure the container is fully stopped prior to step 1. Alternatively, use database-native dumps (e.g.,
pg_dumpormysqldump) for maximum transactional consistency.
You
How can I stream a Docker image directly from one machine to another over SSH without saving a tar file locally first?
Gemini
You can pipe the standard output of docker save directly into docker load over SSH. This streams the image layer by layer across the network without writing a temporary .tar archive to disk on either the source or host machine.
Run this command from your local machine (or source host):
docker save <image_name>:<tag> | ssh user@target-host docker load
How it works:
docker save <image_name>:<tag>writes the uncompressed tar stream of the image directly to standard output (stdout).- The pipe (
|) routesstdoutthrough the encrypted SSH channel. ssh user@target-host docker loadreceives the stream via standard input (stdin) on the target machine and loads the image directly into its local Docker storage engine.
Tips for Faster Transfers
If you are transferring over a LAN or WAN with limited bandwidth, compress the stream on the fly using gzip or zstd before sending it over SSH:
- Using
gzip(standard across all systems):docker save <image_name>:<tag> | gzip | ssh user@target-host "gunzip | docker load" - Using
zstd(faster compression/decompression if installed on both hosts):docker save <image_name>:<tag> | zstd | ssh user@target-host "zstd -d | docker load" - Verification: Once completed, check that the image is present on the target host by running:
ssh user@target-host docker images
You
Move /var/lib/docker
Gemini
Moving /var/lib/docker to a new drive or partition requires stopping the Docker daemon, copying the existing data while preserving absolute permissions and extended attributes, and updating Docker's configuration to point to the new directory.
1
Stop Docker Engine & Create Target Directory
Prerequisite
Stop all running containers and the Docker daemon to avoid file lockups or corruption during copy:
sudo systemctl stop docker.socket
sudo systemctl stop docker
Verify Docker is completely inactive:
sudo systemctl status docker
Create the target directory on your destination drive (replace /mnt/data with your mount point):
sudo mkdir -p /mnt/data/docker
2
Copy /var/lib/docker using rsync
Data Integrity
Copy all content from /var/lib/docker to the new location. Use rsync with -aHAX flags to preserve permissions, ownership, hard links, and extended attributes:
sudo rsync -aHAXv /var/lib/docker/ /mnt/data/docker/
Verification: Confirm that the target directory contains the Docker layout:
sudo ls -la /mnt/data/docker
3
Update daemon.json Data Root
Configuration
Inform the Docker daemon about the new storage location by editing /etc/docker/daemon.json (create the file if it doesn't exist):
sudo nano /etc/docker/daemon.json
Add or update the data-root key:
{
"data-root": "/mnt/data/docker"
}
4
Start Docker and Confirm Directory Path
Restart & Validation
Start the Docker service again:
sudo systemctl start docker
Verification: Query Docker runtime system info to confirm it points to the new path:
docker info | grep "Docker Root Dir"
Expected output: Docker Root Dir: /mnt/data/docker
5
Backup or Delete Original Storage
Cleanup
Once you have verified that your containers, images, and volumes work properly from the new location, rename or remove the old directory to free up disk space on your root drive:
# Rename old directory as safety backup:
sudo mv /var/lib/docker /var/lib/docker.bak
# Or remove it completely once verified:
# sudo rm -rf /var/lib/docker.bak
Mount Point & Storage Caveats
- Filesystem Compatibility: Ensure the target filesystem supports Docker storage drivers (e.g.,
ext4,btrfs, orxfs). Avoid usingNTFSorFATdrives, as missing Linux permissions/symlink support will break container runtimes. - Auto-mount Requirement: If the target directory resides on an external drive or secondary partition, ensure it is configured in
/etc/fstabto mount automatically at boot before thedocker.servicestarts.
What would you like to explore next?