Reproducible, portable build environments for the cmake_template.
Docker images encapsulate the exact toolchain versions (CMake 3.31+, GCC/Clang, Ninja, Doxygen) needed to build, test, and package this project consistently across Linux distributions, CI runners, and developer machines. The goal is build-once, run-anywhere — no "works on my machine" due to distro-specific package versions.
| Image | Base | Use Case | Size (approx.) |
|---|---|---|---|
fedora |
fedora:latest |
Primary CI / development image; most stable toolchain | ~500 MB |
manjaro |
manjarolinux/base:latest |
Rolling-release validation; bleeding-edge compiler versions | ~450 MB |
Note: These images target Linux native builds (
gcc,clang,llvm-mingw-x86_64cross). Android NDK cross-compilation uses the host's NDK installation or a dedicated Android builder image (see Presets). macOS/iOS builds require macOS hosts and are not containerized.
# Fedora (recommended for CI parity)
docker build -t cmake-template:fedora -f docker/fedora.Dockerfile .
# Manjaro (rolling release validation)
docker build -t cmake-template:manjaro -f docker/manjaro.Dockerfile .The default ENTRYPOINT runs the complete CI pipeline:
docker run --rm -v "$(pwd):/app" cmake-template:fedoraThis executes cmake --workflow --preset=gcc-full inside the container, producing build artifacts, test results, and CPack packages in your local build/ and dist/ directories.
docker run --rm -it -v "$(pwd):/app" cmake-template:fedora bash
# Inside container:
cmake --preset=clang
cmake --build --preset=clang-release
ctest --preset=clang-releaseThe Fedora image includes llvm-mingw dependencies. Mount your llvm-mingw toolchain or install it in the container:
docker run --rm -it -v "$(pwd):/app" -v "/path/to/llvm-mingw:/opt/llvm-mingw" cmake-template:fedora bash
export PATH="/opt/llvm-mingw/bin:$PATH"
cmake --workflow --preset=llvm-mingw-x86_64-fullBoth Dockerfiles use a single build stage strategy for simplicity. The images are not minimal runtime containers — they are full development environments. A future runtime stage stripping build-only dependencies (compiler headers, static analysis tools) is tracked as an enhancement.
Key design decisions:
- BuildKit cache mounts (
--mount=type=cache) keep package manager caches (dnf/pacman) between builds, dramatically speeding up local iteration. - Single
RUNlayer for system deps minimizes image layers and reduces final size. COPY . .comes after dependency installation maximizes layer cache hits when only source code changes.ENTRYPOINTdefaults togcc-fullworkflow makesdocker runa one-command CI equivalent.
Layer 1: Base image (fedora:latest / manjarolinux/base:latest)
Layer 2: System dependencies (cached across source changes)
Layer 3: Source code copy (invalidated on any source change)
Layer 4: Preset validation (fail-fast if CMakePresets.json is broken)
Layer 5: Entrypoint (workflow execution)
For CI and reproducibility, tag images explicitly:
# Date-stamped tag for CI cache keys
docker build -t cmake-template:fedora-$(date +%Y%m%d) -f docker/fedora.Dockerfile .
# Toolchain-pinned tag
docker build -t cmake-template:fedora-gcc14 -f docker/fedora.Dockerfile .jobs:
docker-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build and run in Docker
run: |
docker build -t cmake-template -f docker/fedora.Dockerfile .
docker run --rm -v "$(pwd):/app" cmake-template
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: packages
path: build/**/packages/*.docker-build:
image: docker:latest
services:
- docker:dind
script:
- docker build -t $CI_PROJECT_NAME -f docker/fedora.Dockerfile .
- docker run --rm -v "$CI_PROJECT_DIR:/app" $CI_PROJECT_NAME
artifacts:
paths:
- build/**/packages/| Symptom | Cause | Resolution |
|---|---|---|
cmake: command not found |
Base image drifted, package missing | Rebuild with --no-cache |
| Slow rebuilds | Package cache not mounted | Ensure BuildKit is enabled (DOCKER_BUILDKIT=1) |
Permission errors on build/ |
Container user ≠ host user | Run with --user $(id -u):$(id -g) or fix ownership post-build |
| NDK not found in Android preset | NDK not mounted inside container | Android cross-compilation requires host NDK or separate Android builder image |
llvm-mingw preset fails |
Cross-compiler not in container PATH | Mount toolchain volume or extend Dockerfile to install it |
To add a new base distribution (e.g., Ubuntu LTS, Alpine, Arch):
- Copy
docker/fedora.Dockerfileas a template. - Replace
dnfcommands with the target package manager (apt,apk,pacman). - Ensure these packages are present:
cmake >= 3.31,ninja,gcc/g++orclang/clang++,git,doxygen. - Add optional:
llvm-mingwpackages or mount for Windows cross-compilation. - Update this document and the Presets guide.
- Architecture — project structure and build system design
- Presets, Platforms & Cross-Compilation — all available configure/build/test/package presets
- Contributing — guidelines for modifying Dockerfiles
- Docker BuildKit docs — cache mounts, multi-platform builds