51 lines
1.9 KiB
Docker
51 lines
1.9 KiB
Docker
# ---- Stage 1: build ----
|
|
# This stage has the full Go toolchain and is only used to compile the
|
|
# binary. It is discarded entirely after the build - none of its ~800MB+
|
|
# footprint ends up in the final image.
|
|
FROM golang:1.26 AS builder
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy just the module files first and download dependencies before
|
|
# copying the rest of the source. Docker caches each instruction as a
|
|
# layer; as long as go.mod/go.sum don't change, this layer (and the
|
|
# downloads it triggers) is reused on every subsequent build, even if
|
|
# application code changes constantly. If we copied all source first, any
|
|
# code edit would invalidate this cache and force a full re-download every
|
|
# single build.
|
|
COPY go.mod go.sum* ./
|
|
RUN go mod download
|
|
|
|
COPY . .
|
|
|
|
# CGO_ENABLED=0 produces a fully static binary with no dynamic library
|
|
# dependencies, which is what lets it run on the minimal Alpine base image
|
|
# in stage 2 below without missing shared libraries. GOOS=linux ensures we
|
|
# cross-compile for Linux even if you're building this image on macOS or
|
|
# Windows.
|
|
RUN CGO_ENABLED=0 GOOS=linux go build -o /app/bin/server ./cmd/api
|
|
|
|
# ---- Stage 2: run ----
|
|
# A tiny (~7MB) base image that receives ONLY the compiled binary from
|
|
# stage 1 - no compiler, no source code, no build tools. Smaller image,
|
|
# smaller attack surface.
|
|
FROM alpine:3.20
|
|
|
|
# Alpine's minimal base doesn't include root CA certificates by default.
|
|
# Without these, any outbound HTTPS call this app makes (Google's OAuth2
|
|
# token exchange and userinfo endpoints) would fail with a certificate
|
|
# verification error. --no-cache avoids leaving package-manager cache
|
|
# files behind in the image.
|
|
RUN apk add --no-cache ca-certificates
|
|
|
|
WORKDIR /app
|
|
|
|
# Pull just the compiled binary out of the builder stage - this is the
|
|
# actual multi-stage mechanism: --from=builder reaches back into the FIRST
|
|
# image just for this one file.
|
|
COPY --from=builder /app/bin/server .
|
|
|
|
EXPOSE 8080
|
|
|
|
CMD ["./server"]
|