57 lines
1.6 KiB
Docker
57 lines
1.6 KiB
Docker
# syntax=docker/dockerfile:1.7
|
|
|
|
############################
|
|
# Frontend build (Vite/React)
|
|
############################
|
|
# Run toolchains on the build machine, not target arch
|
|
FROM --platform=$BUILDPLATFORM node:20-alpine AS fe
|
|
WORKDIR /src/frontend
|
|
COPY frontend/package*.json ./
|
|
RUN --mount=type=cache,target=/root/.npm npm ci
|
|
COPY frontend/ .
|
|
RUN npm run build
|
|
# expose artifacts in a neutral location
|
|
RUN mkdir -p /out && cp -r dist/* /out/
|
|
|
|
############################
|
|
# Backend build (Go)
|
|
############################
|
|
FROM --platform=$BUILDPLATFORM golang:1.22-alpine AS be
|
|
RUN apk add --no-cache ca-certificates upx git
|
|
ARG TARGETOS
|
|
ARG TARGETARCH
|
|
ENV CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
|
|
GOPROXY=https://proxy.golang.org,direct \
|
|
GOPRIVATE=scm.bstein.dev
|
|
|
|
WORKDIR /src/backend
|
|
|
|
# 1) Cache modules
|
|
COPY backend/go.mod backend/go.sum ./
|
|
RUN --mount=type=cache,target=/go/pkg/mod go mod download
|
|
|
|
# 2) Source
|
|
COPY backend/ .
|
|
|
|
# 3) FE assets where the embed expects them (//go:embed web/dist/**)
|
|
COPY --from=fe /out ./web/dist
|
|
|
|
# 4) Tidy (in case new deps appeared)
|
|
RUN --mount=type=cache,target=/go/pkg/mod go mod tidy
|
|
|
|
# 5) Build the binary; fail if build fails; allow UPX to fail only.
|
|
RUN --mount=type=cache,target=/go/pkg/mod \
|
|
set -eux; \
|
|
mkdir -p /out; \
|
|
go build -trimpath -ldflags="-s -w" -o /out/pegasus ./main.go; \
|
|
test -f /out/pegasus; \
|
|
upx -q --lzma /out/pegasus || true
|
|
|
|
############################
|
|
# Final, minimal image
|
|
############################
|
|
FROM gcr.io/distroless/static:nonroot AS final
|
|
COPY --from=be /out/pegasus /pegasus
|
|
USER nonroot:nonroot
|
|
ENTRYPOINT ["/pegasus"]
|