#!/bin/bash # ============================================ # 基础镜像同步脚本 - 从公共镜像源同步到私有ACR # 用法: # ACR_USERNAME=xxx ACR_PASSWORD=yyy bash scripts/ci/sync_base_images.sh # ============================================ set -euo pipefail ACR_REGISTRY="${ACR_REGISTRY:-xiaoxia-registry.cn-hangzhou.cr.aliyuncs.com/xiaoxiakeji}" ACR_USERNAME="${ACR_USERNAME:-}" ACR_PASSWORD="${ACR_PASSWORD:-}" SOURCE_PREFIX="${SOURCE_PREFIX:-docker.m.daocloud.io/library}" # 需要同步的镜像列表 (源镜像名:tag => ACR目标名:tag) IMAGES=( "python:3.12-slim-bookworm" "python:3.12-slim" "node:20" "nginx:alpine" ) echo "============================================" echo " 基础镜像同步到 ACR" echo " ACR: $ACR_REGISTRY" echo " 源: $SOURCE_PREFIX" echo "============================================" echo "" # 登录 ACR if [ -n "$ACR_PASSWORD" ] && [ -n "$ACR_USERNAME" ]; then echo "登录 ACR..." ACR_HOST=$(echo "$ACR_REGISTRY" | cut -d/ -f1) printf '%s' "$ACR_PASSWORD" | docker login "$ACR_HOST" -u "$ACR_USERNAME" --password-stdin echo "ACR 登录成功" echo "" fi success=0 failed=0 for image in "${IMAGES[@]}"; do source_image="${SOURCE_PREFIX}/${image}" target_image="${ACR_REGISTRY}/base/${image}" echo "--- 同步: $image ---" echo " 源: $source_image" echo " 目标: $target_image" # Pull 源镜像(带重试) pulled=0 for attempt in 1 2 3; do echo " Pull 尝试 $attempt/3..." if docker pull "$source_image"; then pulled=1 break fi echo " Pull 失败,5s 后重试..." sleep 5 done if [ "$pulled" -eq 0 ]; then echo " ❌ Pull 失败: $image" failed=$((failed + 1)) continue fi # Tag docker tag "$source_image" "$target_image" echo " Tag 完成" # Push 到 ACR pushed=0 for attempt in 1 2 3; do echo " Push 尝试 $attempt/3..." if docker push "$target_image"; then pushed=1 break fi echo " Push 失败,5s 后重试..." sleep 5 done if [ "$pushed" -eq 1 ]; then echo " ✅ 同步成功: $image" success=$((success + 1)) else echo " ❌ Push 失败: $image" failed=$((failed + 1)) fi echo "" done echo "============================================" echo " 同步完成" echo " 成功: $success" echo " 失败: $failed" echo "============================================" if [ "$failed" -gt 0 ]; then exit 1 fi