Bascule à la demande d'un serveur Minecraft vers le cloud
Infrastructure · Go · Cloud
En bref
Nos gros événements Minecraft manquaient de puissance, mais ils ne durent que quelques heures par mois. Plutôt qu’un serveur dédié payé en permanence, le serveur bascule à la demande sur une VM Scaleway puissante facturée à l’heure, puis revient sur notre petit VPS et la VM s’éteint.
- ~6,5 € par mois de puissance supplémentaire au lieu de ~140 € pour un dédié, soit près de 1 500 € d’économie par an.
- ~1 minute de coupure par bascule, aucune modification du serveur de jeu.
- Lever, un orchestrateur en Go, automatise la bascule avec des garde-fous testés pour qu’aucune erreur ne puisse coûter un monde ou une base de données.
Go · Docker · WireGuard · HAProxy · Cloudflare Tunnel · Pelican · MongoDB · Scaleway
Le problème : payer la puissance, pas l’attente
Notre serveur réunit un lobby, des mini-jeux et un mode UHC dans une seule instance. Au quotidien, un petit VPS suffit. Les gros événements, eux, le saturent : la boucle de tick est mono-thread, avec un budget de 50 ms par tick ; sur des vCPU partagés, le steal time fait exploser le MSPT.
Le point décisif est le profil d’usage : la puissance n’est utile que pendant les événements, une vingtaine d’heures par mois, soit moins de 3 % du temps. J’ai comparé trois options :
- Un VPS plus gros : payé 24 h/24, pour un gain limité en mono-thread ;
- Un serveur dédié gaming (Ryzen 7 9800X3D, ~140 € HT / mois) : la meilleure machine, mais qui attendrait 97 % du temps ;
- Une instance cloud à l’heure (Scaleway, 4 cœurs EPYC Turin dédiés, 32 Go) : environ 0,23 € de l’heure, et seul le disque reste facturé quand elle est éteinte.
Allumée en permanence, l’instance Scaleway coûterait plus cher qu’un dédié (environ 165 € par mois). Elle ne gagne que grâce à l’usage intermittent, d’où la question : jusqu’où ?
Le seuil de rentabilité se situe vers 600 heures par mois, soit 20 heures par jour. À notre rythme, l’écart est d’un facteur 20, et il reste large même avec trois fois plus d’événements (~15,5 € pour 60 h). Restait à rendre cette solution sûre et sans effort.
L’architecture
Le schéma est actif/passif : tout ce qui doit rester en ligne vit sur le VPS ; la VM ne porte que la puissance de calcul.
Les décisions qui structurent l’ensemble :
- Un tunnel WireGuard initié par la VM. Elle n’expose aucun port entrant et n’a pas besoin d’IP fixe ; son adresse peut changer à chaque démarrage sans rien casser. Tout transite par le tunnel : jeu, administration, base de données, fichiers.
- Une adresse joueurs qui ne change jamais. HAProxy tourne en mode TCP sur le VPS : le backend VM est prioritaire, le VPS est déclaré
backup, et un health check TCP sélectionne l’instance active. Le PROXY protocol v2 transmet l’IP réelle des joueurs. HAProxy reste en L4, sans terminer le protocole Minecraft : le backend gardeonline-mode=true. Velocity, lui, imposeonline-mode=falseet le player-info forwarding. - Une administration sans port ouvert. Le panel Pelican, Wings (le daemon de Pelican) sur la VM et Lever sont publiés via Cloudflare Tunnel. Cloudflare Access protège le panel et Lever ; Wings, lui, reste hors d’Access, car le panel appelle son API et le navigateur y ouvre le websocket de la console : il s’appuie sur sa propre authentification (jeton du nœud pour l’API, JWT signé par le panel pour le websocket).
- Une seule base MongoDB, sur le VPS. Elle écoute sur l’interface WireGuard (
10.8.0.1), jamais sur l’IP publique : la même URI fonctionne depuis les deux hôtes. J’ai écarté le replica set : à deux membres, dont l’un est éteint 97 % du temps, il perd le quorum sans arbitre, et toutes les écritures passent de toute façon par le primaire. J’ai aussi écarté une copie de la base fusionnée au retour, car le site continue d’écrire pendant l’événement. Il n’y a en revanche jamais deux instances du serveur de jeu qui écrivent en même temps. - Des dépendances systemd (
After=/Requires=) :wg-quick@wg0→docker→wings, pour que tout revienne seul après un redémarrage.
Lever : une bascule sûre en un clic
Une VM facturée à l’heure n’est rentable que si on l’éteint vraiment, et une bascule manuelle (arrêter, copier, redémarrer, ne rien oublier) est longue et risquée. Lever est un orchestrateur en Go, avec une interface web d’une page, qui pilote l’API de Scaleway, celle de Pelican, et synchronise les fichiers entre les deux hôtes.
Le déroulé d’une bascule
- Allumer la VM, puis attendre les readiness checks : handshake WireGuard, API Wings, ping MongoDB ;
- Pré-synchroniser les fichiers pendant que le serveur tourne encore sur le VPS ;
- Prévenir les joueurs, arrêter le serveur et le confirmer arrêté ;
- Synchronisation finale des derniers changements, vérifiée par un
rsync --dry-run --itemize-changesqui doit revenir vide ; - Démarrer le serveur sur la VM.
Le retour fait l’inverse, puis éteint la VM. Après 20 minutes sans joueur, Lever déclenche le retour de lui-même : un oubli ne coûte que quelques centimes.
Une machine à états qui survit aux plantages
L’état est reconstruit à chaque démarrage depuis les sources de vérité (API Scaleway et Pelican) ; seul active_copy, qui indique quelle instance détient les données les plus récentes, est persisté. Il est écrit de façon atomique (fichier temporaire, fsync, rename) et ne change qu’après une synchronisation vérifiée. Après un plantage en pleine bascule, aucune reprise automatique : Lever montre l’étape interrompue, et chaque étape est idempotente et reprise sur confirmation.
Six invariants, chacun couvert par un test
- Jamais les deux instances actives en même temps ;
- On ne démarre que l’instance à jour ;
- On ne synchronise que depuis l’instance à jour, serveur confirmé arrêté ;
- Source vide ou suppressions au-delà d’un seuil (
rsync --max-delete) : synchronisation refusée ; - Pas de retour sans rapatriement réussi ;
- Pas d’extinction de la VM tant que les données ne sont pas revenues.
Une synchronisation défensive
rsync sur SSH dans le tunnel. Côté VM, la clé est restreinte par command="rrsync …",restrict dans authorized_keys, cantonnée au dossier du serveur, et le known_hosts est épinglé. Wings exécute les serveurs avec un UID différent sur chaque hôte : plutôt que de les aligner de force, Lever transfère avec -rlpt, sans -o/-g ; les fichiers prennent l’UID de l’utilisateur distant, celui de Wings. Aucun accès root n’est nécessaire.
Lever a été développé avec l’agent de code Claude Code, à partir de spécifications que j’ai rédigées : architecture, invariants, tests attendus. Mon rôle a été celui d’architecte et de relecteur : trancher les choix, valider chaque plan avant le code, éprouver le résultat en conditions réelles.
Bilan
| Mesure | Résultat |
|---|---|
| Coût de la puissance supplémentaire, 20 h / mois | ~6,5 € au lieu de ~140 € |
| Coupure pour les joueurs par bascule | ~1 minute |
| Première synchronisation | 1 168 fichiers, 619 Mo |
| Rapatriement après un événement | 114 fichiers, 15,8 Mo, en 1,4 s |
| Modifications du serveur de jeu | Aucune |
Sources des prix
Prix HT relevés en octobre 2026 : OVH Game-1 2026 (139,99 € / mois), Scaleway MEMORY3-X4C-32G (0,2266 € / h) + ~2 € / mois de disque. OVHcloud, serveurs Game · Scaleway, instances virtuelles · Scaleway, facturation des instances éteintes.