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) <noreply@anthropic.com>
This commit is contained in:
2026-07-02 20:01:51 +08:00
co-authored by Claude Opus 4.8
parent 1b3512042c
commit affc5adb4a
Vendored
+26 -45
View File
@@ -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} \