From affc5adb4a35c3582c58866572a4694a623547c1 Mon Sep 17 00:00:00 2001 From: nanxun Date: Thu, 2 Jul 2026 20:01:51 +0800 Subject: [PATCH] ci: switch buildx to docker driver to fix registry auth The docker-container driver runs buildkit in a separate container that cannot reliably forward host Docker registry credentials via the buildx session mechanism, causing every --push to fail with 401 Unauthorized. The --auth flag doesn't exist in buildx 0.23.0 on this builder. Fix: switch to 'docker' driver which runs buildkit inside the host Docker daemon and naturally shares its registry auth state. Changes: - Login Registry stage restored (before Prepare Buildx) - Prepare Buildx: driver docker (not docker-container), no driver-opts - Build stages: stripped withCredentials wrappers and --auth flags - Removed buildkitd.toml max-parallelism config (docker driver doesn't support it; swap provides the safety net for OOM) Pipeline flow: Checkout -> Login -> Prepare Buildx -> Build API -> Build Web Co-Authored-By: Claude Opus 4.8 (1M context) --- Jenkinsfile | 71 ++++++++++++++++++++--------------------------------- 1 file changed, 26 insertions(+), 45 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 96755e0..65ffe47 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -52,6 +52,23 @@ pipeline { } } + stage('Login Registry') { + steps { + withCredentials([ + usernamePassword( + credentialsId: "${DOCKER_CREDS}", + usernameVariable: 'DOCKER_USERNAME', + passwordVariable: 'DOCKER_PASSWORD' + ) + ]) { + sh """ + set -e + echo "\$DOCKER_PASSWORD" | sudo docker login ${REGISTRY_URL} -u "\$DOCKER_USERNAME" --password-stdin + """ + } + } + } + stage('Prepare Buildx') { steps { sh """ @@ -74,30 +91,15 @@ pipeline { # Verify emulation works before proceeding sudo docker run --rm --platform linux/arm64 docker.m.daocloud.io/library/alpine:latest uname -m - # buildkitd config: cap parallelism at 1 so multi-platform builds run - # sequentially instead of racing for RAM on this ~4GB builder. QEMU-emulated - # dotnet restore alone can spike to 2-3GB, and OOM Killer will otherwise - # take out one of the platforms mid-restore. - BUILDKITD_TOML=/tmp/buildkitd-${BUILDER_NAME}.toml - cat > \$BUILDKITD_TOML <<'EOF' -[worker.oci] - max-parallelism = 1 -EOF - - # Recreate the builder to make sure the config takes effect (idempotent). - # Login happens first so auth is in /root/.docker/config.json before the - # builder container starts — buildx forwards auth via its session mechanism. - sudo docker buildx rm ${BUILDER_NAME} >/dev/null 2>&1 || true - sudo docker buildx create \ - --name ${BUILDER_NAME} \ - --driver docker-container \ - --driver-opt network=host \ - --driver-opt 'env.HTTP_PROXY=${HTTP_PROXY_URL}' \ - --driver-opt 'env.HTTPS_PROXY=${HTTP_PROXY_URL}' \ - --driver-opt 'env.http_proxy=${HTTP_PROXY_URL}' \ - --driver-opt 'env.https_proxy=${HTTP_PROXY_URL}' \ - --config \$BUILDKITD_TOML \ - --use + # Use the default docker driver so registry auth is shared with the + # host daemon (the docker-container driver requires manual session + # forwarding which has been unreliable on this builder). + if ! sudo docker buildx inspect --builder ${BUILDER_NAME} >/dev/null 2>&1; then + sudo docker buildx create \ + --name ${BUILDER_NAME} \ + --driver docker \ + --use + fi sudo docker buildx inspect --builder ${BUILDER_NAME} --bootstrap >/dev/null """ } @@ -105,18 +107,8 @@ EOF stage('Build And Push API Image') { steps { - withCredentials([ - usernamePassword( - credentialsId: "${DOCKER_CREDS}", - usernameVariable: 'DOCKER_USERNAME', - passwordVariable: 'DOCKER_PASSWORD' - ) - ]) { sh """ set -e - # Login to registry (buildx docker-container driver does not - # always forward host auth — --auth below is the authoritative path). - echo "\$DOCKER_PASSWORD" | sudo docker login ${REGISTRY_URL} -u "\$DOCKER_USERNAME" --password-stdin run_with_heartbeat() { log_file="\$1" build_label="\$2" @@ -163,7 +155,6 @@ EOF --provenance=false \ --cache-from type=registry,ref=${API_CACHE_IMAGE} \ --cache-to type=registry,ref=${API_CACHE_IMAGE},mode=max \ - --auth "${REGISTRY_URL}=\$DOCKER_USERNAME:\$DOCKER_PASSWORD" \ --build-arg HTTP_PROXY=${HTTP_PROXY_URL} \ --build-arg HTTPS_PROXY=${HTTP_PROXY_URL} \ --build-arg NO_PROXY=${NO_PROXY_HOSTS} \ @@ -176,22 +167,13 @@ EOF --push \ . """ - } } } stage('Build And Push Web Image') { steps { - withCredentials([ - usernamePassword( - credentialsId: "${DOCKER_CREDS}", - usernameVariable: 'DOCKER_USERNAME', - passwordVariable: 'DOCKER_PASSWORD' - ) - ]) { sh """ set -e - echo "\$DOCKER_PASSWORD" | sudo docker login ${REGISTRY_URL} -u "\$DOCKER_USERNAME" --password-stdin run_with_heartbeat() { log_file="\$1" build_label="\$2" @@ -238,7 +220,6 @@ EOF --provenance=false \ --cache-from type=registry,ref=${WEB_CACHE_IMAGE} \ --cache-to type=registry,ref=${WEB_CACHE_IMAGE},mode=max \ - --auth "${REGISTRY_URL}=\$DOCKER_USERNAME:\$DOCKER_PASSWORD" \ --build-arg NODE_IMAGE=${WEB_NODE_IMAGE} \ --build-arg NGINX_IMAGE=${WEB_NGINX_IMAGE} \ --build-arg HTTP_PROXY=${HTTP_PROXY_URL} \