Multi-stage build
- Go course
- Advanced
- Lesson 48/68
- 4 min
Learn to produce small images with multi-stage build.
Multi-stage build
In a multi-stage build each FROM starts a new stage. The build stage can be large; the final stage takes only what is needed:
FROM golang:1.23 AS builder
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o /out/app .
FROM alpine:3.20
COPY --from=builder /out/app /usr/local/bin/app
CMD ["app"]The image shrinks from ~800 MB to ~15 MB.
Use the cache wisely
Downloading dependencies in a separate layer speeds up repeated builds:
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o /out/app .With BuildKit, RUN --mount=type=cache,target=/root/.cache/go-build also keeps the build cache.
Practice Version information
Declare var version = "dev", to be set at build time with -ldflags "-X main.version=1.2.0", and print fmt.Println("sürüm:", version). (Without the flag it shows dev.)
Starter code
package main
import "fmt"
func main() {
// buraya yaz
}Sample solution
package main
import "fmt"
var version = "dev"
func main() {
fmt.Println("sürüm:", version)
}Expected output
sürüm: dev
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Why does <code>CGO_ENABLED=0</code> matter here?
- It disables the GC
- The binary doesn't link to libc and runs on any base Correct answer
- Compilation gets faster
- It disables tests
Explanation: With cgo on, the binary can link to the system C library; on alpine or scratch bases that library may differ or be missing.
2 Name the stage
FROM golang:1.23 ____ builder
FROM golang:1.23 AS builder
Explanation: AS names the stage; later COPY --from=builder refers to it.
3 Stages
| Term | Meaning |
|---|---|
builder |
Builds |
final |
Only the binary |
COPY --from |
Copy between stages |
go mod download |
Cached layer |