085f48ecd6
问题: - Worker镜像构建因registry缓存推送时连接断开(use of closed network connection)而失败 - docker buildx exporting cache to registry阶段大层传输超时 - 缓存推送失败导致整个构建失败,镜像其实已经构建完成 修复: 1. 创建scripts/ci/docker_build_push.sh通用构建脚本 2. 镜像构建与缓存推送解耦:先构建+推送镜像(只读缓存)保证成功 3. 再单独尝试推送缓存,自动重试3次,失败不影响主构建结果 4. 缓存使用zstd压缩+oci-mediatypes减小传输体积 5. 缓存引用改为按分支名区分,支持多分支独立缓存 涉及:全部6个镜像构建job(staging/production x api/worker/web)
86 lines
2.4 KiB
Bash
Executable File
86 lines
2.4 KiB
Bash
Executable File
#!/bin/bash
|
|
# Docker镜像构建与推送脚本 - 处理registry不稳定问题
|
|
# 特性:
|
|
# 1. 构建+推送镜像(缓存只读模式)保证成功
|
|
# 2. 单独尝试推送缓存,失败不影响主构建
|
|
# 3. 缓存推送自动重试3次
|
|
# 4. zstd压缩减小缓存体积
|
|
set -eu
|
|
|
|
usage() {
|
|
echo "Usage: $0 <dockerfile> <image_tag> <cache_ref> [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 "========================================"
|