New article
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
nemunaire 2026-03-05 23:09:20 +07:00
commit 925f5e47d5
2 changed files with 379 additions and 0 deletions

View file

@ -0,0 +1,198 @@
---
title: L'architecture pragmatique de mes projets en production
date: !!timestamp '2026-03-05 15:00:00'
tags:
- architecture
- web
- infrastructure
---
Lorsqu'on lit certaines discussions entre développeurs ou architectes
logiciels, on pourrait croire que la moindre application web nécessite
aujourd'hui une infrastructure distribuée, un cluster Kubernetes et
plusieurs services cloud spécialisés.
Pourtant, de nombreux services web (y compris ceux qui accueillent
plusieurs milliers de visiteurs par jour) peuvent fonctionner
parfaitement avec une architecture beaucoup plus simple.
Voici un retour d'expérience sur l'infrastructure que j'utilise pour
mes projets en production, dont certains dépassent les 2000 visiteurs
quotidiens, et que j'ai également appliqué pendant des années lors
d'une compétition de sécurité informatique avec plus de 250
participants en présentiel.
<!-- more -->
# Contexte
Pendant longtemps, j'ai hébergé l'ensemble de mes projets directement
chez moi. Mes sites web, mes services, ma forge Git et même mon
infrastructure d'intégration continue tournaient sur de petites
machines ARM (principalement des Pine64).
Contrairement à ce que j'entends partout, cela fonctionnait très bien.
La principale raison pour laquelle j'ai arrêté n'est pas un problème
de puissance de calcul ou de fiabilité, mais simplement mon passage à
un mode de vie plus nomade. Une connexion résidentielle stable et
permanente devient difficile à garantir lorsque l'on se déplace
souvent.
J'ai donc déplacé la partie publique de mes services chez OVH, en
essayant de conserver la même philosophie : simplicité et pragmatisme.
# Une observation simple
Dans beaucoup de projets web modernes, l'architecture ressemble à
quelque chose comme ceci :
```
utilisateur → CDN → frontend → API → base de données
```
Chaque requête déclenche du calcul côté serveur, même lorsque le
contenu change très rarement.
Dans mon cas, plusieurs de mes sites ont une caractéristique
importante : **le contenu principal change une fois par jour.**
Prenons par exemple le [jeu quotidien
Yakazu](https://yakazu-gratuit.fr/) : pour la majorité des visiteurs,
la seule chose qui compte est **la grille du jour**, qui ne change
qu'une fois par jour.
Dans ces conditions, générer la page dynamiquement à chaque requête
n'a pas beaucoup de sens.
# Architecture retenue
La solution est donc très simple : le site est entièrement statique.
Chaque jour, un événement déclenche la CI qui :
1. génère la nouvelle grille ;
2. reconstruit le site ;
3. publie les fichiers statiques.
Ces fichiers sont ensuite servis directement par l'hébergement
statique fourni avec le nom de domaine chez OVH.
Oui, l'offre gratuite de 100 MB.
Cela donne donc une architecture très simple :
```
CI → génération du site → fichiers statiques → OVH
```
Tout le trafic est absorbé par l'infrastructure de l'hébergeur, ce
qui est exactement ce pour quoi elle est conçue.
# Frontend
Le site est construit avec SvelteKit.
Ce choix peut surprendre puisque je n'utilise pas du tout les
capacités serveur de ce framework. Mais il permet :
- de générer facilement un site statique (`@sveltejs/adapter-static`) ;
- d'avoir un routage propre ;
- de structurer le code proprement ;
- de construire des Progressive Web Apps.
Autrement dit : un framework moderne, mais sans dépendre d'un backend
permanent.
# Et quand il faut un backend ?
Certaines fonctionnalités nécessitent malgré tout un peu de logique
serveur.
Par exemple, les championnats organisés régulièrement doivent vérifier les
participations et enregistrer les résultats et les chronos.
Dans ce cas, je démarre un petit serveur backend séparé, qui ne reçoit
qu'un nombre très limité de requêtes.
L'architecture devient alors :
```
site statique → CORS → petit backend
```
Ce backend est volontairement minimal et ne traite que les actions
qui ne peuvent pas être réalisées côté client.
Le point important est que **la majorité du trafic ne le touche
jamais**.
# Résultat
Avec cette architecture :
- la quasi-totalité du trafic est servie sous forme de fichiers ;
- il n'y a quasiment pas de calcul côté serveur ;
- la surface de panne est très réduite.
Les problèmes que je rencontre sont presque toujours liés au pipeline
de génération :
- une image Docker qui n'est plus à jour ;
- un déclenchement CI qui échoue ;
- un oubli dans la génération des données (l'absence de grille de jeu par exemple).
Mais ces problèmes sont faciles à détecter et se corrigent
généralement en quelques minutes.
# Pourquoi faire simple ?
Avec un peu de recul, je me rends compte que cette approche suit
quelques principes simples :
1. **pré-calculer ce qui peut l'être** ;
2. **servir des fichiers plutôt que du calcul** ;
3. **réserver le backend aux cas réellement nécessaires**.
Ces principes permettent souvent d'absorber une charge importante
avec des ressources très modestes.
Pendant plus de dix ans, j'ai par exemple organisé un challenge de
sécurité informatique qui a fini par accueillir environ 300
participants simultanés, avec des machines très simples.
Le secret n'était pas la puissance du matériel, mais la conception du
système. Je vous laisse visionner ma [présentation de cette
infrastructure](https://youtube.com/watch?v=naFxBW5yoUA), avec les
tâtonnements, les erreurs et les contraintes qui l'ont façonné.
# Et les comptes utilisateurs, les paiements ?
Une "connexion" à un compte utilisateur n'a pas nécessairement besoin
d'une validation systématique par un backend (d'ailleurs la notion de
compte utilisateur n'a pas toujours de sens).
Une seule requête d'API peut faire l'authentification (que ce soit
la validation d'un paiement ou d'une adresse email, ...) puis on
stocke cette réponse dans le navigateur pour en faire usage dans
l'interface : maintenant ... ou même plus tard. Comme ça, inutile de
refaire une requête à l'API pour une information que l'on a déjà.
Non seulement cela réduit la charge du serveur, mais cela accroit
aussi la vitesse de chargement pour l'utilisateur qui voit ses données
sans appel réseau, et donc même hors ligne. Tout le monde est gagnant.
# Conclusion
L'infrastructure moderne propose de nombreux outils très puissants.
Mais il est parfois utile de se rappeler que beaucoup de problèmes
peuvent être résolus de manière beaucoup plus simple.
Avant d'ajouter une nouvelle couche technologique, il vaut souvent la
peine de se poser une question très simple :
**est-ce que ce contenu doit vraiment être généré à chaque requête ?**
Dans bien des cas, la réponse est non.