Un produit web commercial écrit en C, serveur par CGI en 2026
Sommaire
En bref
- L'auteur a shipped marketyour.games, une application web complète (comptes utilisateurs, paiements Stripe, emails transactionnels) en C pur via CGI sur OpenBSD.
- La pile technique (BCHS : OpenBSD, C, httpd, SQLite) tient en trois dépendances : libcurl, libsodium, libcjson.
- Chaque requête crée un nouveau processus ; le déploiement est un simple remplacement de binaire, sans redémarrage ni downtime.
Ce que dit la source
L'auteur soutient que CGI, déclaré obsolète vers 2004, ne mérite plus ce jugement en 2026. Il présente sa réalisation comme preuve qu'une application web moderne et entièrement fonctionnelle peut être écrite en C, déployée en un seul binaire statique, avec une surface d'attaque réduite et une chaîne de dépendances minimale.
- Le stack BCHS utilise OpenBSD (pledge, unveil, chroot natif), C pur, httpd intégré et SQLite embarqué ; zéro framework, zéro templating language, zéro serveur de base de données distant.
- Les trois dépendances (libcurl pour Stripe/Postmark, libsodium pour chiffrement et génération d'identifiants, libcjson pour parsing) sont vendored et compilées avec le projet.
- Chaque requête HTTP déclenche un fork du binaire CGI ; le déploiement remplace simplement le fichier exécutable, sans redémarrage ni interruption de service pour les requêtes en cours.
- Les assets (CSS, JS, images) sont compilés directement dans le binaire et servis depuis la mémoire, éliminant les accès disque pour les contenus statiques.
- La pile minimise les dépendances transitives indirectes et renforce la sécurité d'approvisionnement : compromettrerait libcurl (projet très scruté) plutôt qu'un micro-paquet npm obscur.
- OpenBSD isole le binaire CGI via chroot et sandboxing natif ; pledge restreint les appels système permis.
Dans les commentaires
Débat partagé, légèrement sceptique sur les coûts cachés. Un noyau de commentateurs valide l'approche et cite des projets similaires réussis ; d'autres pointe les limitations légitimes : concurrence en C, risques de vulnérabilités non détectées, sauvegarde SQLite sous forte charge, startup overhead du forking.
- Plusieurs commentateurs notent que Go offre une meilleure expérience outillage et une concurrence native (threaded) sans l'overhead du forking, avec un seul binaire et sans dépendances externes si CGO_ENABLED=0.
- Un argument récurrent : nginx (ou tout reverse proxy) est nécessaire pour rate limiting, distribution, filtrage, et gestion des connexions concurrentes ; CGI ne les fournit pas nativement.
- La question des sauvegardes SQLite et de la robustesse sous forte charge : SQLite supporte les lectures concurrentes mais les écritures simultanées de plusieurs processus sont verrouillées ; peu de détail dans l'article sur le comportement en production.
- Un commentateur souligne que le processus CGI forké gaspille cycles et mémoire à chaque requête (.bss et .data réinitialisés) comparé à un serveur persistent threadé ou async, même si c'est acceptable pour faible traffic.
- Peu de confiance en la sécurité long terme : un binaire C monolithique sans framework moderne est une cible d'exploitation possible, et les vulnérabilités du zero-day pourraient rester dormantes longtemps sans framework de détection.
- Un commentateur demande pourquoi le stack moderne (TypeScript + React + Next.js, etc.) est devenu la norme ; les réponses sous-entendent des besoins réels (haute interactivité front, scaling horizontal) mais admettent que beaucoup de projets les surdimensionnent.
Alternatives citées : Go (binaire statique, concurrence native, outillage moderne) et Rust (similaire à Go mais plus sûr en mémoire) cités comme alternatives offrant des points positifs du C sans certains coûts.
Notre lecture
L'article démontre un cas réel d'une approche minimaliste viable. Pour un produit de niche, faible traffic, équipe réduite et tolérance au déploiement sans rechargement d'état, c'est défendable : gain en clarté, réduction drastique des dépendances, debugging simplifié. Cependant, le choix reste étroitement contextualisé. Les risques de sécurité à long terme (RCE non détecté en C sans framework) et les limites de concurrence (forking costeux sous charge) ne disparaissent pas. À considérer sérieusement pour les outils internes, les microservices isolés ou les produits à très faible charge ; à tester d'abord si scaling horizontal ou interactivité front complexe devient nécessaire.