80

I have the below list of images present on my system and want to copy all these images to a remote machine.

REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
u14_py269           latest              6a1ec0b508b3        4 days ago          885.9 MB
u12_py273           latest              c2a804894851        4 days ago          686 MB
u12_core            latest              0d61eba80df2        4 days ago          629.1 MB
c6_py266            latest              cb1a94742d59        4 days ago          1.32 GB
c6_core             latest              77c2ed19d87f        4 days ago          1.278 GB
c7_py275            latest              bb1d3de68452        4 days ago          1.117 GB
c7_core             latest              ca14a76e9cca        4 days ago          1.081 GB
u14_py35            latest              d110c7e4a1f5        5 days ago          914.5 MB
u14_py34            latest              085a37cb8614        5 days ago          830.7 MB
u14_py276           latest              8927c6167930        5 days ago          834.1 MB
u14_core            latest              93ead5abc25b        5 days ago          776.9 MB
centos              centos6             36877b5acebb        5 days ago          228.9 MB
ubuntu              latest              36248ae4a9ac        5 days ago          188 MB
ubuntu              12.04               94a7cb19a65b        5 days ago          137.8 MB
edgester/gerrit     latest              ce4e3238052a        6 days ago          735.2 MB
u14_as374_py276     latest              fa5fb7189d70        11 days ago         1.497 GB
c721_as373_py275    latest              03ccf6961d0c        11 days ago         844.3 MB
c721_as373_py35     latest              b5fece3dd45b        11 days ago         1.127 GB
c171_con_core       latest              8af0d24a38a0        2 weeks ago         377.2 MB
u14_as374_php55     latest              29df638e363a        3 weeks ago         1.073 GB
j_u14_as374_php55   latest              29df638e363a        3 weeks ago         1.073 GB
centos              centos7             c8a648134623        8 weeks ago         196.6 MB
centos              latest              c8a648134623        8 weeks ago         196.6 MB
j_u14_as374_py276   latest              28f379d60882        10 weeks ago        871.5 MB
ubuntu              14.04               89d5d8e8bafb        10 weeks ago        187.9 MB

Currently I am using method suggested in save and load Docker images, but I believe there must be a better way to deal with all images.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Pavan Gupta
  • 17,663
  • 4
  • 22
  • 29

8 Answers8

129

If you want to export all images at once, create one big tar file:

docker save $(docker images -q) -o /path/to/save/mydockersimages.tar

If you want to save multiples images in one .tar file:

IDS=$(docker images | awk '{if ($1 ~ /^(debian|centos)/) print $3}')
docker save $IDS -o /path/to/save/somedockersimages.tar

Finally, if you want to export multiple many images, with one .tar file per images (not disk efficient: common layer are saved in each .tar file):

docker images | awk '{if ($1 ~ /^(openshift|centos)/) print $1 " " $2 " " $3 }' | tr -c "a-z A-Z0-9_.\n-" "%" | while read REPOSITORY TAG IMAGE_ID
do
  echo "== Saving $REPOSITORY $TAG $IMAGE_ID =="
  docker  save   -o /path/to/save/$REPOSITORY-$TAG-$IMAGE_ID.tar $IMAGE_ID
done

You may also want to save the list of images so that the restored images can be tagged:

docker images | sed '1d' | awk '{print $1 " " $2 " " $3}' > mydockersimages.list

On the remote machine, you can load (import) the images:

docker load -i /path/to/save/mydockersimages.tar

and tag the imported images:

while read REPOSITORY TAG IMAGE_ID
do
        echo "== Tagging $REPOSITORY $TAG $IMAGE_ID =="
        docker tag "$IMAGE_ID" "$REPOSITORY:$TAG"
done < mydockersimages.list

For more information about save/load, read: How to copy Docker images from one host to another without using a repository

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Franklin Piat
  • 3,952
  • 3
  • 32
  • 45
  • 10
    I made the sinle huge tar and loaded it. got all images but none have repository or title/Tags. Now how the heck I'm suppose to know what images I have? – Abdul Rehman Jan 01 '18 at 07:06
  • @Bsienn did it take so much time? – Suhayb Mar 11 '18 at 08:00
  • @suhayab no, On my system it took 20 or so mins. – Abdul Rehman Mar 11 '18 at 10:34
  • Note that you may get hiccups using the "saving tags script" mentioned above, if you have images, which do not have any tags ``. Perhaps an additional `| grep -v ''` might do the trick here already. – EagleRainbow Jun 02 '19 at 18:48
  • I am looking to move a set of 6 containers created via docker-compose.yml to another computer. Will this method work? Will it also grab all volumes? Is that needed? – Patrick Steil Dec 06 '19 at 21:27
46

With windows server hosting the command is a little different. Using @EthanSN answer I found the following worked - using go formatting:

docker save $(docker images --format '{{.Repository}}:{{.Tag}}') -o allinone.tar

And the load command:

docker load -i allinone.tar

Worked perfectly with no need for the importing machine to download any images.

vvvvv
  • 25,404
  • 19
  • 49
  • 81
NAJ
  • 1,021
  • 1
  • 8
  • 11
  • 4
    This answer if preferable for a couple of reasons. One: it doesn't use sed and awk to parse the output of docker commands, and instead produces the correct format from one command to the next. Two: it preserves the tags when you load, without the need to save them in a separate file and re-tag the images after loading. – Wilfredo Sánchez Vega Sep 30 '19 at 23:20
  • 4
    This is a nice solution for a Windows OS, but this works only with the power shell and not with cmd – AndreStony Jun 22 '21 at 13:18
  • 1
    It says: Error response from daemon: invalid reference format – user43857 Feb 10 '22 at 20:49
26

Save all images with name:tag to one tar file:

docker save $(docker images | sed '1d' | awk '{print $1 ":" $2 }') -o allinone.tar

Then, load all images:

docker load -i allinone.tar
double-beep
  • 5,031
  • 17
  • 33
  • 41
EthanSN
  • 381
  • 3
  • 5
  • 4
    easy and clean solution! – Sahan Serasinghe Dec 14 '18 at 05:11
  • @rfay i don't think that's a better approach as you will lose all the titles and tags – Mark McDonagh Apr 09 '19 at 10:17
  • @MarkMcDonagh I checked it and you're right, I'll delete the command about using `docker images -q` as misleading. – rfay Apr 09 '19 at 16:47
  • 2
    Getting `Error response from daemon: invalid reference format` – PIYUSH CHUGH Jul 28 '20 at 07:55
  • @Zoinks at which step? Try split command. 1. ```docker images | sed '1d' | awk '{print $1 ":" $2 }'``` 2 docker save some_img:some_tag -o test.tar 3 docker load -i test.tar – EthanSN Jul 29 '20 at 06:08
  • used `grep -v ` to exclude none tagged images fixed the invalid reference format error for me. Here was worked for me: `docker save $(docker images | grep -v \ | sed '1d' | awk '{print $1 ":" $2 }') -o allinone.tar` – toddcscar Aug 04 '20 at 01:26
12

Thanks a lot all your awnsers, but I find a basic and safe solution to save:

docker save -o ubuntu.tar myjenk:latest jenkins/jenkins:lts

REPOSITORY          TAG                    
myjenk              latest    
jenkins/jenkins     lts    

after to restore images:

docker load < ubuntu.tar
Carlos Rivero
  • 191
  • 2
  • 4
6

Script to perform Docker save and load function (tried and tested):

Docker Save:

#!/bin/bash

#files will be saved in the dir 'Docker_images'
mkdir Docker_images
cd Docker_images
directory=`pwd`
c=0
#save the image names in 'list.txt'
doc= docker images | awk '{print $1}' > list.txt
printf "START \n"
input="$directory/list.txt"
#Check and create the image tar for the docker images
while IFS= read -r line
do
     one=`echo $line | awk '{print $1}'`
     two=`echo $line | awk '{print $1}' | cut -c 1-3`
     if [ "$one" != "<none>" ]; then
             c=$((c+1))
             printf "\n $one \n $two \n"
             docker save -o $two$c'.tar' $one
             printf "Docker image number $c successfully converted:   $two$c \n \n"
     fi
done < "$input"

Docker Load:

#!/bin/bash

cd Docker_images/
directory=`pwd`
ls | grep tar > files.txt
c=0
printf "START \n"
input="$directory/files.txt"
while IFS= read -r line
do
     c=$((c+1))
     printf "$c) $line \n"
     docker load -i $line
     printf "$c) Successfully created the Docker image $line  \n \n"
done < "$input"
Syed Faraz Umar
  • 389
  • 1
  • 4
  • 10
  • This is an undervalued answer. Great scripts that save (backup!) all images! Other than most answers, this saves them as separate files. Thanks so much – Jos Mar 29 '23 at 19:55
4

Using a registry, you can have a workflow similar to Git. Modify your container locally, commit changes to a local image, then push your image to the registry. You can then pull the image from your remote machine.

You can use the public Docker Hub, or you can set up your own registry server.

https://docs.docker.com/registry/

kliew
  • 3,073
  • 1
  • 14
  • 25
3

You can use Bash to iterate through the response to docker images running docker save -o <save image to path> <image name> on each image, and then (assuming you saved them all to one folder) you can zip it up and scp it to the remote host.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
kpie
  • 9,588
  • 5
  • 28
  • 50
0

If you are in zsh:

docker image ls | cut -d " " -f 1 | tail -n +2 | xargs -I{} zsh -c 'docker save {} >  $(echo {} | grep -oE "[^/]+$").tar'
Sadiq
  • 184
  • 11