# Multi-stage build for the API gateway. # # The runtime stage is distroless/static: no shell, no package manager, no libc. # That is deliberate — see tasks/6.1-hardened-image.md. It also means the binary # must be fully static, hence CGO_ENABLED=0. # --platform=$BUILDPLATFORM pins the build stage to the machine doing the # building, then Go cross-compiles to $TARGETARCH. Without it, building an # amd64 image from an arm64 workstation runs the whole toolchain under QEMU. FROM --platform=$BUILDPLATFORM golang:1.25-bookworm AS build WORKDIR /src # Copy the module files first so dependency download is cached independently of # source changes. The gateway is stdlib + yaml.v3 only, so this is fast either way. COPY go.mod go.sum ./ RUN go mod download COPY . . # VERSION is stamped in so a running pod can be traced back to an exact build. ARG VERSION=dev # TARGETARCH is supplied by buildx from --platform. Defaulted to amd64 because # every node in the cluster is amd64; a plain `docker build` on an arm64 # workstation would otherwise silently produce an unrunnable image. ARG TARGETARCH=amd64 # -trimpath strips local filesystem paths from the binary. # -w -s drop DWARF and the symbol table; nothing debugs off the production image. RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build \ -trimpath \ -ldflags="-w -s -X main.version=${VERSION}" \ -o /out/gateway ./cmd/gateway # Run the test suite inside the build so a broken commit cannot produce an image. # Separate stage: it is skipped unless targeted, keeping the default build fast. # CGO_ENABLED=1 here on purpose: the race detector requires cgo, so this cannot # reuse the static build's flags. FROM build AS test RUN go vet ./... && CGO_ENABLED=1 go test ./... -race FROM gcr.io/distroless/static-debian12:nonroot # 65532 is distroless's "nonroot" user. It matches runAsUser in the Deployment's # securityContext; if one changes, both must. USER 65532:65532 # distroless/static has no CA certs. Copy them from the build stage so Go's # crypto/tls can verify the Kubernetes API server certificate. COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt COPY --from=build /out/gateway /gateway EXPOSE 8080 ENTRYPOINT ["/gateway"]