A few things I’ve learned about writing better Dockerfiles.

Use Multi-Stage Builds Link to heading

Keep your final images small by separating build and runtime stages:

FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o main .

FROM alpine:latest
COPY --from=builder /app/main /main
ENTRYPOINT ["/main"]

Order Matters Link to heading

Put frequently changing instructions last to maximize layer caching:

  1. System dependencies (rarely change)
  2. Application dependencies (occasionally change)
  3. Application code (frequently changes)

Don’t Run as Root Link to heading

RUN adduser -D appuser
USER appuser

Security matters, even in containers.