#!/bin/bash # 通用Docker镜像构建+推送脚本(构建与缓存解耦) # 用法: docker_build_push.sh [build_arg...] set -eu DOCKERFILE="$1" IMAGE_TAG="$2" CACHE_REF="$3" shift 3 BUILD_ARGS="" for arg in "$@"; do BUILD_ARGS="$BUILD_ARGS --build-arg $arg" done if ! docker buildx inspect ci-builder > /dev/null 2>&1; then docker buildx create --use --name ci-builder --driver docker-container echo "Created ci-builder" else docker buildx use ci-builder echo "Using existing ci-builder" fi docker buildx inspect --bootstrap CACHE_FROM="type=registry,ref=${CACHE_REF},ignore-error=true" echo "=== Step 1: Build & push image (read-only cache) ===" docker buildx build \ $BUILD_ARGS \ --cache-from "${CACHE_FROM}" \ -f "${DOCKERFILE}" \ -t "${IMAGE_TAG}" \ --push \ . echo "Image pushed: ${IMAGE_TAG}" echo "" echo "=== Step 2: Push cache (best effort, retries 3x) ===" CACHE_TO="type=registry,ref=${CACHE_REF},mode=max,compression=zstd" MAX_RETRIES=3 SUCCESS=0 for attempt in $(seq 1 $MAX_RETRIES); do echo "Cache push attempt $attempt/$MAX_RETRIES" if docker buildx build \ $BUILD_ARGS \ --cache-from "${CACHE_FROM}" \ --cache-to "${CACHE_TO}" \ -f "${DOCKERFILE}" \ -t "${IMAGE_TAG}" \ --push \ .; then echo "Cache pushed (attempt $attempt)" SUCCESS=1 break else echo "Cache push failed (attempt $attempt)" if [ $attempt -lt $MAX_RETRIES ]; then WAIT=$((attempt * 5)) echo "Retrying in ${WAIT}s..." sleep $WAIT fi fi done if [ $SUCCESS -eq 0 ]; then echo "WARNING: Cache push failed after $MAX_RETRIES attempts (non-fatal)" fi echo "" echo "Build completed: ${IMAGE_TAG}"