ci: bypass buildx --push auth via per-platform --load + docker push + manifest
buildx build --push has failed 401 on every attempt. The buildkit auth forwarding (whether via docker-container or docker driver) does not work reliably on this builder. New strategy: build each platform separately with --load (into local docker, which can read /root/.docker/config.json), then push with native docker push, then assemble a multi-arch manifest with docker manifest create/push. Per-platform tags are pushed as :<BUILD_ID>-amd64 / :<BUILD_ID>-arm64 and the manifest combines them under the canonical :<BUILD_ID> and :latest. This replaces a single buildx --push call with: 1. buildx build --platform linux/amd64 --load 2. docker push (amd64) 3. docker rmi (free disk) 4. buildx build --platform linux/arm64 --load 5. docker push (arm64) 6. docker rmi (free disk) 7. docker manifest create + push (multi-arch) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Vendored
+113
-58
@@ -90,17 +90,6 @@ pipeline {
|
||||
|
||||
# Verify emulation works before proceeding
|
||||
sudo docker run --rm --platform linux/arm64 docker.m.daocloud.io/library/alpine:latest uname -m
|
||||
|
||||
# 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
|
||||
"""
|
||||
}
|
||||
}
|
||||
@@ -109,6 +98,7 @@ pipeline {
|
||||
steps {
|
||||
sh """
|
||||
set -e
|
||||
|
||||
run_with_heartbeat() {
|
||||
log_file="\$1"
|
||||
build_label="\$2"
|
||||
@@ -144,28 +134,64 @@ pipeline {
|
||||
fi
|
||||
return "\$cmd_status"
|
||||
}
|
||||
sudo docker buildx inspect --builder ${BUILDER_NAME} --bootstrap >/dev/null
|
||||
echo 'Building and pushing multi-arch API image: ${API_IMAGE_TAGGED}'
|
||||
run_with_heartbeat /tmp/live-recorder-api-buildx-${IMAGE_TAG}.log "API multi-arch build" \
|
||||
sudo docker buildx build \
|
||||
--builder ${BUILDER_NAME} \
|
||||
--platform ${TARGET_PLATFORMS} \
|
||||
--network host \
|
||||
--progress=plain \
|
||||
--provenance=false \
|
||||
--cache-from type=registry,ref=${API_CACHE_IMAGE} \
|
||||
--cache-to type=registry,ref=${API_CACHE_IMAGE},mode=max \
|
||||
--build-arg HTTP_PROXY=${HTTP_PROXY_URL} \
|
||||
--build-arg HTTPS_PROXY=${HTTP_PROXY_URL} \
|
||||
--build-arg NO_PROXY=${NO_PROXY_HOSTS} \
|
||||
--build-arg http_proxy=${HTTP_PROXY_URL} \
|
||||
--build-arg https_proxy=${HTTP_PROXY_URL} \
|
||||
--build-arg no_proxy=${NO_PROXY_HOSTS} \
|
||||
-f src/LiveRecorder.WebApi/Dockerfile \
|
||||
-t ${API_IMAGE_TAGGED} \
|
||||
-t ${API_IMAGE_LATEST} \
|
||||
--push \
|
||||
.
|
||||
|
||||
# ── Build each platform separately, push with docker CLI,
|
||||
# then assemble a multi-arch manifest.
|
||||
# buildx --push does not forward auth reliably on this
|
||||
# builder; per-platform --load + docker push + manifest
|
||||
# bypasses that entirely.
|
||||
for PLATFORM in linux/amd64 linux/arm64; do
|
||||
ARCH_TAG="\${PLATFORM##*/}" # amd64 / arm64
|
||||
PLAT_REF="${API_IMAGE_TAGGED}-\${ARCH_TAG}"
|
||||
PLAT_LATEST="${API_IMAGE_LATEST}-\${ARCH_TAG}"
|
||||
|
||||
echo ''
|
||||
echo "=== Building API for \$PLATFORM -> \$PLAT_REF ==="
|
||||
run_with_heartbeat /tmp/live-recorder-api-\${ARCH_TAG}.log "API \${ARCH_TAG} build" \
|
||||
sudo docker buildx build \
|
||||
--platform "\$PLATFORM" \
|
||||
--network host \
|
||||
--progress=plain \
|
||||
--provenance=false \
|
||||
--cache-from type=registry,ref=${API_CACHE_IMAGE} \
|
||||
--build-arg HTTP_PROXY=${HTTP_PROXY_URL} \
|
||||
--build-arg HTTPS_PROXY=${HTTP_PROXY_URL} \
|
||||
--build-arg NO_PROXY=${NO_PROXY_HOSTS} \
|
||||
--build-arg http_proxy=${HTTP_PROXY_URL} \
|
||||
--build-arg https_proxy=${HTTP_PROXY_URL} \
|
||||
--build-arg no_proxy=${NO_PROXY_HOSTS} \
|
||||
-f src/LiveRecorder.WebApi/Dockerfile \
|
||||
-t "\$PLAT_REF" \
|
||||
-t "\$PLAT_LATEST" \
|
||||
--load \
|
||||
.
|
||||
|
||||
echo "=== Pushing \$PLAT_REF ==="
|
||||
sudo docker push "\$PLAT_REF" 2>&1 | tail -5
|
||||
sudo docker push "\$PLAT_LATEST" 2>&1 | tail -5
|
||||
|
||||
# Free disk space before the next platform build
|
||||
sudo docker rmi "\$PLAT_REF" "\$PLAT_LATEST" 2>/dev/null || true
|
||||
done
|
||||
|
||||
echo ''
|
||||
echo "=== Creating multi-arch manifest: ${API_IMAGE_TAGGED} ==="
|
||||
sudo docker manifest create "${API_IMAGE_TAGGED}" \
|
||||
"${API_IMAGE_TAGGED}-amd64" \
|
||||
"${API_IMAGE_TAGGED}-arm64"
|
||||
sudo docker manifest create "${API_IMAGE_LATEST}" \
|
||||
"${API_IMAGE_LATEST}-amd64" \
|
||||
"${API_IMAGE_LATEST}-arm64"
|
||||
|
||||
echo "=== Pushing manifests ==="
|
||||
sudo docker manifest push "${API_IMAGE_TAGGED}" 2>&1 | tail -3
|
||||
sudo docker manifest push "${API_IMAGE_LATEST}" 2>&1 | tail -3
|
||||
|
||||
# (Optionally clean up per-platform tags from registry, but harmless to leave them)
|
||||
echo ''
|
||||
echo "API multi-arch images pushed successfully:"
|
||||
echo " ${API_IMAGE_TAGGED}"
|
||||
echo " ${API_IMAGE_LATEST}"
|
||||
"""
|
||||
}
|
||||
}
|
||||
@@ -174,6 +200,7 @@ pipeline {
|
||||
steps {
|
||||
sh """
|
||||
set -e
|
||||
|
||||
run_with_heartbeat() {
|
||||
log_file="\$1"
|
||||
build_label="\$2"
|
||||
@@ -209,31 +236,59 @@ pipeline {
|
||||
fi
|
||||
return "\$cmd_status"
|
||||
}
|
||||
sudo docker buildx inspect --builder ${BUILDER_NAME} --bootstrap >/dev/null
|
||||
echo 'Building and pushing multi-arch Web image: ${WEB_IMAGE_TAGGED}'
|
||||
run_with_heartbeat /tmp/live-recorder-web-buildx-${IMAGE_TAG}.log "Web multi-arch build" \
|
||||
sudo docker buildx build \
|
||||
--builder ${BUILDER_NAME} \
|
||||
--platform ${TARGET_PLATFORMS} \
|
||||
--network host \
|
||||
--progress=plain \
|
||||
--provenance=false \
|
||||
--cache-from type=registry,ref=${WEB_CACHE_IMAGE} \
|
||||
--cache-to type=registry,ref=${WEB_CACHE_IMAGE},mode=max \
|
||||
--build-arg NODE_IMAGE=${WEB_NODE_IMAGE} \
|
||||
--build-arg NGINX_IMAGE=${WEB_NGINX_IMAGE} \
|
||||
--build-arg HTTP_PROXY=${HTTP_PROXY_URL} \
|
||||
--build-arg HTTPS_PROXY=${HTTP_PROXY_URL} \
|
||||
--build-arg NO_PROXY=${NO_PROXY_HOSTS} \
|
||||
--build-arg http_proxy=${HTTP_PROXY_URL} \
|
||||
--build-arg https_proxy=${HTTP_PROXY_URL} \
|
||||
--build-arg no_proxy=${NO_PROXY_HOSTS} \
|
||||
-f frontend/Dockerfile \
|
||||
--build-arg VITE_API_BASE_URL=/api \
|
||||
-t ${WEB_IMAGE_TAGGED} \
|
||||
-t ${WEB_IMAGE_LATEST} \
|
||||
--push \
|
||||
frontend
|
||||
|
||||
for PLATFORM in linux/amd64 linux/arm64; do
|
||||
ARCH_TAG="\${PLATFORM##*/}"
|
||||
PLAT_REF="${WEB_IMAGE_TAGGED}-\${ARCH_TAG}"
|
||||
PLAT_LATEST="${WEB_IMAGE_LATEST}-\${ARCH_TAG}"
|
||||
|
||||
echo ''
|
||||
echo "=== Building Web for \$PLATFORM -> \$PLAT_REF ==="
|
||||
run_with_heartbeat /tmp/live-recorder-web-\${ARCH_TAG}.log "Web \${ARCH_TAG} build" \
|
||||
sudo docker buildx build \
|
||||
--platform "\$PLATFORM" \
|
||||
--network host \
|
||||
--progress=plain \
|
||||
--provenance=false \
|
||||
--cache-from type=registry,ref=${WEB_CACHE_IMAGE} \
|
||||
--build-arg NODE_IMAGE=${WEB_NODE_IMAGE} \
|
||||
--build-arg NGINX_IMAGE=${WEB_NGINX_IMAGE} \
|
||||
--build-arg HTTP_PROXY=${HTTP_PROXY_URL} \
|
||||
--build-arg HTTPS_PROXY=${HTTP_PROXY_URL} \
|
||||
--build-arg NO_PROXY=${NO_PROXY_HOSTS} \
|
||||
--build-arg http_proxy=${HTTP_PROXY_URL} \
|
||||
--build-arg https_proxy=${HTTP_PROXY_URL} \
|
||||
--build-arg no_proxy=${NO_PROXY_HOSTS} \
|
||||
-f frontend/Dockerfile \
|
||||
--build-arg VITE_API_BASE_URL=/api \
|
||||
-t "\$PLAT_REF" \
|
||||
-t "\$PLAT_LATEST" \
|
||||
--load \
|
||||
frontend
|
||||
|
||||
echo "=== Pushing \$PLAT_REF ==="
|
||||
sudo docker push "\$PLAT_REF" 2>&1 | tail -3
|
||||
sudo docker push "\$PLAT_LATEST" 2>&1 | tail -3
|
||||
sudo docker rmi "\$PLAT_REF" "\$PLAT_LATEST" 2>/dev/null || true
|
||||
done
|
||||
|
||||
echo ''
|
||||
echo "=== Creating multi-arch manifest: ${WEB_IMAGE_TAGGED} ==="
|
||||
sudo docker manifest create "${WEB_IMAGE_TAGGED}" \
|
||||
"${WEB_IMAGE_TAGGED}-amd64" \
|
||||
"${WEB_IMAGE_TAGGED}-arm64"
|
||||
sudo docker manifest create "${WEB_IMAGE_LATEST}" \
|
||||
"${WEB_IMAGE_LATEST}-amd64" \
|
||||
"${WEB_IMAGE_LATEST}-arm64"
|
||||
|
||||
echo "=== Pushing manifests ==="
|
||||
sudo docker manifest push "${WEB_IMAGE_TAGGED}" 2>&1 | tail -3
|
||||
sudo docker manifest push "${WEB_IMAGE_LATEST}" 2>&1 | tail -3
|
||||
|
||||
echo ''
|
||||
echo "Web multi-arch images pushed successfully:"
|
||||
echo " ${WEB_IMAGE_TAGGED}"
|
||||
echo " ${WEB_IMAGE_LATEST}"
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user