From c9839b265c9a16e06fcce1f29b08fd7ebd733f68 Mon Sep 17 00:00:00 2001 From: CI Bot Date: Sat, 18 Jul 2026 15:59:58 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix(ci):=20Web=E6=9E=84=E5=BB=BA=E6=94=B9?= =?UTF-8?q?=E7=94=A8layer=E7=BC=93=E5=AD=98=E6=9B=BF=E4=BB=A3cache=20mount?= =?UTF-8?q?=EF=BC=8C=E9=81=BF=E5=85=8Dnode=5Fmodules=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E6=8D=9F=E5=9D=8F=E5=AF=BC=E8=87=B4=E6=9E=84=E5=BB=BA=E5=85=A8?= =?UTF-8?q?=E6=8C=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除node_modules的cache mount,改为写入镜像layer走ACR缓存 - 保留/root/.npm cache mount加速下载(不影响正确性) - 保留.tscache cache mount加速TS增量编译(坏了不影响构建) - layer缓存由ACR跨runner共享,内容完整性由layer哈希保证 --- infra/docker/web.Dockerfile | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/infra/docker/web.Dockerfile b/infra/docker/web.Dockerfile index f800ed684..12fe02505 100755 --- a/infra/docker/web.Dockerfile +++ b/infra/docker/web.Dockerfile @@ -8,10 +8,9 @@ ENV VITE_API_URL=$VITE_API_URL COPY apps/web/package.json apps/web/package-lock.json ./apps/web/ WORKDIR /app/apps/web -# 安装依赖:用BuildKit cache mount缓存npm下载和node_modules -# sharing=locked 防止并发构建竞争写缓存 +# 安装依赖:node_modules写入镜像layer,走ACR缓存保证完整性 +# /root/.npm 保留cache mount加速下载(不影响构建正确性) RUN --mount=type=cache,target=/root/.npm,sharing=locked \ - --mount=type=cache,target=/app/apps/web/node_modules,sharing=locked \ npm config set registry https://registry.npmmirror.com \ && npm ci @@ -19,8 +18,8 @@ RUN --mount=type=cache,target=/root/.npm,sharing=locked \ COPY apps/web/ ./ # 构建:TS增量编译 + Vite构建,tsbuildinfo用cache mount持久化 -RUN --mount=type=cache,target=/app/apps/web/node_modules,sharing=locked \ - --mount=type=cache,target=/app/apps/web/.tscache,sharing=locked \ +# node_modules直接使用镜像中已安装的(layer缓存保证完整性) +RUN --mount=type=cache,target=/app/apps/web/.tscache,sharing=locked \ mkdir -p .tscache \ && npx tsc --incremental --tsBuildInfoFile .tscache/tsconfig.tsbuildinfo \ && npx vite build -- 2.54.0 From 7ec43b3b28554002a0a79bef4959aa86edda5a89 Mon Sep 17 00:00:00 2001 From: CI Bot Date: Sat, 18 Jul 2026 16:11:06 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix(ci):=20buildx=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E6=8D=9F=E5=9D=8F=E8=87=AA=E5=8A=A8=E6=A3=80?= =?UTF-8?q?=E6=B5=8B+=E6=B8=85=E7=90=86=E9=87=8D=E8=AF=95=EF=BC=8C?= =?UTF-8?q?=E6=A0=B9=E6=B2=BBsnapshot=20not=20found=E8=BF=9E=E9=94=81?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增build_with_cache_retry()函数:检测缓存损坏类错误自动清理本地缓存并重试 - 覆盖错误模式:parent snapshot not found、cache corrupt、failed to compute cache key - 两级降级:本地缓存重试1次 → 完全不用本地缓存只用registry缓存 - 同时清理buildx builder内部snapshot状态(docker buildx prune -a) - 非缓存类错误直接透传,不误重试 --- scripts/ci/docker_build_push.sh | 69 +++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 16 deletions(-) diff --git a/scripts/ci/docker_build_push.sh b/scripts/ci/docker_build_push.sh index dc73eb1d7..23c7e86dc 100755 --- a/scripts/ci/docker_build_push.sh +++ b/scripts/ci/docker_build_push.sh @@ -28,27 +28,64 @@ LOCAL_CACHE_DIR="/tmp/buildx-cache/${CACHE_NAME}" mkdir -p "$LOCAL_CACHE_DIR" -# 缓存源:local优先,registry兜底 -CACHE_FROM_LOCAL="type=local,src=${LOCAL_CACHE_DIR}" -CACHE_FROM_REGISTRY="type=registry,ref=${CACHE_REF},ignore-error=true" +# 缓存源:local优先(带自动修复),registry兜底 +# 本地缓存损坏时自动清理后重试,避免snapshot not found导致构建全挂 +build_with_cache_retry() { + local attempt=1 + local max_attempts=2 + while [ $attempt -le $max_attempts ]; do + local build_output + local exit_code + set +e + build_output=$(docker buildx build \ + $BUILD_ARGS \ + --cache-from "type=local,src=${LOCAL_CACHE_DIR}" \ + --cache-from "type=registry,ref=${CACHE_REF},ignore-error=true" \ + --cache-to "type=local,dest=${LOCAL_CACHE_DIR},mode=max" \ + -f "${DOCKERFILE}" \ + -t "${IMAGE_TAG}" \ + --push \ + . 2>&1) + exit_code=$? + set -e + if [ $exit_code -eq 0 ]; then + echo "$build_output" + return 0 + fi + # 检测到缓存损坏类错误,清掉本地缓存重试 + if echo "$build_output" | grep -qE "parent snapshot.*not found|snapshot.*does not exist|cache.*corrupt|failed to compute cache key"; then + echo "$build_output" + echo "" + echo "⚠️ Local cache appears corrupted, cleaning up and retrying (attempt $attempt/$max_attempts)..." + rm -rf "${LOCAL_CACHE_DIR}" + mkdir -p "${LOCAL_CACHE_DIR}" + # 清理buildx builder的内部snapshot状态 + docker buildx prune -f -a >/dev/null 2>&1 || true + attempt=$((attempt + 1)) + else + # 非缓存类错误,直接输出并返回 + echo "$build_output" + return $exit_code + fi + done + # 重试完还是失败,不用本地缓存最后试一次(只从registry读) + echo "⚠️ All cached attempts failed, building without local cache..." + docker buildx build \ + $BUILD_ARGS \ + --cache-from "type=registry,ref=${CACHE_REF},ignore-error=true" \ + --cache-to "type=local,dest=${LOCAL_CACHE_DIR},mode=max" \ + -f "${DOCKERFILE}" \ + -t "${IMAGE_TAG}" \ + --push \ + . +} -# 本地缓存目标(必选,mode=max最大化命中率) -CACHE_TO_LOCAL="type=local,dest=${LOCAL_CACHE_DIR},mode=max" - -echo "=== Step 1: Build & push image (local cache read-write + registry read) ===" +echo "=== Step 1: Build & push image (local cache + registry read, with auto-repair) ===" echo "Local cache: ${LOCAL_CACHE_DIR}" echo "Registry cache: ${CACHE_REF}" echo "" -docker buildx build \ - $BUILD_ARGS \ - --cache-from "${CACHE_FROM_LOCAL}" \ - --cache-from "${CACHE_FROM_REGISTRY}" \ - --cache-to "${CACHE_TO_LOCAL}" \ - -f "${DOCKERFILE}" \ - -t "${IMAGE_TAG}" \ - --push \ - . +build_with_cache_retry echo "" echo "Image pushed: ${IMAGE_TAG}" -- 2.54.0