11# Multi-stage build for TSFlow with embedded frontend
2+ # Optimized for multi-arch builds (amd64/arm64)
23
34# Frontend build stage
45FROM node:20-alpine AS frontend-build
@@ -9,42 +10,44 @@ COPY frontend/package*.json ./
910RUN npm ci
1011
1112COPY frontend/ ./
12- # Build outputs to ../backend/frontend/dist (relative to frontend/)
1313RUN npm run build
1414
15- # Backend build stage
16- FROM golang:1.25-alpine AS backend-build
15+ # Backend build stage - compile on native arch, cross-compile for target
16+ FROM --platform=$BUILDPLATFORM golang:1.25-alpine AS backend-build
17+
18+ ARG TARGETOS
19+ ARG TARGETARCH
1720
1821WORKDIR /app/backend
1922
20- RUN apk add --no-cache git
23+ RUN apk add --no-cache git ca-certificates
2124
2225COPY backend/go.mod backend/go.sum ./
23- RUN go mod download
26+
27+ # Cache Go modules
28+ RUN --mount=type=cache,target=/go/pkg/mod \
29+ go mod download
2430
2531COPY backend/ ./
26- # Copy built frontend into backend/frontend/dist for embedding
2732COPY --from=frontend-build /app/backend/frontend/dist ./frontend/dist
2833
29- # Build with embedded frontend
30- RUN CGO_ENABLED=0 GOOS=linux go build -o tsflow ./main.go
31-
32- # Runtime stage - single binary, no separate frontend files needed
33- FROM alpine:latest
34+ # Cross-compile with cache mounts for speed
35+ RUN --mount=type=cache,target=/go/pkg/mod \
36+ --mount=type=cache,target=/root/.cache/go-build \
37+ CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
38+ go build -ldflags= "-w -s" -trimpath -o tsflow ./main.go
3439
35- RUN apk --no-cache add ca-certificates
40+ # Runtime stage - distroless for minimal image
41+ FROM gcr.io/distroless/static:nonroot
3642
3743WORKDIR /app
3844
39- # Only copy the binary - frontend is embedded
40- COPY --from=backend-build /app/backend/tsflow ./
45+ COPY --from=backend-build /app/backend/tsflow .
4146
42- # Set default environment to production
4347ENV ENVIRONMENT=production
4448
4549EXPOSE 8080
4650
47- HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
48- CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
51+ USER 65532:65532
4952
50- CMD [". /tsflow" ]
53+ ENTRYPOINT ["/app /tsflow" ]
0 commit comments