Docker und C++: Containerisierung von Anwendungen auf fortgeschrittenem Niveau

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Docker und C++: Containerisierung von Anwendungen: fortgeschrittenes Niveau

\n\n

Die Containerisierung von C++-Anwendungen mit Docker ist mehr als nur das Verschieben einer Binärdatei in eine isolierte Umgebung. Auf fortgeschrittenem Niveau müssen Besonderheiten der Kompilierung, der Abhängigkeitsverwaltung, der Optimierung der Image-Größe und des Debuggings berücksichtigt werden. In diesem Artikel behandeln wir die besten Praktiken zur Erstellung effizienter Docker-Images für C++-Projekte unter Verwendung von Multi-Stage-Builds, statischem und dynamischem Linken sowie modernen Tools wie CMake und vcpkg.

\n\n

1. Multi-Stage-Build

\n

Ein klassisches Problem von Docker-Images für C++ ist die enorme Größe, die durch die Aufnahme von Compiler, Header-Dateien und Bibliotheken in das finale Image entsteht. Multi-Stage-Builds lösen dieses Problem: Die erste Stufe (Build-Stage) enthält alle Werkzeuge für die Kompilierung, die zweite Stufe (Runtime-Stage) nur die minimale Menge an Laufzeitabhängigkeiten.

\n\n
# Erste Stufe: Build\nFROM gcc:13 AS builder\nWORKDIR /app\nCOPY . .\nRUN apt-get update && apt-get install -y cmake libboost-all-dev && \\\n    cmake -B build -DCMAKE_BUILD_TYPE=Release && \\\n    cmake --build build --parallel $(nproc)\n\n# Zweite Stufe: Runtime\nFROM alpine:3.19\nRUN apk add --no-cache libstdc++ libgcc\nCOPY --from=builder /app/build/my_app /usr/local/bin/my_app\nCMD ["my_app"]
\n\n

Dieser Ansatz reduziert das finale Image von 1,5 GB (Image mit GCC) auf etwa 30 MB. Für die Ausführung einer C++-Anwendung in Alpine reichen libstdc++ und libgcc aus.

\n\n

2. Abhängigkeitsverwaltung: vcpkg und Conan

\n

Bei modernen C++-Projekten mit Dutzenden von Bibliotheken wird die manuelle Installation von Abhängigkeiten über apt-get unüberschaubar. Die beste Lösung ist die Verwendung von Paketmanagern wie vcpkg oder Conan direkt im Dockerfile.

\n\n
FROM ubuntu:22.04 AS builder\nRUN apt-get update && apt-get install -y curl git cmake build-essential\nRUN git clone https://github.com/Microsoft/vcpkg.git /opt/vcpkg && \\\n    /opt/vcpkg/bootstrap-vcpkg.sh && \\\n    /opt/vcpkg/vcpkg install fmt spdlog nlohmann-json\n\nWORKDIR /app\nCOPY . .\nRUN cmake -B build -DCMAKE_TOOLCHAIN_FILE=/opt/vcpkg/scripts/buildsystems/vcpkg.cmake && \\\n    cmake --build build
\n\n

Wichtig: Um ein Neukompilieren von vcpkg und den Bibliotheken bei jeder Änderung des Quellcodes zu vermeiden, kopieren Sie vcpkg.json und CMakeLists.txt vor dem Kopieren der restlichen Dateien. Docker cached die Schichten, und die Abhängigkeiten werden nur bei einer Änderung des Manifests neu installiert.

\n\n

3. Image-Optimierung: Statisches Linken und Alpine

\n

Zur maximalen Reduzierung der Image-Größe kann statisches Linken verwendet werden. Dies ist besonders relevant für Microservices und CLI-Tools. Beachten Sie jedoch: Statisches Linken kann die Binärdatei vergrößern, macht es aber überflüssig, dynamische Bibliotheken in den Container mitzunehmen.

\n\n
# CMakeLists.txt\nset(CMAKE_EXE_LINKER_FLAGS "-static -static-libgcc -static-libstdc++")\ntarget_link_libraries(my_app PRIVATE fmt::fmt spdlog::spdlog)
\n\n

Das finale Image kann auf scratch (leeres Image) aufgebaut werden:

\n\n
FROM scratch\nCOPY --from=builder /app/build/my_app /\nENTRYPOINT ["/my_app"]
\n\n

Ein solches Image wiegt nur wenige Megabyte. Beachten Sie jedoch: Statisches Linken ist nicht immer möglich (z. B. bei Verwendung von OpenSSL oder CUDA), und in solchen Fällen ist es besser, Alpine mit dynamischen Bibliotheken zu verwenden.

\n\n

4. Debugging von C++-Anwendungen im Container

\n

Das Debugging in Docker ist eine eigene Herausforderung. Fortgeschrittene Methoden umfassen:

\n
    \n
  • Verwendung von Debug-Images: Erstellen Sie ein separates Image mit Debug-Symbolen und gdbserver. Verbinden Sie sich von Ihrer IDE (VS Code, CLion) über Remote-Debugging damit.
  • \n
  • Core Dumps: Erlauben Sie das Schreiben von Core-Dateien im Container und analysieren Sie diese nach einem Absturz:
  • \n
\n\n
# Dockerfile für                

Blogs

Buchempfehlungen