The 'docker buildx create --name X ssh://...' driver hangs against
docker-build.haven with 'waiting for connection: context deadline exceeded',
even though SSH, the daemon, and dial-stdio all work. Root cause is that
docker-container-driver-over-SSH path; the remote daemon's own default
buildkit (containerd-snapshotter) works fine.
Rework:
- create a docker *context* over SSH and run 'docker --context remote-builder
buildx build --push' directly (drops docker/build-push-action, which needs
a named builder)
- (re)install qemu/binfmt on the remote each run when an arm* platform is
requested (binfmt is kernel state, lost on daemon/host restart -- this was
causing 'exec format error' for arm64 after the daemon was restarted)
- gentags now emits -t args for the direct buildx invocation
Validated end-to-end on real infra: multi-arch amd64+arm64 build + push to
git.ivanch.me/ivanch/pipeline-actions-selftest:citest, manifest confirmed
multi-arch.
ConnectTimeout only bounds the TCP handshake; wrap ssh in a 25s timeout
plus keepalives so a firewall that accepts SYN then drops packets fails
fast with a clear diagnostic instead of hanging the runner.
buildx refuses a builder instance whose name matches an existing docker
context. Create the builder directly from the ssh:// endpoint and clean up
any leftover context/builder of the same name first (idempotent re-runs).
- DOCKER_HOST env var was set to the builder hostname, which Docker treats
as tcp://host:2375 and which overrides the active docker context, so the
SSH remote-builder context was ignored (Cannot connect to tcp://docker-build.haven:2375)
- context endpoint used a literal ssh://***@ instead of the docker_user input
- create an actual buildx builder instance named remote-builder (build-push-action
needs a builder instance, not just a context)