Docker Community Forums

Share and learn in the Docker community.

Determine the parent image


(Dbdevops) #1

Hi there,

I build a custom c/c++ application that link against various system and custom libraries.
Now I want to put it all in a container.
So the next step is to write the docker file.
But what “parent image” to choose ?

If it was a java app I’d use “FROM java:8” … if it was a python script “From python:3.5” … and so on.

As the whole build is done on an Ubuntu machine, do I need to use “FROM ubuntu” … or “FROM scratch” ?

(Fkram) #2

New docker user here who just registered - because I have pretty much the same question. So apologies for the thread hijack - I’ll start a new thread if you want.

My best research so far has led me to this previous thread…

I’ve found a few other snippits with my googling over the last day or so.

So the way I’m understanding it (and have succeeded with a basic c ‘hello world’ app) is there are two ways.

Using FROM scratch - compile the C program entirely statically (use -static and ldd on the exe says ‘not a dynamic executable’ - probably will require glibc-static in your c build environment). Then docker build and run the container.

If not compiling statically then use your base linux image FROM , Depending on dependencies you may need to yum / apt additional libs / dependencies.

I’m struggling right now to get my head round what is the ‘best practice’ way from the above methods? Statically building a big old C/C++ exe is usually frowned upon in C developer circles. But container size at least for a simple app seems a lot leaner than one from a Linux base image.

Anyone more with experience suggest the best practice or another?


(David Maze) #3

Whichever path you go, try to avoid having a full C toolchain in your runtime image. (If you RUN apt-get install build-essential, you’ve lost.)

The pitfalls of building a static binary are at least well-understood. A FROM scratch image with a static binary is reasonably well-established for Go programs. On the flip side, there’s also an established tool for bundling binary data into a Go program and libraries have much less of an expectation of finding a file in /etc or /usr/share.

I think if I was doing it today and had a guarantee that my build system had sufficiently modern tools, I’d use a two-stage Dockerfile, both parts FROM ubuntu:16.04, where the first half built the application and the second half added a minimal set of libraries and the installation.

If that path makes sense to you, and the static-binary path seems technically feasible too, then you’ll make a reasonable decision. I don’t think either way is “wrong”, and using a base Linux distro in the grand scheme of things doesn’t make images that much bigger.

(Fkram) #4

Sorry for the delay in replying. Thank you. Very helpful.