How to move Docker images between hosts

Don't "re-pull" the universe if you are at a low bandwidth site

Posted by Chris on Mon, Nov 19, 2018

If you are located at a site with a slow Internet connection or if your ISP sets a bandwidth quota per your contract, you may not want to waste your bandwidth downloading the same docker images multiple times.

Or, you may have built some of your own custom images and want to distribute them to other computers without setting up your own repository and without having to build the image again on every host.

To start, let’s determine which images are on the local computer (node02).

root@node02:~# docker images
REPOSITORY                                TAG                 IMAGE ID            CREATED             SIZE
tvial/docker-mailserver                   latest              ccc9086e4cf2        3 days ago          521MB
traefik                                   latest              d048a102127b        8 days ago          68.8MB
nextcloud                                 latest              dbcf87f7f289        3 weeks ago         563MB
mediawiki                                 latest              d18ec219bf8c        3 weeks ago         687MB
alpine_pia_proxy                          latest              a39b6cd6ae77        4 weeks ago         10.6MB
openvpn-client                            latest              ae338c22a874        5 months ago        253MB
ubuntu                                    16.04               0b1edfbffd27        6 months ago        113MB
phusion/baseimage                         latest              166cfc3f6974        9 months ago        209MB
alpine                                    latest              3fd9065eaf02        10 months ago       4.15MB

If we wanted to move some of these images to another computer we would use the docker save command to save the image and at the same time pipe it through gzip to compress it.

Here’s a sample of moving tvial/docker-mailserver, nextcloud, mediawiki, alpine, and traefik.

root@node02:~# docker save tvial/docker-mailserver | gzip > docker-mailserver.tar.gz
root@node02:~# docker save nextcloud | gzip > nextcloud.tar.gz
root@node02:~# docker save mediawiki | gzip > mediawiki.tar.gz
root@node02:~# docker save alpine | gzip > alpine.tar.gz
root@node02:~# docker save traefik | gzip > traefik.tar.gz

Next we copy these tar.gz files to the other computer (node01). I generally use rsync/ssh to move things around but ‘you do you’ and use whatever method you prefer.

On node01 we can do a directory listing to verify the files are there.

root@node01:~# ls *gz
alpine.tar.gz  docker-mailserver.tar.gz  mediawiki.tar.gz  nextcloud.tar.gz  traefik.tar.gz

Now we can import each of these files.

root@node01:~# zcat alpine.tar.gz | docker import - alpine:latest
sha256:80a7daea212678a6d44bd202923d3444242ae964fd5111fbd217674fa934d6e9
root@node01:~# zcat docker-mailserver.tar.gz | docker import - tvial/docker-mailserver:latest
sha256:2584e2ce59065e96dbc9bf51fb875c8dd331d49f3505a401ff3712b8d6537962
root@node01:~# zcat mediawiki.tar.gz | docker import - mediawiki:latest
sha256:f6d3b4a81360010c6a5f9b3121625001c2126b72e9208caeccb38fc2f75bb580
root@node01:~# zcat nextcloud.tar.gz | docker import - nextcloud:latest
sha256:2fa735685064e01e0d7a0372f112713f8c964911c3b0d520925bf7fed99b89f0
root@node01:~# zcat traefik.tar.gz | docker import - traefik:latest
sha256:e8956b5466081605771c8c5778ff1b7f701c791c8b4e042759ad273e22161eaf

Note that the sha256 hash can be used to verify these images against the source images.

Once done we can verify that the images are now available on node01:

root@node01:~# docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
traefik                   latest              e8956b546608        9 minutes ago       68.8MB
nextcloud                 latest              2fa735685064        10 minutes ago      584MB
mediawiki                 latest              f6d3b4a81360        11 minutes ago      710MB
tvial/docker-mailserver   latest              2584e2ce5906        12 minutes ago      534MB
alpine                    latest              80a7daea2126        15 minutes ago      4.41MB

That’s it — straightforward enough and easy to automate.

Note that this only copies the image itself. It does not copy any of the ephemeral or mounted volumes that you may have configured in your containers. That is a different process.

Thanks for reading.