# syntax=docker/dockerfile:1.7 # # Multi-stage build: # 1. Build static binary with pinned Go version (matching go.mod). # 2. Copy into distroless static nonroot runtime image. # # Build args (optional): # VERSION - semantic/app version (default: dev) # GIT_COMMIT - git SHA (default: unknown) # BUILD_DATE - RFC3339 build timestamp # # Example build: # docker build \ # --build-arg VERSION=$(git describe --tags --always) \ # --build-arg GIT_COMMIT=$(git rev-parse HEAD) \ # --build-arg BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ) \ # -t go-cart-actor:dev . # # If you add subpackages or directories, no Dockerfile change needed (COPY . .). # Ensure a .dockerignore exists to keep context lean. ############################ # Build Stage ############################ FROM golang:1.26-alpine AS build WORKDIR /src RUN apk add --no-cache git # Build metadata (can be overridden at build time) ARG VERSION=dev ARG GIT_COMMIT=unknown ARG BUILD_DATE=unknown # Ensure reproducible static build # Multi-arch build args (TARGETOS/TARGETARCH provided automatically by buildx) ARG TARGETOS ARG TARGETARCH ENV CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} # Sibling module sources, supplied as BuildKit named contexts (see # deploy/docker-compose.yml additional_contexts + deploy/k8s/build-push.sh # --build-context). They are resolved locally via the go.work written below, # because the renamed git.k6n.net/mats/* modules are not yet published. COPY --from=slaskfinder . ./slask-finder COPY --from=redisinventory . ./go-redis-inventory # This module's source (relay on .dockerignore to prune). COPY . ./go-cart-actor RUN printf 'go 1.26.2\n\nuse (\n\t.\n\t../slask-finder\n\t../go-redis-inventory\n)\n' > ./go-cart-actor/go.work WORKDIR /src/go-cart-actor # (Optional) If you do NOT check in generated protobuf code, uncomment generation: # RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@latest && \ # go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest && \ # protoc --go_out=. --go_opt=paths=source_relative \ # --go-grpc_out=. --go-grpc_opt=paths=source_relative \ # proto/*.proto # Build with minimal binary size and embedded metadata RUN go build -trimpath -ldflags="-s -w \ -X main.Version=${VERSION} \ -X main.GitCommit=${GIT_COMMIT} \ -X main.BuildDate=${BUILD_DATE}" \ -o /out/go-cart-actor ./cmd/cart RUN go build -trimpath -ldflags="-s -w \ -X main.Version=${VERSION} \ -X main.GitCommit=${GIT_COMMIT} \ -X main.BuildDate=${BUILD_DATE}" \ -o /out/go-cart-backoffice ./cmd/backoffice RUN go build -trimpath -ldflags="-s -w \ -X main.Version=${VERSION} \ -X main.GitCommit=${GIT_COMMIT} \ -X main.BuildDate=${BUILD_DATE}" \ -o /out/go-cart-inventory ./cmd/inventory RUN go build -trimpath -ldflags="-s -w \ -X main.Version=${VERSION} \ -X main.GitCommit=${GIT_COMMIT} \ -X main.BuildDate=${BUILD_DATE}" \ -o /out/go-checkout-actor ./cmd/checkout ############################ # Runtime Stage ############################ # Using distroless static (nonroot) for minimal surface area. FROM gcr.io/distroless/static-debian12:nonroot AS runtime WORKDIR / COPY --from=build /out/go-cart-actor /go-cart-actor COPY --from=build /out/go-checkout-actor /go-checkout-actor COPY --from=build /out/go-cart-backoffice /go-cart-backoffice COPY --from=build /out/go-cart-inventory /go-cart-inventory # Document (not expose forcibly) typical ports: 8080 (HTTP), 1337 (gRPC) EXPOSE 8080 1337 USER nonroot:nonroot ENTRYPOINT ["/go-cart-actor"]