Skip to content

Latest commit

 

History

History
42 lines (28 loc) · 2.53 KB

Readme.md

File metadata and controls

42 lines (28 loc) · 2.53 KB

A Docker container with nothing but a statically linked C++ executable

An experiment by Richard Eigenmann

Inspired by a talk from Miroszlav Magyarevity at the 17th Docker Switzerland Meetup hosted by Oracle in the Prime Tower in Zürich on 30 May 2018.

Try it

cd <yourWorkDirectory>
git clone git@github.com:richardeigenmann/staticDocker.git
cd staticDocker
docker build --rm=false -t richardeigenmann/hello .
docker run richardeigenmann/hello

How big is it?

# query the built image:
docker images richardeigenmann/hello
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
richardeigenmann/hello   latest              1ee25d730753        28 minutes ago      17MB
richardeigenmann/hello   latest              c6a00ffe0973        23 minutes ago      5.27MB

The first result was from statically linking <iostream> and calling std::cout on a "Hello World" string. 17MB does seem rather a lot but a Google search reveals that this drags a lot of code in. If we switch to <cstdio> and use printf instead, size drops to 5MB. This actually corresponds to the size of the executable as evidenced by the ls -lh command I planted in the compile step.

Explanation

Setting up a development environment for C++ involves intalling a lot of tools and libraries which can lead to problems. A great feature of containers is that you can push this set-up into a container and use different containers for different requirements.

In this project (see the Dockerfile) I have chosen to build a heavyweight 829MB compiling container out of OpenSuse's Tumbleweed distro. This drags in the latest clang and gcc compilers and a number of utilities. If required I would also install libraries here.

The build step then proceeds to copy the CMakeLists.txt and main.cpp files into the compiling conatiner and uses cmake to compile and link the executable.

Using the multi-stage build feature the Dockerfile then specifies that a new container is to be build based on the SCRATCH image which literally is just an empty container. The COPY --from=0 /src/build/hello . statement then copies the executable into the new container and the ENTRYPOINT instruction ensures that it will be called when the container is run.

The TARGET_LINK_LIBRARIES( hello -static ) entry in the CMakeLists.txt (or more specifically the -static keyword) instructs the linker to create a statically linked executable (meaning that there are no external dependencies and the binary has everythzing is needs built in).