06/29/2020 docker compilation upx ldflags
Docker is supported by many OS — Linux, Unix, Windows, MacOS. Docker containers are also supported by many popular hosting platforms — Microsoft Azure, Amazon, Digital Ocean.
Docker image building is provided by docker build
command, the Dockerfile
is also required to provide building instructions.
Let's take a look to the following Dockerfile:
FROM rhaps1071/golang-1.14-alpine-git AS build WORKDIR /build COPY . . RUN CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -ldflags "-s -w -extldflags '-static'" -o ./app RUN apk add upx RUN upx ./app FROM scratch COPY --from=build /build/app /app ENTRYPOINT ["/app"]
Because we are using GO module, we don't need to put the source code to particular folder
or download the dependencies manually —
it is done by go build
command itself.
Let's now discuss all features of Dockerfile below.
A docker image size is important, because this image is going to be uploaded / downloaded during the build / deploy. The more size of image is the more time you will spend on network transmittion.
On the first stage ("build") in the Dockerfile
i start building from —
rhaps1071/golang-1.14-alpine-git
image which is golang:1.14-alpine with git
installed.
Alpine is the tiniest linux image we currently have. It is image size is about 3MB.
On the second stage i use scratch
just to put binary file there.
scratch
— out of box docker image with zero size.
That means, the resulting image size equals to binary size.
We can change binary size by using two approaches:
Flags -s -w
are to remove debug information from binary.
In my case the size was changed from 15MB to 11MB because of flags.
-extldflags '-static'
is used to statically link binary
even with CGO enabled. Dynamic linking makes our binary require
external libraries (.so files in Linux).
External libraries dependencies can be reviewed by using ldd
command against binary file.
In scratch
, alpine
we don't have these libraries installed.
In this case we have to use static linking — all libraries will be complied in
our program binary.
I also used upx
tool to compress binary. The size was changed from 11MB to 4.1MB.
Source of this example can be found in Github repository.