Dockerfile by Example: Go Application Image
Go applications can be compiled into static binaries, allowing the use of the scratch image. This sample code demonstrates the ultimate minimal image.
Code
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
# Disable CGO for static binary
RUN CGO_ENABLED=0 go build -o myapp main.go
# Start from scratch (empty image)
FROM scratch
# Copy CA certificates for HTTPS support
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
# Copy the binary
COPY --from=builder /app/myapp /myapp
CMD ["/myapp"]Explanation
Go is unique in its ability to easily produce statically linked binaries that have no external runtime dependencies. This allows the use of the scratch image, which is a special, empty Docker image. Using scratch results in the smallest possible container size (often just a few megabytes) and an incredibly small attack surface, as there is no OS, shell, or package manager to exploit.
Considerations for scratch images:
- Must use
CGO_ENABLED=0to ensure static linking - Must manually copy CA certificates if making HTTPS requests
- Must copy user/group files if running as non-root
- Debugging is difficult as there is no shell access
Because scratch is empty, it lacks the root CA certificates required to verify SSL/TLS connections. If your Go application makes HTTPS requests, you must explicitly copy the ca-certificates.crt file from the builder stage (or another image) into the scratch image. Similarly, if you need to run as a specific user, you would need to copy /etc/passwd from a base image.
Code Breakdown
CGO_ENABLED=0 forces static linking of libraries.FROM scratch starts with a completely empty image.COPY ... ca-certificates.crt adds SSL support to the empty image.COPY --from=builder brings in the compiled binary.
