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

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 à un niveau avancé



La conteneurisation d'applications C++ avec Docker ne se limite pas à transférer du code dans un environnement isolé. À un niveau avancé, c'est l'art de trouver un équilibre entre la taille de l'image, la vitesse de construction, la sécurité et la compatibilité avec les bibliothèques système. Dans cet article, nous aborderons les techniques qui vous aideront à créer des images Docker efficaces, légères et maintenables pour vos projets C++.



Nous supposons que vous êtes déjà familier avec les bases de Docker (commandes docker build, docker run) et la syntaxe de base du Dockerfile. Passons maintenant aux tâches réelles : construction multi-étapes, gestion des dépendances système, débogage dans le conteneur et intégration avec CI/CD.



1. Construction multi-étapes : séparer la compilation et l'exécution



Le principal problème du C++ dans Docker est la taille de l'image. Un ensemble complet d'outils (g++, cmake, make, paquets de développement) peut peser 1 à 2 Go. La solution est la construction multi-étapes (multi-stage build).



Prenons un exemple classique : une application C++ utilisant la bibliothèque libcurl.



# Première étape : constructionFROM ubuntu:22.04 AS builder

RUN apt-get update && apt-get install -y \ build-essential \ cmake \ libcurl4-openssl-dev \ && rm -rf /var/lib/apt/lists/*

WORKDIR /appCOPY . .

RUN cmake -B build -DCMAKE_BUILD_TYPE=Release \ && cmake --build build --parallel $(nproc)

# Deuxième étape : image exécutableFROM ubuntu:22.04-slim

RUN apt-get update && apt-get install -y \ libcurl4 \ && rm -rf /var/lib/apt/lists/*

COPY --from=builder /app/build/myapp /usr/local/bin/myapp

CMD ["myapp"]


Points clés :

  • Dans la première étape (builder), nous installons tous les outils et dépendances pour la construction.
  • Dans la deuxième étape, uniquement les dépendances d'exécution (libcurl4 au lieu de libcurl4-openssl-dev).
  • L'image finale contient uniquement le binaire compilé et les bibliothèques nécessaires.
  • Nous utilisons --parallel $(nproc) pour accélérer la construction.


La taille de l'image passe d'environ 1,2 Go à environ 80 Mo. C'est crucial pour le déploiement et le téléchargement des images dans CI/CD.



2. Optimisation de la mise en cache et des couches Docker



Chaque instruction dans un Dockerfile crée une couche. Un ordre incorrect des instructions entraîne une invalidation complète du cache au moindre changement de code.



Règle : copiez d'abord ce qui change rarement (CMakeLists.txt, dépendances), puis le code.



FROM ubuntu:22.04 AS builder

WORKDIR /app

# 1. Dépendances système (changent rarement)RUN apt-get update && apt-get install -y \ build-essential cmake libboost-all-dev \ && rm -rf /var/lib/apt/lists/*

# 2. Fichiers de configuration de construction (changent peu souvent)COPY CMakeLists.txt .

# 3. Code source (change constamment)COPY src/ ./src/

# 4. ConstructionRUN cmake -B build && cmake --build build


Conseils supplémentaires :

  • Utilisez .dockerignore pour exclure build/, .git/, *.o.
  • Regroupez les RUN apt-get install en une seule commande – cela réduit le nombre de couches.
  • Pour les projets C++ avec un grand nombre de fichiers d'en-tête, envisagez d'utiliser ccache dans le conteneur.


3. Gestion des bibliothèques système et liaison statique



Parfois, les bibliothèques dynamiques sont absentes ou incompatibles dans le conteneur. Une approche avancée consiste à utiliser la liaison statique ou Alpine Linux.



Option A : Construction statique (g++)

FROM alpine:3.18 AS builder

RUN apk add --no-cache g++ gcc musl-dev make cmake

WORKDIR /appCOPY . .

# Liaison statiqueRUN g++ -static -O2 -o myapp main.cpp -lpthread

FROM scratchCO

Blogs

Book Recommendations