CodeBlanks Logo Icon CodeBlanks

Multi-stage build

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

main.go
package main

import "fmt"

func main() {
    // buraya yaz
}

Sample solution

main.go
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

Question
FROM golang:1.23 ____ builder
Answer
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

All lessons in Advanced