Le point de départ
J’avais des jeux qui marchaient chacun dans leur coin. Ce que je voulais, c’était que ça ressemble à un vrai service : des joueurs qui retrouvent leur pseudo, des classements, et la certitude que si je me trompe en déployant, rien ne casse pour de bon.
Contrainte que je me suis donnée : un VPS modeste, des outils simples, et que je comprenne chaque pièce. Pas de base de données managée ni de plateforme clé en main.
Les choix qui comptent
Les jeux n’écrivent qu’une ligne par partie
Chaque jeu ajoute un résultat dans un fichier JSONL et c’est tout. Une sonde Python, lancée chaque minute par systemd, les range dans SQLite et calcule classements, saisons, succès et défis. Si la sonde plante, les jeux continuent ; si un jeu plante, la sonde n’y voit rien. Les deux ne se connaissent pas.
Des profils sans mot de passe, mais sérieux
Un pseudo réservé, un cookie de session opaque (256 bits, HttpOnly, SameSite) dont seule l’empreinte est stockée, et un code de récupération affiché une fois. Origine vérifiée sur chaque écriture, débit limité, aucune dépendance npm : 500 lignes que je peux relire en entier. Comme les cookies sont partagés entre sous-domaines, un seul profil suit le joueur d’un jeu à l’autre.
Déployer sans avoir peur
Un merge sur GitHub déclenche le déploiement : image construite, conteneur remplacé, contrôle de santé. Si le contrôle échoue, l’image précédente (étiquetée :previous) est remise en place toute seule. Chaque conteneur tourne en lecture seule, sans privilège noyau, avec limites de mémoire et de processus.
Des sauvegardes que le serveur ne peut pas ouvrir
Les sauvegardes sont chiffrées avec age, avec la clé publique seulement : si le serveur est compromis, l’attaquant ne peut pas relire les archives. La clé privée est ailleurs, pas sur la machine.
Ce qui a été difficile
Les identités. Un joueur peut avoir joué sous un pseudo avant de créer un profil, puis le renommer, puis supprimer son compte. Il a fallu décider ce que devient l’historique dans chaque cas (rattaché au profil, ou effacé avec lui) et le faire de la même façon dans les classements, les fiches publiques et les cartes de partage.
Tester sans prod. Beaucoup de choses (cookies de domaine, volumes Docker) ne se vérifient vraiment qu’une fois déployé. J’ai appris à isoler ce qui est testable (le service de profils a sa suite de tests) et à dire clairement ce qui ne l’est pas.
Ce que je ferais autrement
Les salons de jeu vivent en mémoire : un redémarrage coupe les parties en cours. Pour quelques amis c’est acceptable, mais le prochain pas serait de rendre les salons reprenables.
La sonde est un gros fichier Python. Elle marche et elle est testée à la main sur des jeux de données fabriqués, mais je la découperais en modules avec de vrais tests automatiques.