How to Copy Docker images from one host to another host?
Docker uses prebuilt images to run containers. If there's a need to run a particular container on multiple hosts, we first need to ensure that the required container image is present on all hosts. The container images can vary in size and their actual size depends upon the type of packages present in the container.
If we’re working with large sized images in an environment with low network bandwidth, pulling container images from online registries can be time consuming. In such cases, we need to avoid accessing external registries frequently and find a way to copy images locally between hosts.
Pulling and saving docker images
When running containers through docker, we specify the image to be used. The image is downloaded from a container image registry and is then stored locally on the host. This gives us two major benefits.
- First, we avoid downloading the same image repeatedly.
- Secondly, as we have a local copy of the image available, we can minimize the deployment time for a container. Any custom container images we build are also stored in the same local storage.
When working in a production environment, we can often come across scenarios where a developer finishes testing a custom container image and needs to transfer this image to another developer in either a development or production environment. This can be achieved in multiple ways. We’ll discuss these methods one by one.
Copying docker images between hosts
The following methods can be used to copy docker images between hosts:
- Using docker save
- Using docker save with native ssh command
- Using docker-push-ssh utility
- Using docker machine save
- Using docker machine scp
- Conclusion
Prerequisites
Any Linux distribution with docker and docker machine installation will work for the following tutorial. Docker machine can be installed by following this link. The docker-push-ssh utility can be installed by following this link.
1. Using docker save
Once an image has been pulled from an external registry and saved on local storage. These images from the local storage can be saved to a tar file using the docker save command. The generated file is not a regular TAR archive; it contains image metadata and preserves the original image layers. Using this file, docker can recreate the original image exactly as it was.
Example
In the following example, we’re going to save the alpine image to a tar file using "docker save" and copy it to a remote host using the native SCP command.
1docker save -o alpine.tar alpine
2
3scp alpine.tar user@node2:~/
1user@node1:~$ docker images
2REPOSITORY TAG IMAGE ID CREATED SIZE
3alpine latest e66264b98777 6 weeks ago 5.53MB
4user@node1:~$
5user@node1:~$ docker save -o alpine.tar alpine
6user@node1:~$
7user@node1:~$ scp alpine.tar user@node2:~/
8alpine.tar 100% 5684KB 10.0MB/s 00:00
9user@node1:~$
On the remote host, you can load the image using the “docker load" command.
1docker load -i alpine.tar
1user@node2:~$ docker load -i alpine.tar
224302eb7d908: Loading layer [==================================================>] 5.811MB/5.811MB
3Loaded image: alpine:latest
4user@node2:~$
2. Using docker save with native ssh command
We can also save and transfer docker images by combining "docker save" with the Linux native SSH command. If the image size is large, we can also perform compression on the image to save bandwidth while the image is being transferred over the network. Any compression method can be used for this purpose. The "docker load" command can decompress images saved in bzip2, gzip, and gz. Therefore, it is recommended to save the image in any one of these three formats.
Example
In the following example, we’re going to save the alpine image, compress it using the bzip2 utility on node1, and copy it to node2 using ssh.
1docker save alpine | bzip2 | pv | ssh user@node2 docker load
1user@node1:~$ docker save alpine | bzip2 | pv | ssh user@node2 docker load
22.65MiB 0:00:01 [2.50MiB/s] [ <=> ]
3Loaded image: alpine:latest
4user@node1:~$
5
6user@node2:~$ docker images
7REPOSITORY TAG IMAGE ID CREATED SIZE
8alpine latest e66264b98777 6 weeks ago 5.53MB
9user@node2:~$
3. Using docker-push-ssh utility
docker-push-ssh is a command line utility to push docker images from local to a remote system through an ssh tunnel. It creates a private docker registry on the host, establishes an ssh tunnel and uploads the image over this tunnel. The ssh tunnel is used so that the registry is not exposed to the outside environment.
Example
In the following example, we’re going to push the alpine image using the docker-push-ssh utility. The utility requires that "localhost:5000" is added to the insecure registries list. For connecting to the remote host, key based authentication is required.
1docker-push-ssh -i /user/.ssh/id_rsa user@node2 alpine
1user@node1:~$ docker-push-ssh -i /user/.ssh/id_rsa user@node2 alpine
2[REQUIRED] Ensure localhost:5000 is added to your insecure registries.
3Setting up secure private registry...
4Establishing SSH Tunnel...
5Waiting for SSH Tunnel Initialization...
6Tagging image(s) for push...
7Pushing Image(s) from local host...
8Pushed Image alpine Successfully...
9Pulling and Retagging Image on remote host...
10Pulled Image alpine Successfully...
11Cleaning up...
12user@node1:~$
The image will already be imported on the remote node.
1user@node2:~$ docker images
2REPOSITORY TAG IMAGE ID CREATED SIZE
3registry latest 773dbf02e42e 6 weeks ago 24.1MB
4alpine latest e66264b98777 7 weeks ago 5.53MB
5localhost:5000/alpine latest e66264b98777 7 weeks ago 5.53MB
6user@node2:~$
4. Using docker machine save
If you’re using docker machine and need to copy images between two machines, this can also be done using the save and load commands.
Example
In the following example, we’ll copy the alpine image available on machine1 to machine2.
1docker-machine ls
2
3docker $(docker-machine config machine1) save alpine | docker $(docker-machine config machine2) load
4
5docker-machine ssh machine1
1user@node1:~$ docker-machine ls
2NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
3machine1 * virtualbox Running tcp://192.168.99.100:2376 v19.03.12
4machine2 - virtualbox Running tcp://192.168.99.101:2376 v19.03.12
5user@node1:~$
6user@node1:~$ docker-machine ssh machine1
7 ( '>')
8 /) TC (\ Core is distributed with ABSOLUTELY NO WARRANTY.
9 (/-_--_-\) www.tinycorelinux.net
10
11docker@machine1:~$ docker images
12REPOSITORY TAG IMAGE ID CREATED SIZE
13alpine latest e66264b98777 7 weeks ago 5.53MB
14docker@machine1:~$
1user@node1:~$ docker-machine ssh machine2
2 ( '>')
3 /) TC (\ Core is distributed with ABSOLUTELY NO WARRANTY.
4 (/-_--_-\) www.tinycorelinux.net
5docker@machine2:~$ docker images
6REPOSITORY TAG IMAGE ID CREATED SIZE
7docker@machine2:~$ exit
To copy the image from machine1 to machine2, run the following command. This will also load the image on macine2.
1docker $(docker-machine config machine1) save alpine | docker $(docker-machine config machine2) load
1user@node1:~$ docker $(docker-machine config machine1) save alpine | docker $(docker-machine config machine2) load
224302eb7d908: Loading layer [==================================================>] 5.811MB/5.811MB
3Loaded image: alpine:latest
4user@node1:~$
Verify that the image has been copied and loaded on machine2.
1user@node1:~$ docker-machine ssh machine2
2 ( '>')
3 /) TC (\ Core is distributed with ABSOLUTELY NO WARRANTY.
4 (/-_--_-\) www.tinycorelinux.net
1docker@machine2:~$ docker images
2REPOSITORY TAG IMAGE ID CREATED SIZE
3alpine latest e66264b98777 7 weeks ago 5.53MB
5. Using docker machine scp
You can also use scp with docker machine. If you’ve saved an image using "docker save", you can use the "docker-machine scp" command to copy it to a machine.
Example In the following example, we’ll use "docker-machine scp" to copy image from the local host to machine1.
1docker-machine scp alpine.tar machine1:/tmp
1user@node1:~$ docker-machine ls
2NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
3machine1 * virtualbox Running tcp://192.168.99.100:2376 v19.03.12
4user@node1:~$
5user@node1:~$ docker-machine scp alpine.tar machine1:/tmp
6alpine.tar 100% 5684KB 32.3MB/s 00:00
7user@node1:~$
We’ll now import the image.
1docker-machine ssh machine1 docker load -i alpine.tar
1user@node1:~$ docker-machine ssh machine1 docker load -i alpine.tar
224302eb7d908: Loading layer [==================================================>] 5.811MB/5.811MB
3Loaded image: alpine:latest
4user@node1:~$
6. Conclusion
There are several approaches available for copying docker images between hosts. By using any of these methods, we can avoid the recurring use of external registries and reduce container deployment times.
Posts in this Series
- (docker run -d) Why Does a Docker Container Stop Automatically?
- Attach and detach from Docker's process?
- How I Change Name of My Docker Repository and Rename Images?
- How to set-up Cron Jobs in Docker Containers?
- 4 Ways to copy file from localhost to docker container
- Multiple commands execution in Docker Compose?
- How to push Docker Images to AWS ECR(Elastic Container registry)?
- How to Copy Docker images from one host to another host?
- What is persistent storage in docker and how to manage it
- Docker Installation on MacOS, Linux and Windows
- Docker - ADD, Update, Export Environment variable
- How to fix-Docker docker failed to compute cache key not found
- How to fix docker driver failed programming external connectivity on endpoint webserver?
- How to fix docker error executable file not found in $PATH?
- How to expose port on live containers?
- How to expose multiple ports with Docker?
- How to restart single docker container within multiple docker container?
- How to edit file within Docker container or edit a file after I shell into a Docker container?
- How to fix Error starting docker service Unit not found?
- How to remove old, unused images of Docker?
- How to fix docker error invalid reference format error?
- How to fix requested access to the resource is denied?
- How to fix Docker error cannot delete docker container conflict unable to remove repository reference?
- How to fix docker error no space left on device?
- How to connect localhost from docker container?
- Docker COPY vs Docker ADD?
- 6 Ways to fix - Got permission denied while trying to connect to the Docker daemon socket?
- 6 Ways to fix – Docker COPY failed: stat no source files were specified