Docker is a powerful platform for containerization, but sometimes you need to move images between different hosts – perhaps from a development machine to a production server, or between air-gapped environments. While Docker Hub and other registries are the typical solution, there are scenarios where you don’t want or can’t use them. This tutorial explains how to transfer Docker images directly between hosts without relying on a registry.
Understanding the Approach
The core idea is to package the Docker image into a single archive file, transfer that file using standard file transfer tools, and then unpack it on the destination host. Docker provides commands to save an image to a file and load it from a file.
Saving a Docker Image
The docker save
command takes a Docker image as input and creates a tar archive containing all the layers and metadata necessary to recreate the image.
docker save -o <output_file_path> <image_name>
-o <output_file_path>
: Specifies the path and filename for the output tar archive. It’s important to include the filename; specifying only a directory will not work as expected.<image_name>
: The name of the Docker image you want to save. This can include the tag (e.g.,my-image:latest
) or the image ID.
For example, to save an image named my-app:1.0
to a file called my-app.tar
in your home directory, you would use:
docker save -o /home/user/my-app.tar my-app:1.0
Transferring the Image Archive
Once the image is saved as a tar archive, you can transfer it to the destination host using any standard file transfer tool:
cp
: For copying within the same machine or network filesystem.scp
: Secure Copy – useful for transferring files over SSH.rsync
: A powerful tool for synchronizing files and directories, offering features like incremental transfers and compression. This is often the most efficient option for large images.
For example, using scp
:
scp /home/user/my-app.tar user@destination_host:/tmp/
Loading the Image on the Destination Host
On the destination host, use the docker load
command to import the image from the tar archive.
docker load -i <input_file_path>
-i <input_file_path>
: Specifies the path to the tar archive containing the Docker image.
For example:
docker load -i /tmp/my-app.tar
After running this command, the image will be available in the destination host’s Docker image list. You can verify this by running docker images
.
Optimizing Transfers with Compression
For large images, compressing the tar archive before transferring it can significantly reduce transfer time. You can combine compression and transfer using pipes:
docker save <image_name> | gzip | ssh user@destination_host 'gzip -d | docker load'
This command does the following:
docker save <image_name>
: Saves the image to standard output.gzip
: Compresses the output fromdocker save
.ssh user@destination_host '...'
: Executes the enclosed command on the remote host via SSH.gzip -d
: Decompresses the input on the remote host.docker load
: Loads the decompressed image into Docker.
Alternatively, you can use bzip2
or xz
for potentially better compression ratios (at the cost of increased compression/decompression time). Choose the compression algorithm based on your network speed and CPU resources.
Example with xz
compression
docker save <image_name> | xz | ssh user@destination_host 'xz -d | docker load'
Important Considerations
- Image Tags and Names: Ensure that the image name and tag are consistent between the source and destination hosts.
- File Permissions: Check that the user on the destination host has the necessary permissions to access and load the tar archive.
- Disk Space: Make sure you have enough disk space on both the source and destination hosts to store the tar archive and the image layers.