✦ For everyone, free.

Practical knowledge for real and everyday life

Home

12.2.4.1 Go Static Binary

A focused guide to Go Static Binary, connecting core concepts with practical Docker and container operations.

A Go static binary is the single, self-contained executable produced by Go's build process when compiled with CGo disabled, requiring no external dynamic libraries at runtime, which is exactly what makes running it in an extremely minimal final container image (including the empty scratch base) actually possible.

Building a True Static Binary

Disabling CGo during the build ensures the compiler doesn't link against the C standard library dynamically.

CGO_ENABLED=0 go build -o server .
file server
server: ELF 64-bit LSB executable, statically linked

Confirming the binary is reported as statically linked validates that this build genuinely produced a self-contained executable.

Why Some Go Programs Require CGo, Complicating True Static Linking

A Go program depending on a package that itself relies on CGo (certain database drivers or system-level libraries, for instance) can't be fully statically linked without addressing that specific dependency.

go build -o server .
ldd server
linux-vdso.so.1
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6

A binary like this, despite being a Go program, still has dynamic dependencies, meaning it requires a base image actually providing those specific libraries, ruling out an empty scratch base.

Using a Minimal but Non-Empty Base for CGo-Dependent Binaries

For a binary that does need CGo, a minimal Alpine-based final image, rather than scratch, provides the small set of needed libraries while still keeping the image quite small.

FROM alpine:3.19
RUN apk add --no-cache ca-certificates
COPY --from=build /app/server /server
ENTRYPOINT ["/server"]
Including CA Certificates for Outbound HTTPS Connections

A statically linked binary in a scratch image needs CA certificates explicitly copied in if it makes any outbound HTTPS connections, since scratch itself provides none.

COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
Why Go Static Binary Matters

Understanding exactly what makes a Go binary truly statically linked — and the specific circumstances (CGo dependencies, HTTPS certificate needs) that complicate this — is essential for correctly building toward the extremely minimal final images Go's compilation model otherwise makes possible.