The docker-container driver's buildkit session mechanism does not reliably
forward host Docker credentials to the buildkit container, causing every
docker buildx build --push to fail with 401 Unauthorized on the manifest
HEAD request.
Fix: remove the standalone Login Registry stage and embed withCredentials
directly into each build stage, passing credentials to buildkit via the
docker buildx build --auth flag:
--auth 'reg.nxsir.cn=:'
This sends auth directly to buildkit rather than relying on the implicit
docker login -> config.json -> session forwarding chain.
Each stage also does a docker login for the host CLI (needed for
buildx inspect --bootstrap to pull images from the registry, and for
cache-from/cache-to operations).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Docker buildx create --driver-opt splits values on commas as list
separators, causing 'env.NO_PROXY=127.0.0.1,localhost,...' to be parsed
as separate key=value entries and failing with:
invalid value "localhost", expecting k=v
The NO_PROXY hosts for build containers are already passed via build-arg
in the build stage; the buildkit container itself doesn't need them.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Move Login Registry stage before Prepare Buildx so Docker credentials are
in /root/.docker/config.json BEFORE the buildx docker-container builder
is created and bootstrapped. Previously the builder started without auth,
causing buildx --push to fail with '401 Unauthorized' on the manifest
HEAD request (blob layers pushed but manifest rejected).
Also expand the NO_PROXY driver-opt from just 'reg.nxsir.cn' to the full
NO_PROXY_HOSTS list (Tsighua, MCR, daocloud) so the buildkit container
itself also bypasses the proxy for these direct-reachable registries.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The 7890 proxy intermittently returns '502 Bad Gateway' when tunneling to
mirrors.tuna.tsinghua.edu.cn (observed on libglapi-mesa during
apt-get install in the runtime layer). The Tsinghua mirror, MCR, and
daocloud are all directly reachable from this builder, so the proxy adds
no value and only introduces failure modes.
Add the following hosts to NO_PROXY_HOSTS so apt/curl inside the build
containers hit them directly:
- mirrors.tuna.tsinghua.edu.cn, .tsinghua.edu.cn
- mcr.microsoft.com
- docker.m.daocloud.io
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Multi-platform buildx (linux/amd64 + linux/arm64) races both platforms in
parallel by default. On the 4GB build agent, QEMU-emulated 'dotnet restore'
for arm64 alone spikes to 2-3GB and racing amd64 apt-installs push us into
the OOM Killer ("cannot allocate memory" at build 4/5).
Fix: write a small buildkitd.toml with max-parallelism = 1 and pass it to
'docker buildx create --config'. buildkit now runs stages sequentially so
the two platforms don't step on each other's RSS.
Recreate the builder every run so the config always takes effect.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The build agent cannot reach auth.docker.io from behind the local network,
causing 'docker run tonistiigi/binfmt --install arm64' to fail with a token
fetch timeout.
Fix: three-tier fallback for ARM64 binfmt registration:
1. Skip if /proc/sys/fs/binfmt_misc/qemu-aarch64 already exists.
2. Pull tonistiigi/binfmt via docker.m.daocloud.io mirror.
3. Fall back to qemu-user-static via apt.
Add a post-registration sanity check (arm64 alpine + uname -m) so
misconfigured builders fail fast rather than at buildx invocation time.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>