# --platform=$BUILDPLATFORM pins the builder to the machine doing the building, so a # multi-arch build compiles both targets natively instead of running an emulated arm64 # toolchain under QEMU. Go cross-compiles from TARGETOS/TARGETARCH, which BuildKit fills # in per platform. The CI runner has no binfmt registration and no way to get one (the # JS action that used to install it cannot run there), so this is not just an # optimisation -- it is what makes the arm64 image buildable at all. FROM --platform=$BUILDPLATFORM golang:1.25-alpine AS builder WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . ARG VERSION=dev ARG TARGETOS ARG TARGETARCH RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ go build -ldflags="-w -s -X main.version=${VERSION}" -o /terdut ./cmd/terdut FROM scratch # scratch has no trust store, and a Go binary on it fails every HTTPS call with # "x509: certificate signed by unknown authority". Nothing needed one until single # sign-on: discovery and the token exchange are HTTPS calls to the identity provider. # The bundle is the builder's, copied by name so a missing file fails the build # rather than shipping an image that cannot sign anybody in. COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt COPY --from=builder /terdut /terdut EXPOSE 8080 ENTRYPOINT ["/terdut"]