Skip to content

Commit 068c4e5

Browse files
committed
Optimize Docker build for multi-arch
- Use --platform=$BUILDPLATFORM for native compilation - Cross-compile with GOOS/GOARCH (avoids slow QEMU emulation) - Add cache mounts for Go modules and build cache - Use distroless runtime for smaller image - Add provenance: false to skip slow SLSA generation
1 parent df15a1d commit 068c4e5

2 files changed

Lines changed: 22 additions & 18 deletions

File tree

.github/workflows/release.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,4 @@ jobs:
7777
labels: ${{ steps.meta.outputs.labels }}
7878
cache-from: type=gha
7979
cache-to: type=gha,mode=max
80+
provenance: false

Dockerfile

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Multi-stage build for TSFlow with embedded frontend
2+
# Optimized for multi-arch builds (amd64/arm64)
23

34
# Frontend build stage
45
FROM node:20-alpine AS frontend-build
@@ -9,42 +10,44 @@ COPY frontend/package*.json ./
910
RUN npm ci
1011

1112
COPY frontend/ ./
12-
# Build outputs to ../backend/frontend/dist (relative to frontend/)
1313
RUN 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

1821
WORKDIR /app/backend
1922

20-
RUN apk add --no-cache git
23+
RUN apk add --no-cache git ca-certificates
2124

2225
COPY 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

2531
COPY backend/ ./
26-
# Copy built frontend into backend/frontend/dist for embedding
2732
COPY --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

3743
WORKDIR /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
4347
ENV ENVIRONMENT=production
4448

4549
EXPOSE 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

Comments
 (0)