mirror of
https://github.com/dockersrc/go
synced 2026-06-24 20:01:07 -04:00
⚡ Cross-compile go install tools to eliminate QEMU build hang ⚡
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
This commit is contained in:
+22
@@ -29,6 +29,26 @@ ARG DISTRO_VERSION="${IMAGE_VERSION}"
|
|||||||
ARG BUILD_VERSION="${BUILD_DATE}"
|
ARG BUILD_VERSION="${BUILD_DATE}"
|
||||||
|
|
||||||
FROM tianon/gosu:latest AS gosu
|
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
|
FROM ${PULL_URL}:${DISTRO_VERSION} AS build
|
||||||
ARG TZ
|
ARG TZ
|
||||||
ARG USER
|
ARG USER
|
||||||
@@ -159,6 +179,8 @@ RUN echo "Custom Applications"; \
|
|||||||
$SHELL_OPTS; \
|
$SHELL_OPTS; \
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
COPY --from=go-tools /go/bin/ /usr/local/bin/
|
||||||
|
|
||||||
RUN echo "Running custom commands"; \
|
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; \
|
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 ""
|
echo ""
|
||||||
|
|||||||
@@ -191,45 +191,10 @@ _install_bin \
|
|||||||
"https://github.com/pressly/goose/releases/download/${_GOOSE_VER}/goose_linux_${_ARCH_GLIBC}" \
|
"https://github.com/pressly/goose/releases/download/${_GOOSE_VER}/goose_linux_${_ARCH_GLIBC}" \
|
||||||
"goose"
|
"goose"
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - -
|
# go install tools (goimports, stringer, gopls, govulncheck, dlv, gops, benchstat,
|
||||||
# go install for tools without standalone release binaries
|
# 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
|
||||||
echo "Installing Go tooling via go install"
|
# before this script runs — no QEMU-emulated compilation needed here.
|
||||||
|
|
||||||
# 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"
|
|
||||||
|
|
||||||
# Strip the module download cache and ephemeral build cache from this layer
|
# Strip the module download cache and ephemeral build cache from this layer
|
||||||
go clean -modcache
|
go clean -modcache
|
||||||
|
|||||||
Reference in New Issue
Block a user