5 min read

How to Migrate Docker Containers from One Server to Another

How to Migrate Docker Containers from One Server to Another
Photo by Growtika / Unsplash

Docker is a popular tool for creating and running containerised applications. It allows you to deploy your code in a consistent and portable way across different environments. But what if you need to move your Docker containers from one server to another? How can you do that without losing any data or configuration?

In this blog post, I will show you two methods to migrate Docker containers from one Ubuntu server to another. The first method is to use the docker save and docker load commands, which preserve the image history and metadata. The second method uses the docker export and import commands, creating a snapshot of the container’s filesystem. Both methods require you to transfer the container volumes separately, as they are not included in the image or the snapshot.

Method 1: Using docker save and docker load

This method is suitable to keep the image history and metadata, such as the image name, tag, and layers. It also allows you to run the container with the same options as before, such as ports, environment variables, and networks.

To use this method, follow these steps:

  1. Stop the container on the source server with the command docker stop <container_id>, where <container_id>is the ID of the container you want to migrate. You can get the container ID with the command docker ps -a.
  2. Save the container image to a tar file with the command docker save -o <tar_file> <image_name>, where <tar_file> is the name of the tar file you want to create, and <image_name> is the name of the image you want to save. For example, docker save -o myapp.tar myapp:latest.
  3. Copy the tar file to the destination server with a file transfer tool of your choice, such as scprsync, or sftp. For example, scp myapp.tar user@destination:/home/user.
  4. Load the image from the tar file on the destination server with the command docker load -i <tar_file>, where <tar_file> is the name of the tar file you copied. For example, docker load -i myapp.tar.
  5. Run the container from the image on the destination server with the command docker run <options> <image_name>, where <options> are the same options you used to run the container on the source server, and <image_name> is the name of the image you loaded. For example, docker run -d -p 80:80 -e APP_ENV=production myapp:latest.

Method 2: Using docker export and docker import

This method is suitable if you only care about the container’s filesystem and not the image history or metadata. It also allows you to reduce the size of the tar file by excluding unnecessary files. However, it does not preserve container options like ports, environment variables, and networks. You must specify them manually when you run the container on the destination server.

To use this method, follow these steps:

  1. Pause the container on the source server with the command docker pause <container_id>, where <container_id> is the ID of the container you want to migrate. You can get the container ID with the command docker ps -a.
  2. Export the container to a tar file with the command docker export <container_id> -o <tar_file>, where <container_id> is the ID of the container you want to export, and <tar_file> is the name of the tar file you want to create. For example, docker export myapp -o myapp.tar.
  3. Copy the tar file to the destination server with a file transfer tool of your choice, such as scprsync, or sftp. For example, scp myapp.tar user@destination:/home/user.
  4. Import the tar file to an image on the destination server with the command docker import <tar_file> <image_name>, where <tar_file> is the name of the tar file you copied, and <image_name> is the name of the image you want to create. For example, docker import myapp.tar myapp:latest.
  5. Run the container from the image on the destination server with the command docker run <options> <image_name>, where <options> are the options you want to use to run the container, such as ports, environment variables, and networks, and <image_name> is the name of the image you imported. For example, docker run -d -p 80:80 -e APP_ENV=production myapp:latest.

Transferring container volumes

As mentioned earlier, both methods do not include the container volumes in the image or the snapshot. Therefore, you will have to transfer them separately to the destination server. To do that, follow these steps:

  1. Identify the container volumes with the command docker inspect <container_id>, where <container_id> is the ID of the container you want to migrate. You can get the container ID with the command docker ps -a. Look for the Mounts section in the output, and note down the Source and Destination fields for each volume. The Source field is the path on the host where the volume data is stored, and the Destination field is the path inside the container where the volume is mounted.
  2. Copy the volume data from the source server to the destination server with a file transfer tool of your choice, such as scprsync, or sftp. For example, rsync -avz /var/lib/docker/volumes/myapp_data user@destination:/var/lib/docker/volumes.
  3. Create the volume on the destination server with the command docker volume create <volume_name>, where <volume_name> is the name of the volume you want to create. For example, docker volume create myapp_data.
  4. Specify the volume when you run the container on the destination server with the option -v <volume_name>:<destination>, where <volume_name> is the name of the volume you created, and <destination> is the path inside the container where the volume should be mounted. For example, -v myapp_data:/app/data.

Conclusion

In this blog post, I showed you two methods to migrate Docker containers from one Ubuntu server to another. The first method uses the docker save and docker load commands, which preserve the image history and metadata. The second method uses the docker export and import commands, creating a snapshot of the container’s filesystem. Both methods require you to transfer the container volumes separately, as they are not included in the image or the snapshot.

I hope you found this blog post helpful and informative. If you have any questions or feedback, please reach out. Thank you for reading! 😊