I can't remember where I saw it, I thought it was on Datadog or on NewRelic or maybe CloudFlare? but I remember someone mentioning that with Golang, they run release binaries in production (of course), and within their Docker containers, they also include a separate file containing debug symbols in case a crash occurs so as to be able to see what happened.
I'm building and running in Docker with a Dockerfile like this:
# do all of our docker building in one image
FROM golang:latest as build
WORKDIR /usr/src/api
COPY go.mod go.sum ./
RUN go mod download
COPY . .
# build the application with relevant flags to make it completely self-contained for a scratch container
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags "-s" -a -installsuffix cgo -o app
# and then copy the built binary to an empty image
FROM ubuntu:latest
COPY --from=build /usr/src/api/app /
COPY --from=build /usr/src/api/config.defaults.json /config.json
COPY --from=build /usr/src/api/logo.png /
# default to running in a dev environment
ENV ENV=dev
EXPOSE 8080
ENTRYPOINT ["/bin/bash"]
If I don't use the flags above, the binary will fail to execute in alpine
and scratch
base images:
standard_init_linux.go:219: exec user process caused: no such file or directory
Running this in ubuntu:latest
just works, so the above compile flags seem to fix the issue for alpine
and scratch
.
With this environment in mind, is it possible to have go build
emit debug symbols into a separate file to live alongside my static binary in the Docker image?
Use go tool compile
using -E
flag to Debug symbol export
. Is that what you need?
$ go tool compile -E *.go
Type:
go tool compile
for more help regarding how to use it and what are the options available.
Reference:
You don't need to use " -a -installsuffix cgo" flags when building with CGO_ENABLED=0 -- just setting the environment variable will do the trick.
You are building with "-ldflags -s", which is going to strip out all debug symbols and ELF symbol table information. Instead of doing that, do a regular build, archive that executable (in case you need the symbols later) and then remove symbols using strip. Eg
$ CGO_ENABLED=0 GOOS=linux go build -o app.withsymbols
$ cp app.withsymbols /my/archive/for/debugging/production/issues
$ strip app.withsymbols -o app.stripped
$ cp app.stripped /production/bin
That should give you the behavior you're asking for (eg a small production binary, but also a backup binary with symbols for debugging problems in production).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.