Migrating Docker Containers to a New Server: A ‘Manual’ but Rock-Solid Method

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

Get It Done in 5 Minutes (Quick Start)

Need to quickly move a container from Server A to Server B without the hassle of Docker Hub? Here is the shortest path to get it done in no time. Assume your container is named web_app and the data is in volume web_data.

  1. On the old server: Stop the container gracefully to avoid data corruption during the copy process.
    docker stop web_app
    docker commit web_app web_app_backup
    docker save -o web_app_image.tar web_app_backup
  2. Transfer the file to the new server: Use rsync to leverage compression and resume capabilities if the connection drops.
    rsync -avzP web_app_image.tar [email protected]:/root/
  3. On the new server: Load the image and run it.
    docker load -i web_app_image.tar
    docker run -d --name web_app web_app_backup

That’s the ideal scenario. In reality, if your application uses Volumes (data), moving only the image is like moving to a new house but leaving all your furniture behind.

Why Go Manual When You Have Docker Registry?

Using Docker Hub or a Private Registry is easy. However, in the world of systems administration, you will eventually run into “tough” cases that force you to do it manually:

  • Air-gapped Environments: Servers located in internal networks with no internet access.
  • Strict Security: Images containing sensitive configurations or proprietary source code that are not allowed on any cloud platform.
  • Hotfixes: You happened to jump into a container to fix a few lines of code directly and don’t want to rebuild the Dockerfile from scratch.
  • Save Bandwidth: Moving a 2GB file over a 1Gbps LAN is much faster than uploading and then downloading it from a Registry.

Safe Migration Process: Slow but Steady

Step 1: Packaging the “Shell” (Container Image)

Many people simply docker save the original image from Docker Hub. Error! If you have installed extra tools or modified configurations inside the container, those changes will vanish. The commit command is the key.

# Capture the current state of the container into a new image
docker commit web_app web_app_migrated:v1

# Export to a tar file
docker save -o web_app_migrated.tar web_app_migrated:v1

Note: commit only packages the writable layer; it does not touch the data stored in Volumes.

Step 2: Moving the “Soul” (Volume Data)

Data is the most valuable asset. First, check where the volume is located on the disk:

docker inspect web_app | grep -A 10 "Mounts"

When dealing with these messy JSON blocks, I usually use JSON Formatter to reformat it for easier reading, saving my eyes from hunting for the Source path.

Usually, data is stored in /var/lib/docker/volumes/. Use rsync instead of scp. Why? Because rsync preserves ownership and permissions—critical for databases like MySQL 8.0 to avoid “Permission denied” errors when starting on the new machine.

# Push the data folder to the new server while keeping file permissions intact
rsync -avzP /data/my_app/ [email protected]:/data/my_app/

Handling Large Data (Tens of GBs)

If your volume is around 50GB or more, plain rsync could take hours. My rule of thumb is to use zstd for compression. It is 3 times faster than gzip and offers an excellent compression ratio.

tar -I zstd -cf web_data.tar.zst /var/lib/docker/volumes/my_volume/_data
rsync -avzP web_data.tar.zst [email protected]:/root/

On the new server, after extracting, check the UID/GID. If the old machine used a mysql user with ID 999, the new machine must match so the container can read the files.

A Few Pro Tips

  • Check Disk Space: A 5GB tar file can fill up the /root partition if you’re not careful. Run df -h before executing the commands.
  • Bring Docker Compose Along: Don’t try to memorize a 5-line docker run command. Copy the docker-compose.yml file to the new machine and just update the image name.
  • Verify File Size: Run du -sh on both servers after copying. If there is even a few KB difference, check the rsync logs immediately.
  • Cleanup: Delete the .tar files once done. Don’t let them waste server resources.

Manual Docker migration is not outdated. It is an essential survival skill when you cannot rely on the Cloud or third-party Registries. By being meticulous with rsync and save/load, you will have complete control over your system.

Share: