Around Go: containers · 3 MIN READ

Build a small Go image with explicit runtime needs

Separate the build stage from the runtime image and identify what a minimal image leaves out.

A container image packages a native application and its runtime files. It does not compile Go inside the iOS app, and it does not remove the need to maintain the operating environment. Multi-stage builds let the final image omit the compiler and source tree.

01

Read the two stages

The builder resolves dependencies and compiles a Linux binary. The final stage copies only the program. This example assumes go.mod and go.sum exist and the program lives in cmd/api.

dockerfile
# syntax=docker/dockerfile:1
FROM golang:1.27 AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /out/api ./cmd/api

FROM scratch
COPY --from=build /out/api /api
USER 65532:65532
EXPOSE 8080
ENTRYPOINT ["/api"]
Read the code

This scratch example fits a compatible pure-Go binary with no required external files. It omits CA certificates, zoneinfo, a shell and writable application directories. Add the actual runtime assets or choose an appropriate maintained runtime base. Pin and update base image digests in a reproducible release process.

02

Build the final image and inspect its metadata

Keep logs, local builds and secrets out of the build context with .dockerignore. Copy module files before source to reuse dependency work. The actual final image still needs a startup test; metadata inspection alone cannot prove its runtime files are sufficient.

bash
docker build -t go-api:dev .
docker image inspect go-api:dev --format '{{.Config.User}} {{json .Config.Entrypoint}}'
docker image ls go-api
Read the code

For this Dockerfile the user should be 65532:65532 and the entrypoint /api. Verify the build succeeds before inspecting the tag, or you might inspect an older image. A CGO-dependent program needs a compatible build/runtime strategy.

03

Run the artifact you intend to release

A non-root user reduces ordinary process privileges, but does not replace resource and filesystem limits. Test startup, configuration, TLS requirements and graceful termination using the actual final image. A compiler-stage unit test alone cannot prove the minimal runtime image contains the files the service needs.

TAKE THIS WITH YOU

Build with the toolchain, run with the required runtime files, and verify the final image. A smaller image must still satisfy the program's contract.

Check your understanding

Which statement is correct about a multi-stage image build?

Go to the source

Progress stays in this browser. No account needed.