From 9a631145eeeabfd08091afb2351af258cac4ac86 Mon Sep 17 00:00:00 2001 From: Andreas Fritzler Date: Fri, 21 Feb 2025 15:55:32 +0100 Subject: [PATCH] Fix multi-arch docker build --- Dockerfile | 65 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/Dockerfile b/Dockerfile index 377d3a7d..53e78ea7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,16 +2,16 @@ FROM --platform=$BUILDPLATFORM golang:1.23-bookworm AS builder WORKDIR /workspace + # Copy the Go Modules manifests -COPY go.mod go.mod -COPY go.sum go.sum -# cache deps before building and copying source so that we don't need to re-download as much -# and so that source changes don't invalidate our downloaded layer +COPY go.mod go.sum ./ + +# Cache dependencies before copying source code RUN --mount=type=cache,target=/root/.cache/go-build \ --mount=type=cache,target=/go/pkg \ go mod download -# Copy the go source +# Copy the Go source code COPY api/ api/ COPY internal/ internal/ COPY cmd/ cmd/ @@ -19,38 +19,51 @@ COPY hack/ hack/ ARG TARGETOS ARG TARGETARCH +ARG BUILDPLATFORM +ENV BUILDARCH=amd64 -# Install AMD64 dependencies -RUN if [ "$TARGETARCH" = "amd64" ]; then \ - apt-get update && apt-get install -y --no-install-recommends \ - qemu-user-static qemu-utils ca-certificates \ - libvirt-clients libcephfs-dev librbd-dev librados-dev libc-bin \ - gcc g++ \ - && update-ca-certificates \ - && rm -rf /var/lib/apt/lists/*; \ - fi +# Install common dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + qemu-user-static qemu-utils ca-certificates \ + libvirt-clients libcephfs-dev librbd-dev librados-dev libc-bin \ + gcc g++ \ + && update-ca-certificates \ + && rm -rf /var/lib/apt/lists/* -# Install ARM64 dependencies -RUN if [ "$TARGETARCH" = "arm64" ]; then \ +# Install cross-compiler for ARM64 if building for arm64 on an amd64 host +RUN if [ "$TARGETARCH" = "arm64" ] && [ "$BUILDARCH" = "amd64" ]; then \ dpkg --add-architecture arm64 && \ apt-get update && apt-get install -y --no-install-recommends \ - gcc-aarch64-linux-gnu librbd-dev:arm64 librados-dev:arm64 libc6-dev:arm64 \ - && rm -rf /var/lib/apt/lists/*; \ + gcc-aarch64-linux-gnu librbd-dev:arm64 librados-dev:arm64 libc6-dev:arm64; \ fi -# Build the binary with the necessary flags -RUN --mount=type=cache,target=/root/.cache/go-build \ - --mount=type=cache,target=/go/pkg \ +# Install cross-compiler for AMD64 if building for amd64 on an arm64 host +RUN if [ "$TARGETARCH" = "amd64" ] && [ "$BUILDARCH" = "arm64" ]; then \ + apt-get install -y --no-install-recommends \ + gcc g++; \ + fi + +# Set compiler and linker flags based on target architecture +ENV CC="" +ENV CGO_LDFLAGS="" + +RUN if [ "$TARGETARCH" = "arm64" ]; then \ + export CC="/usr/bin/aarch64-linux-gnu-gcc"; \ + export CGO_LDFLAGS="-L/usr/lib/aarch64-linux-gnu -Wl,-lrados -Wl,-lrbd"; \ + elif [ "$TARGETARCH" = "amd64" ]; then \ + export CC="/usr/bin/gcc"; \ + export CGO_LDFLAGS="-L/usr/lib/x86_64-linux-gnu -Wl,-lrados -Wl,-lrbd"; \ + fi && \ CGO_ENABLED=1 GOOS=$TARGETOS GOARCH=$TARGETARCH \ - CGO_LDFLAGS="$(if [ "$TARGETARCH" = "arm64" ]; then echo "-L/usr/lib/aarch64-linux-gnu -Wl,-lrados -Wl,-lrbd"; else echo "-L/usr/lib/x86_64-linux-gnu -Wl,-lrados -Wl,-lrbd"; fi)" \ - CC="$(if [ "$TARGETARCH" = "arm64" ]; then echo "/usr/bin/aarch64-linux-gnu-gcc"; else echo "/usr/bin/gcc"; fi)" \ + CC="$CC" CGO_LDFLAGS="$CGO_LDFLAGS" \ go build -ldflags="-s -w -linkmode=external" -o libvirt-provider ./cmd/libvirt-provider/main.go -# go build -ldflags="-s -w $(if [ "$TARGETARCH" = "arm64" ]; then echo "-linkmode=external -extld=/usr/bin/aarch64-linux-gnu-ld"; fi)" -o libvirt-provider ./cmd/libvirt-provider/main.go # Install irictl-machine RUN --mount=type=cache,target=/root/.cache/go-build \ --mount=type=cache,target=/go/pkg \ - CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH GO111MODULE=on go install github.com/ironcore-dev/ironcore/irictl-machine/cmd/irictl-machine@main + CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH GO111MODULE=on \ + go install github.com/ironcore-dev/ironcore/irictl-machine/cmd/irictl-machine@main && \ + ls -l /workspace # Since we're leveraging apt to pull in dependencies, we use `gcr.io/distroless/base` because it includes glibc. FROM gcr.io/distroless/base-debian11 AS distroless-base @@ -111,7 +124,7 @@ COPY --from=builder /usr/lib/${LIB_DIR_PREFIX}-linux-gnu/ceph/libceph-common.so. COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ COPY --from=builder /workspace/libvirt-provider /libvirt-provider -COPY --from=builder /go/bin/irictl-machine /irictl-machine +COPY --from=builder /workspace/irictl-machine /irictl-machine USER 65532:65532