From d2e92d12b276605a08ee99a051c1edc4c62f32c8 Mon Sep 17 00:00:00 2001 From: casjay Date: Sun, 21 Jun 2026 09:43:14 -0400 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Cross-compile=20go=20install=20tool?= =?UTF-8?q?s=20to=20eliminate=20QEMU=20build=20hang=20=E2=9A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The arm64 build was stuck for 12+ hours compiling gopls, dlv, and other Go tools from source under QEMU user-mode emulation. QEMU makes Go compilation 20-50× slower than native; gopls alone can take hours. Fix: add a --platform=$BUILDPLATFORM go-tools stage in the Dockerfile that cross-compiles all go install tools natively on amd64 using Go's built-in cross-compilation (GOOS=linux GOARCH=$TARGETARCH). The binaries are then COPYed into the main build stage before 05-custom.sh runs. No QEMU is involved for any compilation step. - Dockerfile: add go-tools stage using --platform=$BUILDPLATFORM with golang:alpine; cross-compiles goimports, stringer, gopls, govulncheck, dlv, gops, benchstat, wire, mockgen, protoc-gen-go, protoc-gen-go-grpc; COPY /go/bin/ → /usr/local/bin/ before the 05-custom.sh RUN layer - rootfs/root/docker/setup/05-custom.sh: remove all go install commands (11 tools now provided by the Dockerfile stage); keep go clean -modcache/-cache cleanup Dockerfile rootfs/root/docker/setup/05-custom.sh --- Dockerfile | 22 ++++++++++++++ rootfs/root/docker/setup/05-custom.sh | 43 +++------------------------ 2 files changed, 26 insertions(+), 39 deletions(-) diff --git a/Dockerfile b/Dockerfile index ccf7065..1443903 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,6 +29,26 @@ ARG DISTRO_VERSION="${IMAGE_VERSION}" ARG BUILD_VERSION="${BUILD_DATE}" FROM tianon/gosu:latest AS gosu + +# Build Go tools natively on the host platform using Go's cross-compilation. +# This avoids QEMU emulation for arm64 and reduces compile time from hours to minutes. +FROM --platform=$BUILDPLATFORM golang:alpine AS go-tools +ARG TARGETOS=linux +ARG TARGETARCH +ENV CGO_ENABLED=0 +RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go install \ + golang.org/x/tools/cmd/goimports@latest \ + golang.org/x/tools/cmd/stringer@latest \ + golang.org/x/tools/gopls@latest \ + golang.org/x/vuln/cmd/govulncheck@latest \ + github.com/go-delve/delve/cmd/dlv@latest \ + github.com/google/gops@latest \ + golang.org/x/perf/cmd/benchstat@latest \ + github.com/google/wire/cmd/wire@latest \ + go.uber.org/mock/mockgen@latest \ + google.golang.org/protobuf/cmd/protoc-gen-go@latest \ + google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest + FROM ${PULL_URL}:${DISTRO_VERSION} AS build ARG TZ ARG USER @@ -159,6 +179,8 @@ RUN echo "Custom Applications"; \ $SHELL_OPTS; \ echo "" +COPY --from=go-tools /go/bin/ /usr/local/bin/ + RUN echo "Running custom commands"; \ if [ -f "/root/docker/setup/05-custom.sh" ];then echo "Running the custom script";/root/docker/setup/05-custom.sh||{ echo "Failed to execute /root/docker/setup/05-custom.sh" && exit 10; };echo "Done running the custom script";fi; \ echo "" diff --git a/rootfs/root/docker/setup/05-custom.sh b/rootfs/root/docker/setup/05-custom.sh index 0042a61..809289e 100755 --- a/rootfs/root/docker/setup/05-custom.sh +++ b/rootfs/root/docker/setup/05-custom.sh @@ -191,45 +191,10 @@ _install_bin \ "https://github.com/pressly/goose/releases/download/${_GOOSE_VER}/goose_linux_${_ARCH_GLIBC}" \ "goose" -# - - - - - - - - - - - - - - - - - - - - - - - - - -# go install for tools without standalone release binaries - -echo "Installing Go tooling via go install" - -# Import organiser — superset of gofmt that also manages import groups -go install golang.org/x/tools/cmd/goimports@latest - -# Generate String() methods for iota-based types -go install golang.org/x/tools/cmd/stringer@latest - -# Official Go language server (no binary releases; must compile) -go install golang.org/x/tools/gopls@latest - -# Vulnerability scanner against the Go vulnerability database -go install golang.org/x/vuln/cmd/govulncheck@latest - -# Source-level debugger -go install github.com/go-delve/delve/cmd/dlv@latest - -# Live process diagnostics: list Go processes, dump stacks, force GC -go install github.com/google/gops@latest - -# Benchmark comparison — statistically sound diff of pprof benchmark runs -go install golang.org/x/perf/cmd/benchstat@latest - -# Compile-time dependency injection code generator -go install github.com/google/wire/cmd/wire@latest - -# Mock generator for interfaces (Uber fork of golang/mock) -go install go.uber.org/mock/mockgen@latest - -# protobuf Go code generator -go install google.golang.org/protobuf/cmd/protoc-gen-go@latest - -# gRPC Go code generator -go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest - -echo "Go tooling installed" +# go install tools (goimports, stringer, gopls, govulncheck, dlv, gops, benchstat, +# wire, mockgen, protoc-gen-go, protoc-gen-go-grpc) are cross-compiled natively on +# the build platform in the Dockerfile go-tools stage and copied to /usr/local/bin +# before this script runs — no QEMU-emulated compilation needed here. # Strip the module download cache and ephemeral build cache from this layer go clean -modcache