Save all Docker images and push to docker registry or copy to another machine
In this article will cover to push/save all docker images from local machine and save to remote machine or private registry
Example 1: Save all Docker images and load to another machine
Save all docker images in local machine
docker save $(docker images --format '{{.Repository}}:{{.Tag}}') -o allinone.tar
scp it to remote machine
scp allinone.tar root@ip:/home/
login to remote machine and run following command
docker load -i allinone.tar
Example 2: Tag all local images with remote repo url and push it to private repository
1. List all docker image which want to sent private repo
$ docker images | grep <filter-image-name>
2. Retag listed image with private registry name with the following commands
If PRIVATE Registry URL Mentioned in Listed IMAGE Name$ for i in $(docker images | grep <one-private-repo-name> | awk '{print $1}') ; do docker tag $(docker images | grep $i | awk '{print $1 ":" $2}') <other-private-repo-name>/$(docker images | grep $i | awk '{print $1 ":" $2 }' | sed 's:[^/]*/\(.*\):\1:') ; doneIf PRIVATE Registry URL not Mentioned in Listed IMAGE Name$ for i in $(docker images | sed '1d' | awk '{print $1}');do echo docker tag $(docker images | grep $i | awk '{print $1 ":" $2}') <private-repo-name>/$(docker images | grep $i | awk '{print $1":"$2}') ;done
3. Push newly tag mages to other private registry with the following commands
$ for i in $(docker images | grep <other-private-repo-name> | awk '{print $1 ":" $2}');do echo docker push $i;done
Example 3: Send to Private registry via script
- create file includes image list
docker images --format '{{.Repository}}:{{.Tag}}' >> images.txt
2. copy following script save-image.sh and make it executable and run it
$ErrorActionPreference = 'Stop'$script_name = mylist_image_upload_script
$image_list = "images.txt"
$images = "images.tar.gz"
$os_release_id = $(Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\' | Select-Object -ExpandProperty ReleaseId)
$help = $falsefunction usage {
echo "USAGE: $script_name [--image-list images.txt] [--images images.tar.gz]"
echo " [-l|--image-list path] text file with list of images; one image per line."
echo " [-i|--images path] tar.gz generated by docker save."
echo " [-o|--os-release-id (1809|1903|...)] release id of OS, gets detected automatically if not passed."
echo " [-h|--help] Usage message."
}# parse arguments
$vals = $null
for ($i = $args.Length; $i -ge 0; $i--)
{
$arg = $args[$i]
switch -regex ($arg)
{
'^(-l|--image-list)$' {
$image_list = ($vals | Select-Object -First 1)
$vals = $null
}
'^(-i|--images)$' {
$images = ($vals | Select-Object -First 1)
$vals = $null
}
'^(-o|--os-release-id)$' {
$os_release_id = ($vals | Select-Object -First 1)
$vals = $null
}
'^(-h|--help)$' {
$help = $true
$vals = $null
}
default {
if ($vals) {
$vals = ,$arg + $vals
} else {
$vals = @($arg)
}
}
}
}if ($help)
{
usage
exit 0
}if (-not (Test-Path $image_list))
{
echo "Could not find '$image_list' file"
usage
exit 1
}$fullname_images = @()
Get-Content -Force -Path $image_list | ForEach-Object {
if ($_) {
$fullname_image = ('{0}-windows-{1}' -f $_, $os_release_id)
echo "Pulling $fullname_image"
docker pull $fullname_image
if ($?) {
$fullname_images += @($fullname_image)
}
}
}if (-not $fullname_images)
{
echo "Could not save empty images to host"
echo "Please verify the images of '$image_list' existing or not"
exit 1
}
docker save $($fullname_images) -o $images
chmod save-image.sh
RUN command:./save-images.sh --image-list ./images.txt
3. copy following script load-image.sh and make it executable and run it
#!/bin/bash
images="images.tar.gz"
list="images.txt"
windows_image_list=""
windows_versions="1903"
usage () {
echo "USAGE: $0 [--images images.tar.gz] --registry my.registry.com:5000"
echo " [-l|--image-list path] text file with list of images; one image per line."
echo " [-i|--images path] tar.gz generated by docker save."
echo " [-r|--registry registry:port] target private registry:port."
echo " [--windows-image-list path] text file with list of images used in Windows. Windows image mirroring is skipped when this is empty"
echo " [--windows-versions version] Comma separated Windows versions. e.g., \"1809,1903\". (Default \"1903\")"
echo " [-h|--help] Usage message"
}push_manifest () {
export DOCKER_CLI_EXPERIMENTAL=enabled
manifest_list=()
for i in "${arch_list[@]}"
do
manifest_list+=("$1-${i}")
doneecho "Preparing manifest $1, list[${arch_list[@]}]"
docker manifest create "$1" "${manifest_list[@]}" --amend
docker manifest push "$1" --purge
}while [[ $# -gt 0 ]]; do
key="$1"
case $key in
-r|--registry)
reg="$2"
shift # past argument
shift # past value
;;
-l|--image-list)
list="$2"
shift # past argument
shift # past value
;;
-i|--images)
images="$2"
shift # past argument
shift # past value
;;
--windows-image-list)
windows_image_list="$2"
shift # past argument
shift # past value
;;
--windows-versions)
windows_versions="$2"
shift # past argument
shift # past value
;;
-h|--help)
help="true"
shift
;;
*)
usage
exit 1
;;
esac
done
if [[ -z $reg ]]; then
usage
exit 1
fi
if [[ $help ]]; then
usage
exit 0
fidocker load --input ${images}linux_images=()
while IFS= read -r i; do
[ -z "${i}" ] && continue
linux_images+=("${i}");
done < "${list}"arch_list=()
if [[ -n "${windows_image_list}" ]]; then
IFS=',' read -r -a versions <<< "$windows_versions"
for version in "${versions[@]}"
do
arch_list+=("windows-${version}")
donewindows_images=()
while IFS= read -r i; do
[ -z "${i}" ] && continue
windows_images+=("${i}")
done < "${windows_image_list}"# use manifest to publish images only used in Windows
for i in "${windows_images[@]}"; do
if [[ ! " ${linux_images[@]}" =~ " ${i}" ]]; then
case $i in
*/*)
image_name="${reg}/${i}"
;;
*)
image_name="${reg}/rancher/${i}"
;;
esac
push_manifest "${image_name}"
fi
done
fiarch_list+=("linux-amd64")
for i in "${linux_images[@]}"; do
[ -z "${i}" ] && continue
arch_suffix=""
use_manifest=false
if [[ (-n "${windows_image_list}") && " ${windows_images[@]}" =~ " ${i}" ]]; then
# use manifest to publish images when it is used both in Linux and Windows
use_manifest=true
arch_suffix="-linux-amd64"
fi
case $i in
*/*)
image_name="${reg}/${i}"
;;
*)
image_name="${reg}/rancher/${i}"
;;
esacdocker tag "${i}" "${image_name}${arch_suffix}"
docker push "${image_name}${arch_suffix}"if $use_manifest; then
push_manifest "${image_name}"
fi
done
chmod a+x load-image.sh
./load-images.sh --image-list ./images.txt --registry <REGISTRY.YOURDOMAIN.COM:PORT>
Enjoy