#!/bin/bash # Docker镜像构建与推送脚本 - 处理registry不稳定问题 # 特性: # 1. 构建+推送镜像(缓存只读模式)保证成功 # 2. 单独尝试推送缓存,失败不影响主构建 # 3. 缓存推送自动重试3次 # 4. zstd压缩减小缓存体积 set -eu usage() { echo "Usage: $0 [build_args...]" echo " dockerfile: Dockerfile路径" echo " image_tag: 完整镜像标签 (registry/repo:tag)" echo " cache_ref: 缓存引用 (registry/repo-cache:branch)" echo " build_args: 额外的--build-arg参数 (可选)" exit 1 } if [ $# -lt 3 ]; then usage fi DOCKERFILE="$1" IMAGE_TAG="$2" CACHE_REF="$3" shift 3 BUILD_ARGS="" for arg in "$@"; do BUILD_ARGS="$BUILD_ARGS --build-arg $arg" done CACHE_FROM="type=registry,ref=${CACHE_REF},ignore-error=true" CACHE_TO="type=registry,ref=${CACHE_REF},mode=min,compression=zstd,oci-mediatypes=true" echo "========================================" echo "构建镜像: $IMAGE_TAG" echo "Dockerfile: $DOCKERFILE" echo "缓存引用: $CACHE_REF" echo "========================================" # Step 1: 构建并推送镜像(只读缓存,保证主构建成功) echo "" echo "[1/2] 构建并推送镜像 (只读缓存模式)..." docker buildx build \ $BUILD_ARGS \ --cache-from "$CACHE_FROM" \ -f "$DOCKERFILE" \ -t "$IMAGE_TAG" \ --push \ . echo "✅ 镜像构建并推送成功: $IMAGE_TAG" # Step 2: 尝试推送缓存(失败不影响,重试3次) echo "" echo "[2/2] 尝试推送缓存到 registry (最多重试3次)..." CACHE_PUSH_SUCCESS=false for attempt in 1 2 3; do echo " 缓存推送尝试 $attempt/3..." if docker buildx build \ $BUILD_ARGS \ --cache-from "$CACHE_FROM" \ --cache-to "$CACHE_TO" \ -f "$DOCKERFILE" \ -t "$IMAGE_TAG" \ --push \ . 2>&1 | tail -5; then CACHE_PUSH_SUCCESS=true echo " ✅ 缓存推送成功 (第$attempt次尝试)" break else echo " ⚠️ 缓存推送失败 (第$attempt次尝试),等待后重试..." sleep $((attempt * 5)) fi done if [ "$CACHE_PUSH_SUCCESS" = false ]; then echo "" echo "⚠️ 缓存推送最终失败,跳过(不影响构建结果)" echo " 下一次构建将使用旧缓存或无缓存构建" fi echo "" echo "========================================" echo "✅ 构建完成: $IMAGE_TAG" echo "========================================"