C, docker, programming

C build environment in a docker container

This container is my base build environment for compiling C programs. It produces colored output and it caches compilation artifacts so that subsequent re-compilations are greately accelerated.

It is layered on top of my minidebian container, and I usually expand it further depending on the project. See this example.


  • GCC 6
  • ccache for fast recompilation
  • colorgcc for colored output
  • Support for cross-compiling with external toolchain
  • Very small: 240 MB including the base ownyourbits/minidebian ( ~50 MB )

CCache is a compiler cache that greatly improves recompilation times. I sometimes spend hours and hours waiting for builds to complete, so this is a must in my toolbox.

colorGCC is also a nice addition. It helps to make sense out of compilation output, and it’s really nice to catch warnings in long builds ( “eh! what was that colored output?” ).

Did I mention that I love color already?

Initially, I created this container because I was tired of setting up my C environment with ccache and colorgcc over and over again.

I used to have to go to the Arch wiki every single time, in order to remember the exact setup and the location of the symlinks needed for this rather hacky setup to work. Now I have it scripted and packaged… much better!



It is recommended to use this alias

Then, use it just as you would use make

You can pass Makefile targets and variables the usual way

A .ccache directory will be generated in the directory of execution to speed up subsequent compilations.

Note that the container only includes the generic libraries, so if you need to use some external libraries for your project, you will need to extend the container.

For instance, if you need to link against the ncurses library it will naturally fail

You need to install it first. Just create another layer on top of mmake


This method supports specifying an external toolchain, such as this ARM cross-compiler toolchain.

In order to cross-compile to a different architecture, you can use the following alias

Then again, use it just as you would use make

If we now inspect the file, we can see that we are crosscompiling the same C code, in the same folder just by invoking xmake instead of mmake. Nice!

We now have a MIPS version of main.

The output will still be colored, but if you want to use ccache, you have to include it in the toolchain it and set it up for your particular case.

Check out this collection of ready to use toolchains from free-electrons.

Advanced usage

In order to avoid the delay in the creation and deletion of the container, you can leave the container running for faster execution.

Use these aliases

I do this whenever I am developing a single project and I am in the stage of frequent recompiling and curating the code.


Even though initially I was using this as a simple make wrapper, I have found many uses for it:

  • Having a stable build environment is very important in order to achieve reproducible builds that do not depend on what system each member of the development team runs. It is common that Arch is ahead of Debian in gcc version, for example.
  • Pulling the image from docker makes it really easy to share the development environment with your team.
  • It is ideal to be linked it to a continuos integration system that supports docker, such as Gitlab CI.
  • You can docker run --entrypoint bash into the container and work inside the development environment, in the fashion of good old chroot build environments.
  • It is a nice base for creating derivative containers taylored to different projects, reusing a common base and saving disk space. For instance, you might want to build a container with a bunch of libraries plus CUnit for one project, and Doxygen for another.

As usual, you can find the build code on Github.


Author: nachoparker

Humbly sharing things that I find useful [ github dockerhub ]

Leave a Reply

Your email address will not be published. Required fields are marked *