Dockerfile For Go Basics
Fast recall
Quick revision
Core answer
Whether you understand Dockerfile For Go Basics beyond memorized syntax.
Giving a definition without explaining a practical trade-off.
Connect the concept to a small production example and state its complexity or failure mode.
Interview-ready guide
Interview answer
The multi-stage Dockerfile:
# Stage 1: Build (the golang image)
FROM golang:1.22-alpine AS builder
WORKDIR /app
# Layer caching: go.mod/go.sum first (deps change rarely)
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o server .
# Stage 2: Runtime (minimal — just the binary)
FROM alpine:latest
COPY --from=builder /app/server /server
EXPOSE 8080
CMD ["/server"]Why multi-stage: the build stage (golang image — the toolchain, ~800MB) stays behind; the runtime stage copies ONLY the compiled binary (~15MB) into an Alpine image (~5MB) — the final image is ~20MB, not 800MB. Each stage is a separate image; only the final one ships.
The Go-specific flags: CGO_ENABLED=0 — static binary (no libc dependency — runs on scratch) GOOS=linux, GOARCH=amd64 (or arm64) — cross-compile for the target
The layer caching (the CI-speed win): COPY go.mod go.sum FIRST + RUN go mod download. The dependency layer only rebuilds when go.mod changes. Then COPY . . (the code — changes every build, but the cached dep layer survives). Without this, every build re-downloads the world.
The variants: scratch (FROM scratch — literally empty: the binary alone, 15MB, zero CVE surface); alpine (the convenience shell: ~5MB, the busybox tools); distroless (the hardened middle: no shell, no package manager, minimal).
Dockerfile For Go Basics
Direct Answer
Multi-stage: golang image for build, minimal image for runtime. COPY go.mod go.sum → download deps → COPY source → CGO_ENABLED=0 go build → copy the binary to a scratch/alpine image. Final image is megabytes.
Deep Dive & Architecture
The static-binary mechanics: CGO_ENABLED=0 makes the Go compiler emit a binary with no cgo calls — no libc linkage. The binary is completely self-contained (the Go runtime, the net stack, everything linked in) — which is why FROM scratch works. With CGO (a SQLite driver, for instance), the binary needs the C library, and scratch fails — the Dockerfile needs alpine or distroless.
The build-cache internals: Docker layers are content-addressed — COPY go.mod go.sum + RUN go mod download form two layers; the second is valid until the first's content changes. COPY . . is the layer that invalidates every build (the source changes). The ordering — rarely-changing first (deps), frequently-changing last (code) — is the caching discipline for any language's Dockerfile.
The distroless-vs-alpine-vs-scratch trade: scratch (5MB with the binary — zero attack surface, nothing to debug with); alpine (a shell for debugging — but a bigger surface + musl libc nuances); distroless (Google's images: no shell, minimal but with certs/timezone — the production default). The choice: scratch/distroless for prod, alpine for the debuggability during development.
Common Mistakes & Pitfalls
Giving a definition without explaining a practical trade-off.
Check your understanding
Answer these without looking back at the article.
- When would you use Dockerfile For Go Basics in a real project?
- How would you compare Dockerfile For Go Basics with an alternative?
- What is a common mistake when using Dockerfile For Go Basics?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.