I was building a Docker image using scratch
as base.
The following build command:
RUN go build -o /go/bin/myapp
created a binary that kept failing when executed:
standard_init_linux.go:211: exec user process caused "no such file or directory"
By trial and error I found out that I needed to build as follows:
RUN CGO_ENABLED=0 go build -o /go/bin/myapp -a -ldflags '-extldflags "-static"' .
Why are both CGO_ENABLED=0
and -ldflags '-extldflags "-static"'
necessary?
Don't both options create static binaries? (i.e. binaries that will need absolutely nothing in terms of libraries from the environments they will run on?)
Just before we start, a heads up by Russ Cox's: Comment
Read this as well: Comment
Yes, I agree with Volker's comment that some systems don't really allow static binaries.
Read on: Compile packages and dependencies
-a
force rebuilding of packages that are already up-to-date.
-ldflags '[pattern=]arg list'
arguments to pass on each go tool link invocation.
Read: go tool link
-extldflags flags
Set space-separated flags to pass to the external linker.
Hence, it tries to rebuild all the packages (dependencies as well) with CGO disabled and also -static
means do not link against shared libraries.
Some of the points related to static linking are explained well: Linking golang statically