Use Docker multi-stage builds to reduce final docker image size#179
Use Docker multi-stage builds to reduce final docker image size#179
Conversation
Makefile
Outdated
| $(NAME): .build/deps.ok .build/vendor.ok bindata_assetfs.go $(SOURCES) | ||
| go build -ldflags "-X main.version=$(VERSION)" | ||
|
|
||
| $(NAME)-static: .build/deps.ok .build/vendor.ok bindata_assetfs.go $(SOURCES) |
There was a problem hiding this comment.
What's this change? Should it be in a separate commit?
There was a problem hiding this comment.
We're no longer keeping resulting binary in the image it was build, so we need a more static build.
But it's likely that CGO_ENABLED=0 is only needed really, @terinjokes ?
There was a problem hiding this comment.
CGO_ENABLED=0 will give you a statically-compiled Go binary, the 'extldflags' shouldn't be necessary.
What's the reason for adding a new Makefile target rather than modifying the existing build target(s)?
| rm -fr /go/src && \ | ||
| apk del .build-dependencies | ||
|
|
||
| FROM gcr.io/distroless/base |
There was a problem hiding this comment.
What's the advantage of this over using the 'scratch' image and adding ca-certificates as necessary e.g. https://blog.codeship.com/building-minimal-docker-containers-for-go-applications/? It would be good to explain the rationale in your commit message.
There was a problem hiding this comment.
gcr.io/distroless/base already is a minimal docker image with ca certs included
why maintain our own?
There was a problem hiding this comment.
What else does it pull in? Can we include that rationale in the commit message so that future contributors understand why we chose distroless?
There was a problem hiding this comment.
I already updated commit message, ca-cert is all we should need
see https://github.com/GoogleCloudPlatform/distroless
There was a problem hiding this comment.
I was struggling to find info as to what the distroless base image contains, but this covers it:
We don't need glibc or libssl if the binary is statically compiled.
The code to use scratch would look roughly like:
# Build stage
FROM golang:1.8 as build
WORKDIR /go/src/github.com/foo/bar
RUN apt-get update
RUN apt-get upgrade -y ca-certificates
RUN apt-get install -y git make
COPY . /go/src/github.com/foo/bar
RUN make # or similar
# Main stage
FROM scratch
COPY --from=build /etc/ssl/certs /etc/ssl/certs
COPY --from=build /go/bin/example /
ENTRYPOINT ["/example"]
...which gives you an image containing only the statically-compiled binary and the CA certificates copied from Debian.
I'm not suggesting you change it, I think using distroless is fine.
terinjokes
left a comment
There was a problem hiding this comment.
I'm not going to block for the extldflags, but if they're not needed, probably reasonable to remove.
For second stage use https://github.com/GoogleCloudPlatform/distroless which provides a minimal image with CA certificates. Binary is compiled with CGO_ENABLED=0 to prevent dynamical linking to any libraries.
No description provided.