The image starts from scratch
: a special docker image that’s empty. It’s truly 0B!
A normal compiled app is dynamically linked to the libraries it needs to run (i.e., all the C libraries it binds to).
Unfortunately, scratch is empty, so there are no libraries and no loadpath for it to look in. What we have to do is modify our build script to statically compile our app with all libraries built in.
Build on your machine
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo -o main .
Alternatively you can use the -s
and -w
linker flags to strip the debugging information and reduce container size
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -a -installsuffix cgo -o main .
docker build -t go-docker-minimal .
docker run -t go-docker-minimal
Using a multi-stage build you can compile go executable and then create the minimal docker-image using the same dockerfile.
(With -f
I can pass a non default dockerfile filename)
docker build -t go-docker-minimal-multistage -f Dockerfile.multistage .
docker run -t go-docker-minimal-multistage
The docker image created is less than 2 Mb. Running docker images
you can see this:
REPOSITORY TAG IMAGE ID CREATED SIZE
go-docker-minimal latest a5ad46a94d25 5 minutes ago 1.23MB
To have more information about it read this article from codeship.com