GHCR から Amazon ECR に Docker コンテナイメージをコピーする

GHCR から Amazon ECR に Docker コンテナイメージをコピーする

掲題を実施したいシチュエーションがあったのでコマンドをメモ。

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