Created
July 4, 2024 16:28
-
-
Save zxkane/4624d699ff664698d94e3b8bf51de3e2 to your computer and use it in GitHub Desktop.
Mirror multiple arch images from Docker Hub to AWS Public ECR
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -o errexit # exit on first error | |
set -o nounset # exit on using unset variables | |
set -o pipefail # exit on any error in a pipeline | |
set -x # enable debugging | |
# Script to mirror multi-arch images from Docker Hub to Amazon ECR Public. | |
# Usage: ./mirror-multi-arch-repos.sh <source-image>:<tag> <ecr-repo-name> | |
if [ $# -ne 2 ]; then | |
echo "Usage: $0 <source-image>:<tag> <ecr-repo-name>" | |
exit 1 | |
fi | |
SOURCE_IMAGE_TAG_STR=$1 | |
ECR_REPO_NAME=$2 | |
# Get ECR registry URL | |
ECR_REGISTRY_URL=$(aws ecr-public describe-registries --region us-east-1 --query 'registries[0].registryUri' --output text) | |
# Function to extract platform from manifest as a list of json strings | |
get_platforms() { | |
docker manifest inspect $SOURCE_IMAGE_TAG_STR | jq -r '.manifests[].platform | select(.architecture!="unknown") | @json' | |
} | |
get_suffix() { | |
local os=$1 | |
local arch=$2 | |
local variant=${3:-""} | |
prefix="-" | |
suffix=${os}-${arch}${variant:+$prefix$variant} | |
echo $suffix | |
} | |
# Pull and push images to ECR | |
pull_and_push_to_ecr() { | |
# Create ECR repository if it doesn't exist | |
aws ecr-public create-repository --repository-name $ECR_REPO_NAME --region us-east-1 || true | |
platforms=( $(get_platforms) ) | |
for platform in "${platforms[@]}"; do | |
arch=$(echo $platform | jq -r .architecture) | |
os=$(echo $platform | jq -r .os) | |
variant=$(echo $platform | jq -r '.variant? // empty') | |
suffix=$(get_suffix $os $arch $variant) | |
local source_image_with_platform="${SOURCE_IMAGE_TAG_STR}-${suffix}" | |
local ecr_image_with_arch="${ECR_REGISTRY_URL}/${source_image_with_platform}" | |
echo "Pulling $SOURCE_IMAGE_TAG_STR for $suffix" | |
docker pull --platform $os/$arch${variant:+/$variant} $SOURCE_IMAGE_TAG_STR | |
echo "Tagging $SOURCE_IMAGE_TAG_STR as $ecr_image_with_arch" | |
docker tag $SOURCE_IMAGE_TAG_STR $ecr_image_with_arch | |
echo "Pushing $ecr_image_with_arch to ECR" | |
docker push $ecr_image_with_arch | |
done | |
} | |
# Create and push manifest list | |
create_manifest() { | |
local manifest_list="${ECR_REGISTRY_URL}/${SOURCE_IMAGE_TAG_STR}" | |
echo "Creating manifest list: $manifest_list" | |
platforms=( $(get_platforms) ) | |
for platform in "${platforms[@]}"; do | |
arch=$(echo $platform | jq -r .architecture) | |
os=$(echo $platform | jq -r .os) | |
variant=$(echo $platform | jq -r '.variant? // empty') | |
suffix=$(get_suffix $os $arch $variant) | |
# Construct the image tag with the suffix | |
image_tag="${SOURCE_IMAGE_TAG}-${suffix}" | |
# Add the image to the manifest list | |
docker manifest create "$manifest_list" "${ECR_REGISTRY_URL}/${SOURCE_IMAGE}:${image_tag}" --amend | |
docker manifest annotate $manifest_list \ | |
"${ECR_REGISTRY_URL}/${SOURCE_IMAGE}:${image_tag}" \ | |
--os $os --arch $arch ${variant:+--variant $variant} | |
done | |
echo "Pushing manifest list to ECR" | |
docker manifest push $manifest_list | |
} | |
# a method to parse the image name and tag from SOURCE_IMAGE_TAG_STR | |
# e.g. "nginx:latest" will be split into "nginx" and "latest" | |
SOURCE_IMAGE=$(echo $SOURCE_IMAGE_TAG_STR | cut -d: -f1) | |
SOURCE_IMAGE_TAG=$(echo $SOURCE_IMAGE_TAG_STR | cut -d: -f2) | |
# Main execution | |
echo "Authenticating with ECR" | |
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws | |
echo "Pulling multi-architecture images for $SOURCE_IMAGE_TAG_STR, then pushing images to ECR" | |
pull_and_push_to_ecr | |
echo "Creating and pushing manifest list" | |
create_manifest | |
echo "Mirroring complete for $SOURCE_IMAGE_TAG_STR to ${ECR_REGISTRY_URL}/${ECR_REPO_NAME}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage: ./mirror-multi-arch-repos.sh timberio/vector:0.35.1-debian timberio/vector