Votre application C++ mérite un meilleur emballage : plongeons dans Docker
\n\nVous avez écrit un analyseur C++ génial qui traite des gigaoctets de journaux à la vitesse de l'éclair. Ou peut-être avez-vous créé un microservice à forte charge pour travailler avec des sockets réseau. Le code est débogué, tout fonctionne parfaitement. Mais le moment de vérité arrive — le déploiement. Et là, ça commence : « Quelle version de libcurl as-tu ? », « Pourquoi ça a planté en production avec une erreur GLIBC ? », « Pourquoi installes-tu tout GCC sur le serveur ? ».
\n\nÇa vous parle ? Bienvenue dans le monde de la conteneurisation d'applications C++ avec Docker. Si vous pensiez jusqu'à présent que Docker était réservé à JavaScript et Python, vous passez à côté de quelque chose. En réalité, c'est pour le C++ que la conteneurisation offre un super-pouvoir : vous obtenez un environnement immuable dans lequel le binaire est compilé une fois et fonctionne partout — de votre ordinateur portable à votre cluster de production.
\n\nDans cet article, nous n'allons pas simplement aborder la théorie. Nous allons pas à pas créer une application C++, l'empaqueter dans Docker, optimiser l'image à la taille minimale possible et faire fonctionner le conteneur comme une horloge. C'est parti !
\n\nPourquoi Docker est le meilleur ami du développeur C++ ?
\n\nBeaucoup pensent que les applications C++ sont faciles à distribuer sous forme de binaires. Techniquement — oui. Pratiquement — c'est la porte de l'enfer. Différentes distributions Linux, versions de glibc, bibliothèques manquantes, compatibilité ABI cassée — ce ne sont là que quelques-uns des problèmes.
\n\nDocker résout les trois principales douleurs du développeur C++ :
\n\n- \n
- Reproductibilité de la compilation : vous savez exactement quelle version du compilateur, de CMake, de Boost et des autres dépendances est utilisée. Plus de « ça marche sur ma machine ». \n
- Isolation : le conteneur ne pollue pas le système hôte. Pas besoin d'installer GCC sur le serveur de production — un runtime minimal suffit. \n
- Mise à l'échelle : l'image prête peut être facilement déployée dans Kubernetes ou Docker Swarm. Le C++ gère parfaitement la charge, et Docker aide à répartir cette charge. \n
Et surtout — la conteneurisation d'applications C++ ne nécessite pas de magie. Tout ce dont vous avez besoin, c'est de Docker et d'un peu de patience.
\n\nCréons une application C++ simple pour la conteneurisation
\n\nPour l'exemple, prenons non pas un « Hello, World! », mais quelque chose de plus concret. Supposons que nous écrivions un petit serveur HTTP en C++ utilisant Boost.Beast. Mais pour ne pas alourdir l'article, faisons une version simplifiée — un serveur écho socket avec l'API POSIX pure. Cela montrera comment travailler avec les dépendances système.
\n\nFichier server.cpp :
#include <iostream>\n#include <string>\n#include <cstring>\n#include <sys/socket.h>\n#include <netinet/in.h>\n#include <unistd.h>\n\nint main() {\n int server_fd, new_socket;\n struct sockaddr_in address;\n int opt = 1;\n int addrlen = sizeof(address);\n char buffer[1024] = {0};\n\n // Création du socket\n if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {\n perror("socket failed");\n exit(EXIT_FAILURE);\n }\n\n // Liaison au port 8080\n if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) {\n perror("setsockopt");\n exit(EXIT_FAILURE);\n }\n address.sin_family = AF_INET;\n address.sin_addr.s_addr = INADDR_ANY;\n address.sin_port = htons(8080);\n\n if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {\n perror("bind failed");\n exit(EXIT_FAILURE);\n }\n\n if (listen(server_fd, 3) < 0) {\n perror("listen");\n exit(EXIT_FAILURE);\n }\n\n std::cout << "Server listening on port 8080" << std::endl;\n\n while (true) {\n if ((new_socket = accept(server_fd, (struct sockaddr *)&address,\n (socklen_t*)&addrlen)) < 0) {\n perror("accept");\n exit(EXIT_FAILURE);\n }\n\n read(new_socket, buffer, 1024);\n