掲題を実施したいシチュエーションがあったのでコマンドをメモ。
crane という Google 製の OSS を使用して、GHCR から Amazon ECR に Docker コンテナイメージをコピーしています。(https://github.com/google/go-containerregistry/blob/main/cmd/crane/README.md)
# 必要なコマンドがあることを確認する
jq --version
crane version
# コマンドがなければインストールする
# jq - https://jqlang.org/download/
# crane - https://github.com/google/go-containerregistry/blob/main/cmd/crane/README.md
# 変数を設定する(内容は自分の環境に合わせて変更すること)
GHCR_ORG_NAME='my-org'
GHCR_REPOSITORY_NAME='my-repository'
GITHUB_USER_NAME='MY_GITHUB_USER_NAME'
GITHUB_TOKEN='MY_TOKEN'
AWS_REGION=ap-northeast-1
ECR_REGISTRY=************.dkr.ecr.ap-northeast-1.amazonaws.com
ECR_REPOSITORY="${GHCR_REPOSITORY_NAME}/${GHCR_ORG_NAME}"
# GHCR、ECR へログインする
echo "${GITHUB_TOKEN}" | crane auth login ghcr.io -u "${GITHUB_USER_NAME}" --password-stdin
aws ecr get-login-password --region "${AWS_REGION}" | crane auth login "${ECR_REGISTRY}" -u AWS --password-stdin
# 最新何件分をコピーするか指定する
LATEST_COUNT=5
# 常にコピーしたいタグがあれば指定する(なければ空にする)
FIXED_TAGS=(
"0123456789abcdefghijklmnopqrstuv"
"a0b1c2d3e4f5g6h7i8j9k0l1m2n3o4pq"
)
# 最新タグを取得する
LATEST_TAGS=$(
curl -fsSL \
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/orgs/${GHCR_ORG_NAME}/packages/container/${GHCR_REPOSITORY_NAME}/versions?per_page=100" \
| jq -r --argjson latest_count "${LATEST_COUNT}" '
map(select(.metadata.container.tags | length > 0))
| sort_by(.created_at)
| reverse
| .[:$latest_count]
| map(.metadata.container.tags[0])
| .[]
'
)
# 最新タグ + 固定タグ をまとめて重複排除してから ECR → GHCR にコピーする
{
printf '%s\n' "${LATEST_TAGS}"
for tag in "${FIXED_TAGS[@]}"; do
printf '%s\n' "${tag}"
done
} \
| sort -u \
| while IFS= read -r TAG; do
echo "copy ${TAG}"
crane copy \
"ghcr.io/${GHCR_ORG_NAME}/${GHCR_REPOSITORY_NAME}:${TAG}" \
"${ECR_REGISTRY}/${ECR_REPOSITORY}:${TAG}"
done