Docker Images for C++ with and without Qt Framework v6.12.0
General
This document serves as the technical reference for Docker images used in C++ development and CI/CD pipelines, supporting both pure C++ environments (compilers, build tools, and toolchains) and Qt 6.12.0-enabled environments.
Qt 6.12.0 is a Long-Term Support (LTS) release addressing EU Cyber Resilience Act (CRA) compliance and introducing modern development features such as QML hot reload. To maximize efficiency and reusability, Docker images are structured into two distinct tiers:
- Base C++ Builder Image: A comprehensive environment containing native and cross-compilation toolchains (GCC, Clang/LLVM, MinGW, MSVC via Wine 11.0), CMake, Ninja, and supporting build utilities without Qt libraries.
- Qt-Enabled Image: A specialized image extending the base C++ environment by incorporating pre-compiled Qt 6.12.0
libraries (
lnx-x86_64,lnx-aarch64,win-x86_64,w64-x86_64) either at build time or dynamically at runtime.
Architecture and Build Pipeline Relationship
The build architecture follows a sequential lifecycle where the base C++ Docker image serves as both a standalone build container and the execution host for compiling the Qt framework itself:
- Base Image Creation: The base C++ Docker image (
builder/cpp.Dockerfile) is built first, packaging all compilers, cross-compilers, and Wine 11.0 prerequisites. - Qt Library Compilation (Sub-Process): Using the base container environment or native host setups, Qt 6.12.0 libraries are compiled from source. Source compilation steps are detailed in Qt from Source.
- Artifact Packaging & Storage: Compiled Qt libraries and toolchains are compressed (
.tar.gzor.zip) and stored in the private Nexus raw repository usingcpp-builder.shpackaging commands (qt-lnx,qt-win,qt-w64,qt-all). - Qt Docker Image Composition: Qt-enabled images are produced either statically by layering Qt archives atop the
base image (
builder/qt.Dockerfile) or dynamically at container runtime via on-demand mounting and downloading inbuilder/bin/entrypoint.sh.
Base C++ Builder Image (builder/cpp.Dockerfile)
The base builder image provides a standalone, standardized C++ development environment containing native and cross-compilation toolchains without bundling the Qt framework libraries.
Environment Specifications
- Operating System: Ubuntu 24.04 LTS (Noble Numbat) for both
x86_64(amd64) andaarch64(arm64). - Compilers & Debuggers:
- Native GCC / G++ (Ubuntu Noble defaults).
- Clang / LLVM toolchains with
clang-formatfixes. - MinGW-w64 cross-compiler (
g++-mingw-w64-x86-64,gdb-mingw-w64-target). - ARM64 cross-compiler on AMD64 (
gcc-aarch64-linux-gnu,g++-aarch64-linux-gnu,qemu-user-static).
- Windows Integration (MSVC & Wine):
- Wine 11.0 with dedicated prefix (
/opt/wine-prefix) and automated registry initialization. - Optional 32-bit Wine support (
WINE32=true, enabled by default) required for the MSVC toolchain execution.
- Wine 11.0 with dedicated prefix (
- Build Tools & Utilities:
- CMake (4.4+), Ninja-build, CTest, CPack, ccache, Doxygen, Graphviz.
- Packaging tools:
dpkg-dev,rpm,nsis. - Python 3 with virtual environment support and analysis tools (
pefile,pyelftools). - Space-efficient archive mounting tools:
ratarmount,fuse-zip,bindfs.
- Pre-packaged Toolchains:
- Supports mounting pre-built toolchain packages (
toolchain-combi,toolchain-msvc,toolchain-mingw,tool-combi) hosted on Nexus.
- Supports mounting pre-built toolchain packages (
Base Image Build Operations
To maintain independence from external Docker Hub rate limits and ensure reproducibility, base images are managed via
cpp-builder.sh:
# 1. Pull base Ubuntu image from external registry and tag for private Nexus repository
./cpp-builder.sh base-pull
# 2. Push tagged base image to local Nexus Docker registry
./cpp-builder.sh base-push
# 3. Build standalone base C++ image (without Qt libraries)
./cpp-builder.sh --qt-ver '' build
# For ARM64 platform:
./cpp-builder.sh --base-image arm64v8/ubuntu --platform arm64 --qt-ver '' build
Qt-Enabled Image Construction
Two distinct construction strategies are supported for building Docker images with Qt 6.12.0:
Construction Strategies
Strategy A: Layered Build (builder/qt.Dockerfile via build-qt)
Recommended for CI/CD pipelines and fast iterative image assembly. This method takes an existing base image and adds the pre-compiled Qt 6.12.0 libraries as an incremental layer:
- Pulls or references the existing base image (
gnu-cpp:24.04). - Downloads compressed Qt archives from the Nexus raw repository (
NEXUS_RAW_LIB_URL). - Pre-indexes archives with
ratarmount --recreate-indexfor high-performance mounting at container startup. - Labels the image with metadata
com.scanframe.qt-version="6.12.0".
Strategy B: Monolithic Build (builder/cpp.Dockerfile via build)
Constructs the full builder image from scratch in a single Dockerfile run, pulling base packages, setting up Wine, and baking in the Qt 6.12.0 libraries and toolchains.
Compression Options and Packaging Workflows
Artifact packaging commands in cpp-builder.sh support flexible compression formats via --compress <zip|tgz>
(defaults to tgz / .tar.gz):
| Command | Description | Artifact Output |
|---|---|---|
qt-lnx |
Package native Linux Qt libraries | qt-lnx-<arch>-<ver>.<ext> |
qt-win |
Package MinGW cross-compiled Qt libraries | qt-win-x86_64-<ver>.<ext> |
qt-w64 |
Package native Windows Qt libraries | qt-w64-x86_64-<ver>.<ext> |
qt-w64-tools |
Package Windows Qt host tools | qt-w64-tools.<ext> |
qt-all |
Batch generate and upload all Qt targets | All targets for --qt-ver |
win-tools / win-tools-up |
Package and upload Windows toolchain | win-x86_64-combi.<ext> |
lnx-tools / lnx-tools-up |
Package and upload Linux toolchain | lnx-<arch>-combi.<ext> |
Packaging and Uploading Examples
# Package and upload all Qt 6.12.0 libraries in one command
./cpp-builder.sh --qt-ver 6.12.0 qt-all
# Or package and upload individual targets using tar.gz (default) or zip
./cpp-builder.sh --qt-ver 6.12.0 --compress tgz qt-lnx
./cpp-builder.sh --qt-ver 6.12.0 --compress tgz qt-lnx-up
./cpp-builder.sh --qt-ver 6.12.0 --platform arm64 qt-lnx
./cpp-builder.sh --qt-ver 6.12.0 --platform arm64 qt-lnx-up
./cpp-builder.sh --qt-ver 6.12.0 qt-win
./cpp-builder.sh --qt-ver 6.12.0 qt-win-up
./cpp-builder.sh --qt-ver 6.12.0 qt-w64
./cpp-builder.sh --qt-ver 6.12.0 qt-w64-up
Runtime Mounting and Entrypoint Logic (builder/bin/entrypoint.sh)
The container entrypoint manages dynamic permission synchronization, toolchain mounting, and on-demand Qt library retrieval.
User Identity and Permission Mapping
To ensure files generated during containerized builds match host ownership without requiring root permissions:
LOCAL_USERResolution: ReadsLOCAL_USER(formatuid:gid) from the environment, or automatically resolves it by inspecting/mnt/projector the user home directory.- User Modification: Dynamically adjusts the internal
useraccount to match the hostuidandgid. - Wine Prefix & Drives: Maps
/opt/wine-prefixto${HOME}/.wineusingbindfs, mounts Wine applications from/opt/wine-appsto driveP:viafuse-zip, and maps/mnt/projectto driveN:.
Toolchain Archive Mounting
The entrypoint detects pre-packaged toolchain archives located in ${HOME} and mounts them without full disk extraction
using ratarmount:
${HOME}/tool-combi.{zip,tar.gz}$\rightarrow$ mounted read-only at${HOME}/tools.${HOME}/toolchain-*.{zip,tar.gz}$\rightarrow$ combined and mounted read-only at${HOME}/toolchain.
Qt Library Mounting and Dynamic On-Demand Downloading
The entrypoint follows a fallback hierarchy to provide Qt 6.12.0 libraries to the container environment:
-
Local Host Directory Mount:
- Checks for a volume mounted at
/usr/local/lib/qt. - If present, symlinks it directly to
${HOME}/lib/qt.
- Checks for a volume mounted at
-
On-Demand Dynamic Download via
SF_QT_VERSION:- If
/usr/local/lib/qtis not mounted and no localqt-*.{zip,tar.gz}files exist in${HOME}, settingSF_QT_VERSION=6.12.0triggers automatic downloading fromSF_QT_DOWNLOAD_BASE(defaults to Nexushttps://nexus.scanframe.com/repository/shared/library/qt). - Downloads
qt-lnx-<arch>-6.12.0.tar.gzfor native compilation. - On
x86_64hosts, automatically fetches cross-compilation packages:qt-win-x86_64,qt-lnx-aarch64, andqt-w64-x86_64.
- If
-
High-Performance FUSE Mounting:
- Discovered or downloaded
qt-*.{zip,tar.gz}archives are mounted to${HOME}/lib/qt/<target>viaratarmount. - For
lnx-aarch64onx86_64hosts, a--write-overlayis applied to permit symlinking the hostlibexecdirectory for cross-compilation tools.
- Discovered or downloaded
# Example running base container with dynamic on-demand Qt 6.12.0 download:
docker run -it --rm \
--privileged \
-e LOCAL_USER="$(id -u):$(id -g)" \
-e SF_QT_VERSION="6.12.0" \
-v "$(pwd):/mnt/project" \
nexus.scanframe.com/amd64/gnu-cpp:24.04 bash
Deployment and Registry Distribution
Once built, images can be pushed to internal Nexus registries or Docker Hub:
Private Nexus Docker Registry
To store images in the internal Nexus Docker repository:
# Push Qt 6.12.0 image to Nexus
./cpp-builder.sh --qt-ver 6.12.0 push
# Pull Qt 6.12.0 image from Nexus
./cpp-builder.sh --qt-ver 6.12.0 pull
Docker Hub
To publish images to Docker Hub:
# Push with version tag (e.g., 24.04-6.12.0)
./cpp-builder.sh --qt-ver 6.12.0 docker-push
# Tag and push as 'latest'
./cpp-builder.sh --qt-ver 6.12.0 docker-latest
Image Tagging Convention
The tagging schema distinguishes between base images and Qt-versioned images:
- Format:
<architecture>/gnu-cpp:<base-ver>[-<qt-ver>][-<revision>] - Architecture:
amd64(x86_64) orarm64(aarch64). - Base Version: Ubuntu release version (e.g.,
24.04). - Qt Version: Bundled Qt version (e.g.,
6.12.0), omitted for standalone base builder images. - Revision: Optional incrementing revision (e.g.,
-1).
Examples:
amd64/gnu-cpp:24.04: Standalone base C++ builder image for x86_64.amd64/gnu-cpp:24.04-6.12.0: Qt 6.12.0-enabled builder image for x86_64.arm64/gnu-cpp:24.04-6.12.0-1: Qt 6.12.0-enabled builder image for ARM64, revision 1.
Container Operations and Troubleshooting
cpp-builder.sh provides operational commands for running, debugging, and inspecting containers:
Execution and GUI Forwarding
# Run foreground container mounting current project
./cpp-builder.sh --project /path/to/project run
# Run with X11 forwarding for Qt GUI application execution and testing
./cpp-builder.sh --project /path/to/project runx
# Start background daemon with SSH service on port 3022
./cpp-builder.sh start
./cpp-builder.sh startx
# Manage running background container
./cpp-builder.sh status
./cpp-builder.sh attach
./cpp-builder.sh stop
./cpp-builder.sh kill
Toolchain Version Auditing
Verify compiler and tool versions across image iterations:
| Application | Qt 6.10.1 Image | Qt 6.12.0 Image | Purpose |
|---|---|---|---|
| Ubuntu Base | 24.04 LTS | 24.04 LTS | Operating System |
| CMake | 4.3.0 | 4.4.4 | Build Configuration |
| Git | 2.53.0 | 2.55.0 | Version Control |
| Wine | 11.0 | 11.0 | MSVC Windows Toolchain Execution |
| Ratarmount | Enabled | Enabled | FUSE Compressed Archive Mounting |
CI/CD Pipeline Integration
The Docker images serve as build executors for GitLab CI/CD pipelines managed via gitlab-runner.sh:
# Register runner using the docker executor
./gitlab-runner.sh --token <registration-token> register
# Start runner in background
./gitlab-runner.sh start
Repositories & Registries
- Git Repository: docker-runner Repository
- Docker Hub (AMD64): avolphen/amd64-gnu-cpp
- Docker Hub (ARM64): avolphen/arm64-gnu-cpp
- Nexus Private Registry: Nexus Docker Tags