#!/bin/bash # CI 公共步骤:确保宿主机持久 buildx builder 存在(DooD 模式下所有 job 共享) # - builder 名固定: ci-builder-persist # - docker-container driver, host 网络 # - 层缓存保存在 buildkit 容器及其 _state 命名卷中,job 结束不清理 # - 宿主机 ci-docker-cleanup.sh 已豁免该 builder # - 每次执行自动同步宿主机 docker config 到 BuildKit 容器(确保 registry 认证) # 用法: bash scripts/ci/ensure_persistent_builder.sh set -eu BUILDER="ci-builder-persist" if ! docker buildx inspect "$BUILDER" >/dev/null 2>&1; then echo "=== 创建持久 buildx builder: $BUILDER ===" # 并发安全:matrix 多个 job 可能同时检测到 builder 不存在,只有一个 create 成功; # 其余 job 的 create 会因 "builder already exists" 失败(set -e 下会退出)。 # 用 create || inspect 兜底:create 失败时若 builder 实际已被别的 job 创建,直接复用。 if ! docker buildx create --name "$BUILDER" --driver docker-container \ --driver-opt network=host \ --buildkitd-flags "--allow-insecure-entitlement network.host" \ --platform linux/amd64 2>/tmp/_buildx_create.err; then if docker buildx inspect "$BUILDER" >/dev/null 2>&1; then echo "=== builder 已被并发任务创建,复用: $BUILDER ===" else echo "❌ builder 创建失败且不存在:" cat /tmp/_buildx_create.err exit 1 fi fi else echo "=== 复用持久 buildx builder: $BUILDER ===" fi docker buildx use "$BUILDER" docker buildx inspect "$BUILDER" --bootstrap echo "✅ builder ready" docker buildx ls | head -5 # === 同步宿主机 docker config 到 BuildKit 容器(确保 registry 认证) === # BuildKit 容器名遵循 docker buildx 命名规则: buildx_buildkit__0 BUILDKIT_CONTAINER="buildx_buildkit_${BUILDER}_0" if docker inspect "$BUILDKIT_CONTAINER" >/dev/null 2>&1; then # 宿主机 docker config 路径 HOST_DOCKER_CONFIG="/root/.docker/config.json" if [ -f "$HOST_DOCKER_CONFIG" ]; then echo "=== 同步 docker config 到 BuildKit 容器 ===" # 确保容器内 .docker 目录存在 docker exec "$BUILDKIT_CONTAINER" mkdir -p /root/.docker # 拷贝 config.json docker cp "$HOST_DOCKER_CONFIG" "$BUILDKIT_CONTAINER:/root/.docker/config.json" echo "✅ docker config 已同步到 BuildKit 容器" else echo "⚠️ 宿主机 docker config 不存在: $HOST_DOCKER_CONFIG(跳过同步)" fi else echo "⚠️ BuildKit 容器不存在: $BUILDKIT_CONTAINER(跳过 config 同步)" fi