Docker et C++ : conteneurisation d'applications de niveau avancé

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Docker et C++ : conteneurisation d'applications : niveau avancé

\n\n

La conteneurisation d'applications C++ avec Docker ne se limite pas à transférer un binaire dans un environnement isolé. Au niveau avancé, il faut prendre en compte les spécificités de la compilation, la gestion des dépendances, l'optimisation de la taille de l'image et le débogage. Dans cet article, nous allons analyser les meilleures pratiques pour créer des images Docker efficaces pour des projets C++, en utilisant la construction multi-étapes, la liaison statique et dynamique, ainsi que des outils modernes tels que CMake et vcpkg.

\n\n

1. Construction multi-étapes (Multi-stage build)

\n

Le problème classique des images Docker pour C++ est leur taille énorme due à l'inclusion du compilateur, des fichiers d'en-tête et des bibliothèques dans l'image finale. La construction multi-étapes résout ce problème : la première étape (build stage) contient tous les outils de compilation, tandis que la seconde (runtime stage) ne contient qu'un ensemble minimal de dépendances d'exécution.

\n\n
# Première étape : compilation\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# Deuxième étape : exécution\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

Cette approche réduit l'image finale de 1,5 Go (image avec GCC) à environ 30 Mo. Pour exécuter une application C++ dans Alpine, seuls libstdc++ et libgcc sont nécessaires.

\n\n

2. Gestion des dépendances : vcpkg et Conan

\n

Pour les projets C++ modernes avec des dizaines de bibliothèques, l'installation manuelle des dépendances via apt-get devient ingérable. La meilleure solution est d'utiliser des gestionnaires de paquets, comme vcpkg ou Conan, directement dans le 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

Important : pour éviter de recompiler vcpkg et les bibliothèques à chaque modification du code source, copiez vcpkg.json et CMakeLists.txt avant de copier les autres fichiers. Docker met en cache les couches, et les dépendances ne seront réinstallées qu'en cas de modification du manifeste.

\n\n

3. Optimisation de l'image : liaison statique et Alpine

\n

Pour réduire au maximum la taille de l'image, vous pouvez utiliser la liaison statique. Cela est particulièrement pertinent pour les microservices et les utilitaires en ligne de commande. Cependant, rappelez-vous : la liaison statique peut augmenter la taille du binaire, mais elle évite d'avoir à inclure les bibliothèques dynamiques dans le conteneur.

\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

L'image finale peut être construite sur scratch (image vide) :

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

Une telle image ne pèse que quelques mégaoctets. Cependant, notez que la liaison statique n'est pas toujours possible (par exemple, avec OpenSSL ou CUDA), et dans ce cas, il est préférable d'utiliser Alpine avec des bibliothèques dynamiques.

\n\n

4. Débogage d'applications C++ dans un conteneur

\n

Le débogage dans Docker est une difficulté supplémentaire. Les méthodes avancées incluent :

\n
    \n
  • Utilisation d'images de débogage : construisez une image séparée avec des symboles de débogage et gdbserver. Connectez-vous-y depuis votre IDE (VS Code, CLion) via le débogage à distance.
  • \n
  • Core dumps : autorisez l'écriture des fichiers core dans le conteneur et analysez-les après un plantage :
  • \n
\n\n
# Dockerfile pour                

Blogs

Book Recommendations