Image size
Minimize your image size not only enhance your develop speed, but also help for better scaling speed in container cluster (e.g. AWS ECS, Kubernetes)
Docker provide a feature called multi-stage build.
Your final image can based on a previous image to reduce the image layers, copying the artifact you really need.
This significantly help us to reduce the image size.
Here’s an example for Docker doc, compare these two Dockerfile.
Fat
Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14
FROM golang:1.21 WORKDIR /src COPY <<EOF ./main.go package main import "fmt" func main() { fmt.Println("hello, world") } EOF RUN go build -o /bin/hello ./main.go CMD ["/bin/hello"]
Image size total 841 MB
IMAGE CREATED CREATED BY SIZE COMMENT de04cbb694be 10 minutes ago CMD ["/bin/hello"] 0B buildkit.dockerfile.v0 <missing> 10 minutes ago RUN /bin/sh -c go build -o /bin/hello ./main… 27MB buildkit.dockerfile.v0 <missing> 10 minutes ago COPY <<EOF ./main.go # buildkit 78B buildkit.dockerfile.v0 <missing> 10 minutes ago WORKDIR /src 0B buildkit.dockerfile.v0 <missing> 41 hours ago WORKDIR /go 0B buildkit.dockerfile.v0 <missing> 41 hours ago RUN /bin/sh -c mkdir -p "$GOPATH/src" "$GOPA… 0B buildkit.dockerfile.v0 <missing> 41 hours ago COPY /target/ / # buildkit 214MB buildkit.dockerfile.v0 <missing> 41 hours ago ENV PATH=/go/bin:/usr/local/go/bin:/usr/loca… 0B buildkit.dockerfile.v0 <missing> 41 hours ago ENV GOPATH=/go 0B buildkit.dockerfile.v0 <missing> 41 hours ago ENV GOTOOLCHAIN=local 0B buildkit.dockerfile.v0 <missing> 41 hours ago ENV GOLANG_VERSION=1.21.11 0B buildkit.dockerfile.v0 <missing> 41 hours ago RUN /bin/sh -c set -eux; apt-get update; a… 258MB buildkit.dockerfile.v0 <missing> 2 days ago /bin/sh -c set -eux; apt-get update; apt-g… 177MB <missing> 2 days ago /bin/sh -c set -eux; apt-get update; apt-g… 48.4MB <missing> 2 days ago /bin/sh -c #(nop) CMD ["bash"] 0B <missing> 2 days ago /bin/sh -c #(nop) ADD file:b532f8e401e9a1fcc… 117MB
Thin
Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
FROM golang:1.21 as builder WORKDIR /src COPY <<EOF ./main.go package main import "fmt" func main() { fmt.Println("hello, world") } EOF RUN go build -o /bin/hello ./main.go FROM scratch COPY --from=builder /bin/hello /bin/hello CMD ["/bin/hello"]
Image size - Only 1.8 MB
IMAGE CREATED CREATED BY SIZE COMMENT ee1389c8966e 8 minutes ago CMD ["/bin/hello"] 0B buildkit.dockerfile.v0 <missing> 8 minutes ago COPY /bin/hello /bin/hello # buildkit 1.8MB buildkit.dockerfile.v0
Compare this two cases image size, that’s why it is important leverage multi-stage build to minimize your image size.