11 min de lecture - Auto-héberger notre infrastructure : observabilité, sécurité, déploiement
Infrastructure & DevOps
Nous auto-hébergeons tout. Pas par idéologie — par souci d'économie et de contrôle.
Les services managés sont excellents, jusqu'au jour où la facture de monitoring dépasse la facture de calcul, où il faut inspecter le plan d'exécution d'une requête sur une base de données qui ne vous appartient pas, ou où un fournisseur retire discrètement la fonctionnalité dont dépend votre pipeline. Nous avons connu les trois cas. Nous faisons donc tourner notre propre infrastructure et, pour une structure de conseil légère, l'équation économique joue largement en notre faveur.
Cet article détaille la façon dont nous l'exploitons concrètement — organisé non pas par outil, mais par le problème que résout chaque couche. Si vous avez lu la première partie consacrée à notre stack de frameworks, voici ce qui se trouve en dessous.
Vue d'ensemble de la stack
| Couche | Outils | Rôle |
|---|---|---|
| Observabilité | Grafana, Prometheus, Loki, k6, InfluxDB, Beszel | Métriques, journaux, alerting, tests de charge, supervision des hôtes |
| Données | PostgreSQL, MongoDB, Redis | État relationnel, documentaire et éphémère |
| Déploiement | Docker, Coolify | Conteneurs, CI/CD, déploiements sans interruption de service |
| Inférence IA | Ollama | Service de LLM en local et évaluation de modèles |
| Réseau et secrets | Tailscale, Cloudflared, Infisical | VPN maillé, tunnels, secrets centralisés |
| Sauvegarde | Duplicati | Sauvegardes chiffrées hors site, tests de restauration mensuels |
Coût total : moins de 200 EUR/mois. Tous les outils sont open source.
Voir ce qui se passe
Impossible de piloter ce qu'on ne voit pas. C'est le premier problème que nous avons résolu, et cette couche reste la plus importante.
Prometheus collecte les métriques de chaque service — API, bases de données, workers en arrière-plan, la plateforme de déploiement elle-même — toutes les 15 secondes. Trente jours de données haute résolution, sous-échantillonnées ensuite. Loki gère les journaux : la sortie structurée de chaque conteneur arrive via des sidecars Promtail, indexée par label (service, environnement, sévérité, trace ID) sans indexer le corps complet du log. Le stockage reste ainsi dix fois moins coûteux qu'avec Elasticsearch, tout en nous permettant de répondre en quelques secondes à la question « que s'est-il passé à 3h47 sur le service de paiement ? ».
Grafana relie le tout. C'est là que les métriques, les journaux et les résultats des tests de performance issus d'InfluxDB atterrissent dans des tableaux de bord unifiés. C'est aussi notre système d'alerting : latence P95 supérieure à 500 ms, taux d'erreur supérieur à 1 %, disque à 80 %, certificat expirant dans la semaine. Quand quelque chose tourne mal, c'est généralement Grafana qui le sait en premier.
Avant chaque mise en production, nous lançons des tests de charge k6 sur l'environnement de staging — schémas de trafic réalistes, parcours d'authentification, soumissions de formulaires concurrentes — et streamons les résultats vers InfluxDB. Les tableaux de bord Grafana affichent ensuite les tendances de latence P50/P95/P99 sur les différentes releases. « Est-ce que ça fonctionne ? » est une question différente de « est-ce que ça fonctionne sous charge ? », et les outils d'APM managés y répondent aussi, mais à un prix 10 fois supérieur.
Il reste un angle mort que Prometheus ne couvre pas bien : la visibilité au niveau du matériel. Temps de vol CPU (steal time), saturation des I/O disque, pression mémoire, débit réseau par interface. Beszel comble ce manque avec des agents légers sur chaque hôte, qui alimentent les mêmes tableaux de bord Grafana. Cela nous donne la vision matérielle que les métriques de conteneurs ne captent pas.
L'ensemble de la stack d'observabilité tourne sur une seule VM à 4 cœurs, 8 Go. Environ 1,5 Go de RAM utilisés, un CPU quasi négligeable en dehors des pics de requêtes.
Trois bases de données, aucun chevauchement
Nous faisons tourner PostgreSQL, MongoDB et Redis. Chacun a un rôle précis, et ils ne se marchent pas dessus.
PostgreSQL récupère tout ce qui est relationnel et transactionnel. Comptes utilisateurs, facturation, métadonnées de projet, journaux d'audit — tout ce qui exige l'ACID, des clés étrangères ou des jointures complexes. Nous sommes sur PostgreSQL 16, avec réplication logique vers un serveur de secours (standby) et PgBouncer en frontal pour garder le nombre de connexions sous contrôle.
MongoDB gère les données de forme documentaire, là où la flexibilité du schéma compte plus que l'intégrité relationnelle. Dans FormAI, les définitions de formulaires sont des structures JSON profondément imbriquées qui changent de forme en permanence au fil de nos itérations. MongoDB nous permet de les faire évoluer sans scripts de migration. Nous l'utilisons aussi pour l'event sourcing, quand des collections de documents en ajout seul (append-only) collent naturellement au domaine métier.
Redis n'est pas vraiment une base de données pour nous — c'est une brique opérationnelle. Sessions, limitation de débit (rate limiting), mise en cache, pub/sub pour les fonctionnalités temps réel, files de jobs via BullMQ. Tout est éphémère. Si Redis disparaissait, aucune donnée permanente ne serait perdue ; les choses ralentiraient simplement jusqu'à son retour.
Oui, gérer trois moteurs est plus complexe qu'un seul. Mais chacun reste dans son domaine de force, et nous évitons l'antipattern qui consiste à forcer des requêtes relationnelles dans un store documentaire ou à entasser des données de cache dans une base transactionnelle.
Livrer du code sans la taxe des plateformes managées
Tout est livré sous forme de conteneur Docker. Sans exception. Builds reproductibles, parité dev/prod, exécution possible n'importe où.
Pour le déploiement, nous utilisons Coolify — auto-hébergé, installé sur une VM à $20/mois, et qui gère chacun des services que nous exploitons. Un push sur main, et Coolify construit l'image, exécute les health checks, effectue une mise à jour progressive sans interruption de service. Les environnements de staging, de production et de preview bénéficient tous du même niveau de prise en charge. En coulisses, Traefik gère le SSL, le routage et la répartition de charge. Les limites de CPU et de mémoire par service sont visibles dans un tableau de bord, à côté des logs de build et de l'historique des déploiements.
Cette taxe des plateformes est bien réelle, et elle s'accumule vite. Un service qui coûte $7/mois en calcul brut revient à $25-50/mois sur Heroku ou Railway une fois qu'on intègre l'egress, les minutes de build et la tarification par siège. Multipliez cela par 15 à 20 services, et l'écart devient considérable.
La contrepartie : nous maintenons Coolify nous-mêmes. Mises à jour, sauvegardes de la base de configuration, débogage occasionnel quand un build échoue de façon étrange. Environ deux heures par mois. Une fraction de ce que les économies sur les frais de plateforme permettent de couvrir.
Faire tourner des modèles en local
Ollama nous donne accès à l'inférence LLM en local. Pas d'appels API, pas de facturation au token, aucune donnée qui sort de notre réseau.
Nous le faisons tourner sur une machine dédiée équipée d'un GPU modeste, qui sert des modèles ouverts quantifiés pour un usage interne — suggestions de revue de code, brouillons de documentation, génération de données de test, comptes rendus de réunion. Toutes les tâches n'ont pas besoin d'un modèle de pointe. Un modèle à 7B de paramètres s'en sort très bien dans la plupart des cas, et il répond plus vite que n'importe quel endpoint API, puisqu'il n'y a aucun aller-retour réseau.
Cette machine nous sert aussi de plateforme d'évaluation. Quand nous évaluons des modèles à poids ouverts pour un projet client, nous les récupérons en local, lançons des benchmarks, comparons les résultats — sans provisionnement de GPU cloud, sans jonglage avec des clés API. Cette rapidité compte quand un client demande « quel modèle devrions-nous utiliser ? » et veut une réponse cette semaine, pas le mois prochain.
Le périmètre de sécurité
Quand on s'auto-héberge, aucun fournisseur cloud n'abstrait le réseau à votre place. Vous construisez le périmètre vous-même, ou vous n'en avez pas.
Tailscale est notre VPN maillé. Chaque serveur, chaque poste de développeur et chaque runner CI rejoint le réseau. Les services internes — bases de données, panneaux d'administration, tableaux de bord de supervision — vivent exclusivement sur le maillage Tailscale. Aucune IP publique, aucun port ouvert sur l'internet public. Les tunnels basés sur WireGuard sont assez rapides pour que la latence supplémentaire soit imperceptible, et les contrôles d'accès basés sur l'identité nous permettent de définir des permissions granulaires par personne et par service.
Cloudflared fonctionne dans l'autre sens : il expose des services spécifiques à l'internet public sans ouvrir de ports sur le pare-feu. Nos API publiques et nos sites web se connectent en sortie vers Cloudflare via des tunnels chiffrés. Vu de l'extérieur, le trafic transite par le CDN et la protection DDoS de Cloudflare. Vu de l'intérieur, c'est le serveur qui initie la connexion. Aucun port entrant. Cela élimine toute une classe de surface d'attaque.
Infisical conserve les secrets. Clés API, identifiants de bases de données, tokens tiers, clés de chiffrement — tout est centralisé au lieu d'être dispersé dans des fichiers .env et des stores de variables CI. Les services récupèrent les secrets à l'exécution via l'agent Infisical, injectés sous forme de variables d'environnement. Rotation, journaux d'audit, cloisonnement par environnement — tout est intégré nativement.
Ensemble, ces trois outils créent une posture zero-trust : chaque connexion authentifiée et chiffrée, des secrets centralisés avec pistes d'audit, une surface d'attaque publique limitée aux endpoints proxifiés par Cloudflare. C'est le même modèle de sécurité que les grandes entreprises mettent en place en dépensant des sommes à six chiffres auprès d'éditeurs commerciaux. Nous l'obtenons avec trois projets open source et zéro frais de licence.
Quand les choses tournent mal
S'auto-héberger, c'est assumer soi-même les modes de défaillance. Il n'y a pas de bouton « appeler le support ». Votre stratégie de sauvegarde est votre police d'assurance, et si vous n'avez jamais testé une restauration, vous n'avez pas une sauvegarde — vous avez un espoir.
Duplicati fait tourner notre pipeline de sauvegarde. Sauvegardes planifiées de tout ce qui compte : dumps logiques PostgreSQL, exports MongoDB, fichiers de configuration, exports du coffre de secrets, définitions des tableaux de bord Grafana. Tout est chiffré côté client avant d'être envoyé vers un stockage objet compatible S3, hébergé hors site chez un fournisseur différent de notre infrastructure principale.
Le calendrier : bases de données toutes les 6 heures (PostgreSQL via pg_dump, MongoDB via mongodump, avec vérification scriptée de l'intégrité avant chaque envoi). Configuration et secrets tous les jours. Snapshots complets des VM toutes les semaines, conservés pendant 30 jours.
Nous testons les restaurations tous les mois. Nous démarrons une VM propre, récupérons le dernier jeu de sauvegardes, restaurons les bases de données, déployons les services via Coolify, puis lançons la suite de smoke tests. Moins de 45 minutes de bout en bout. Le jour où nous sautons ce test est le jour où nous cessons de faire confiance à nos sauvegardes.
Les chiffres réels
Voici ce que nous payons réellement chaque mois :
| Ressource | Coût mensuel |
|---|---|
| Calcul principal (8 vCPU, 32 Go RAM) | ~90 EUR |
| VM d'observabilité (4 vCPU, 8 Go RAM) | ~25 EUR |
| Stockage de sauvegarde hors site (500 Go) | ~10 EUR |
| Domaine et DNS | ~5 EUR |
| Tailscale (le plan gratuit couvre nos effectifs) | 0 EUR |
| Cloudflare (plan gratuit + tunnels) | 0 EUR |
| Total | ~130 EUR/mois |
Chaque outil de cette stack est open source. Les seuls coûts sont le calcul, le stockage et la bande passante. L'équivalent managé — Grafana Cloud, des bases de données managées, Heroku ou Railway, un gestionnaire de secrets commercial, un outil d'APM cloud — dépasserait 800 EUR/mois pour la même charge de travail.
La contrepartie, c'est le temps. Nous consacrons 4 à 6 heures par mois à la maintenance : mises à jour, revue de supervision, vérification des sauvegardes, débogage occasionnel. Pour nos effectifs, l'équation reste favorable.
Cet article a couvert la façon dont nous maintenons l'infrastructure en état de marche. La troisième partie couvre la couche métier — CRM, planification, e-mail, publication de contenu, et l'automatisation qui relie le tout.
Si vous envisagez l'auto-hébergement et voulez savoir si cela a du sens pour vos effectifs et votre charge de travail, nous sommes passés par là et serons ravis de partager ce que nous avons appris — y compris les moments qui ne se sont pas déroulés sans accroc.
Parlons-en.
Exceev accompagne les startups et les PME dans leurs projets de conseil, d'outillage open source et de logiciels prêts pour la production.