Post

Single-binary Docker images

Go applications are very self-contained. So self-contained, in fact, that they can act as their own Docker container!

1
2
3
4
5
6
7
8
9
10
FROM --platform=$BUILDPLATFORM golang:1 AS build
ARG TARGETOS TARGETARCH
WORKDIR /work
COPY . .
RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o app .

FROM scratch
COPY --from=build /work/app /app
EXPOSE 8080
ENTRYPOINT ["/app"]

The example above also works with docker buildx and uses Go’s native cross-compilation to produce binaries for other architectures. So, to produce an amd64 container on an arm64 Mac, for example, run docker buildx --platform=linux/amd64 .

One important note: you may receive a certificate signed by unknown authority error when your application reaches out to a remote host. This is because the image contains nothing besides the Go application, not even x509 root certificates, which are normally found on the local file system.

Fortunately, there is a solution for this. Import the official golang.org/x/crypto/x509roots/fallback package somewhere in your application and the root certificates will be embedded in the application itself.

1
2
3
4
5
package main

import (
    _ "golang.org/x/crypto/x509roots/fallback"
)