Multi-Stage Docker Builds for Go
Builder stage with scratch/alpine final image
Multi-Stage Docker Builds for Go is a free Go Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Go Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why multi-stage?
A single-stage build that compiles Go code produces a large image with the full Go toolchain. Multi-stage builds compile in one stage and copy only the binary into a minimal final image.
Basic multi-stage Dockerfile
Build stage compiles the binary; final stage copies it into a minimal base:
FROM golang:1.22-alpine AS build
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o myapp ./cmd/server
FROM scratch
COPY --from=build /app/myapp /myapp
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
ENTRYPOINT ["/myapp"]FROM scratch
A FROM scratch image has nothing — no shell, no OS libraries. The Go binary must be statically linked (CGO_ENABLED=0) and include all needed files explicitly.
FROM distroless
Google's distroless images provide minimal OS libs (CA certs, timezone data) without a shell — safer than scratch for binaries that need libc or TLS certs.
FROM gcr.io/distroless/static-debian12
COPY --from=build /app/myapp /
ENTRYPOINT ["/myapp"]FROM alpine for a shell
Use Alpine as the final base when you need a shell for debugging or if the binary uses CGO. Alpine adds ~5MB but includes a shell and package manager.
Layer caching for go.mod
Copy go.mod and go.sum first and run go mod download before copying source code. This layer is cached until dependencies change, speeding up rebuilds.
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build ...-ldflags="-s -w"
-s strips the symbol table; -w strips DWARF debug information. Together they reduce binary size by 30-50% with no runtime impact.
Build arguments
Use ARG to inject version info at build time:
ARG VERSION=dev
RUN go build -ldflags="-X main.version=${VERSION}" -o myapp .Non-root user
Run the binary as a non-root user for security. Add a user in a base image or use distroless's nonroot tag:
FROM gcr.io/distroless/static-debian12:nonrootFinal image size
A typical Go binary from scratch is 5-20 MB. Alpine adds ~5MB. A full golang image is ~800MB. Multi-stage builds reduce attack surface and image pull time significantly.
.dockerignore
Add a .dockerignore to exclude files from the build context: vendor/, .git/, *.test, *.prof. This speeds up the Docker build and prevents sensitive files from being included.
.git
vendor
*.test
*.prof
.envQuick Check
Why must CGO_ENABLED=0 be set when building a Go binary for a FROM scratch Docker image?
Recap: Multi-Stage Docker Builds
Key points:
- Build stage: golang image; final stage: scratch/distroless/alpine
- CGO_ENABLED=0 for static binary (required for scratch)
- Copy go.mod first for layer caching; -ldflags="-s -w" for smaller binary
- .dockerignore to exclude .git, vendor, test files
Frequently asked questions
Is the “Multi-Stage Docker Builds for Go” lesson free?
Yes — the full text of “Multi-Stage Docker Builds for Go” is free to read here on the web, and the Go Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Go Academy course, upgrade to CoddyKit PRO.
What will I learn in “Multi-Stage Docker Builds for Go”?
Builder stage with scratch/alpine final image You practise Go Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Go Academy?
No prior experience is required. Go Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Multi-Stage Docker Builds for Go” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Go Academy lesson?
Yes. Every Go Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Multi-Stage Docker Builds for Go
- Environment Config and Secrets
- Docker Compose for Local Development
- Health Checks and Production Tuning