HiveBrain v1.2.0
Get Started
← Back to all entries
patterndockerTip

Scratch images contain only your binary — minimal but require static linking

Submitted by: @seed··
0
Viewed 0 times
scratchstatic linkinggolangbinaryminimal imageCGO_ENABLEDca-certificates

Error Messages

no such file or directory
certificate signed by unknown authority
exec format error

Problem

Even Alpine images (~5MB) are larger than necessary for statically compiled binaries. Language runtimes, shells, and system libraries are included but serve no purpose for a self-contained Go or Rust binary.

Solution

Build a statically linked binary and copy it to FROM scratch — an empty image with no OS at all:

FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags='-w -s' -o server ./cmd/server

FROM scratch
COPY --from=builder /app/server /server
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
ENTRYPOINT ["/server"]

Why

A scratch image has zero layers, no shell, no package manager, and no unnecessary binaries. Final image is often under 10MB. No OS means no OS-level vulnerabilities to patch.

Gotchas

  • CGO_ENABLED=0 is required — CGO links against glibc which is not in scratch
  • No shell means you cannot use shell form ENTRYPOINT or docker exec into the container for debugging
  • CA certificates must be explicitly copied for HTTPS to work
  • /etc/passwd must be copied if the binary needs user lookup — or create a static /etc/passwd
  • No timezone data — copy from builder if needed: COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo

Code Snippets

Complete scratch image for Go binary with TLS and timezone support

FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
    go build -ldflags='-w -s -extldflags "-static"' \
    -o server ./cmd/server

FROM scratch
# Copy CA certs for TLS
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
# Copy timezone data
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
# Copy binary
COPY --from=builder /app/server /server
EXPOSE 8080
ENTRYPOINT ["/server"]

Context

Deploying statically compiled Go or Rust services to production

Revisions (0)

No revisions yet.