# Build both binaries # Use BUILDPLATFORM so Go runs natively, cross-compile for target arch FROM --platform=$BUILDPLATFORM golang:1.25-trixie AS builder ARG TARGETOS ARG TARGETARCH ARG BUILDARCH # Install C cross-compiler for CGO when building arm64 from amd64 RUN if [ "$BUILDARCH" = "amd64" ] && [ "$TARGETARCH" = "arm64" ]; then \ apt-get update && apt-get install -y gcc-aarch64-linux-gnu && rm -rf /var/lib/apt/lists/*; \ fi WORKDIR /workspace # Copy go mod files and download deps COPY go.mod go.sum ./ RUN go mod download # Copy source code COPY api/ api/ COPY cmd/ cmd/ COPY internal/ internal/ # Build runner (static, no CGO) # Use -s -w to strip debug symbols and reduce binary size RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} \ go build -a -ldflags='-s -w -extldflags "-static"' \ -o loom-runner ./cmd/runner # Build controller (requires CGO for sqlite3) # Use -s -w to strip debug symbols and reduce binary size # Use cross-compiler for arm64 when building from amd64 RUN CC=$(if [ "$TARGETARCH" = "arm64" ] && [ "$BUILDARCH" = "amd64" ]; then echo "aarch64-linux-gnu-gcc"; else echo "gcc"; fi) && \ CGO_ENABLED=1 CC=$CC GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} \ go build -a -ldflags='-s -w' -o manager ./cmd/controller # Unified image with both binaries FROM gcr.io/distroless/base-debian13:nonroot COPY --from=builder /workspace/manager /manager COPY --from=builder /workspace/loom-runner /loom-runner LABEL org.opencontainers.image.title="Loom" \ org.opencontainers.image.description="Kubernetes Operator for Tangled Spindles " \ org.opencontainers.image.authors="Evan Jarrett" \ org.opencontainers.image.source="https://tangled.org/evan.jarrett.net/loom" \ org.opencontainers.image.documentation="https://tangled.org/evan.jarrett.net/loom" \ org.opencontainers.image.licenses="Apache-2.0" \ org.opencontainers.image.version="latest" ENTRYPOINT ["/manager"]