Le moyen le plus fiable de maintenir un serveur de jeu en vie est de gérer son processus avec un fichier de service systemd. Les processus lancés en arrière-plan avec screen ou nohup disparaissent au redémarrage du serveur, et personne ne les relance en cas de plantage. systemd, lui, démarre votre processus de jeu automatiquement au boot, le relance après un crash et rend toute sa sortie lisible depuis un seul endroit. Dans cet article, nous transformons un processus de jeu en service systemd de zéro.
Pourquoi utiliser un service systemd ?
Qu'il s'agisse de Metin2, Minecraft, d'un cœur de jeu en C++ ou de votre propre binaire serveur, ce sont tous des processus en arrière-plan qui doivent tourner longtemps. Les lancer directement depuis un terminal pose ces problèmes :
- Le processus meurt à la fermeture de la session SSH.
- Le jeu ne redémarre pas automatiquement après un reboot.
- Un plantage exige une intervention manuelle.
- Les logs sont éparpillés, ce qui complique le suivi des événements.
systemd résout tout cela. C'est le système d'init par défaut des distributions Linux modernes (Debian, Ubuntu, AlmaLinux, Rocky), vous n'avez donc rien d'autre à installer.
Créer un utilisateur dédié au service
Pour des raisons de sécurité, mieux vaut ne pas exécuter le processus de jeu en tant que root. Créez un utilisateur système dédié, sans shell :
sudo useradd --system --create-home --shell /usr/sbin/nologin gameserver
sudo mkdir -p /opt/game
sudo chown -R gameserver:gameserver /opt/game
Placez vos fichiers de jeu sous /opt/game et vérifiez les permissions du binaire exécutable : chmod +x /opt/game/start. Cet utilisateur ne fait qu'exécuter le jeu et ne peut pas se connecter au système, ce qui limite l'impact d'une éventuelle faille de sécurité.
Écrire le fichier de service systemd
Les définitions de service se trouvent dans des fichiers à extension .service sous /etc/systemd/system/. Créez /etc/systemd/system/gameserver.service :
[Unit]
Description=Serveur de jeu
After=network.target
[Service]
Type=simple
User=gameserver
Group=gameserver
WorkingDirectory=/opt/game
ExecStart=/opt/game/start
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
Signification des sections :
- [Unit] —
After=network.targetgarantit que le service ne démarre pas avant que le réseau soit prêt. - Type=simple — Le bon choix quand le processus s'exécute au premier plan (la plupart des serveurs de jeu le font). Si le processus se met lui-même en arrière-plan, utilisez
Type=forking. - WorkingDirectory — Certains cœurs de jeu cherchent leurs fichiers de configuration par rapport au répertoire de travail ; définissez-le toujours.
- ExecStart — La commande complète à exécuter. Utilisez toujours un chemin absolu ; systemd ne suppose pas de
PATH. - Restart=on-failure — Relance le processus s'il se termine avec un code non nul.
RestartSec=5attend 5 secondes avant de relancer. - LimitNOFILE — Augmente la limite de fichiers/sockets ouverts pour gérer de nombreuses connexions de joueurs.
Activer et démarrer le service
Après avoir enregistré le fichier, demandez à systemd de lire la nouvelle définition, puis activez le service au démarrage et lancez-le :
sudo systemctl daemon-reload
sudo systemctl enable gameserver
sudo systemctl start gameserver
Vérifiez l'état :
sudo systemctl status gameserver
Si vous voyez active (running) dans la sortie, le service tourne. La commande enable rattache le service à multi-user.target pour que le jeu revienne à chaque démarrage du serveur. Pour faire les deux en une seule commande, utilisez systemctl enable --now gameserver.
Suivre les logs avec journalctl
systemd collecte la sortie standard et la sortie d'erreur du processus dans journald, vous n'avez donc pas à gérer un fichier de log séparé :
# Afficher les logs récents
sudo journalctl -u gameserver
# Suivre en direct (comme tail)
sudo journalctl -u gameserver -f
# Seulement les logs d'aujourd'hui
sudo journalctl -u gameserver --since today
Si votre cœur de jeu écrit ses propres fichiers de log, ceux-ci restent à leur place ; journald ne capture que ce qui est affiché dans la console. Pour éviter de remplir le disque, envisagez une limite comme SystemMaxUse=500M dans /etc/systemd/journald.conf.
Arrêt propre et erreurs courantes
Beaucoup de serveurs de jeu ont besoin d'un arrêt en douceur pour sauvegarder les données des joueurs. Par défaut, systemd envoie SIGTERM ; idéalement votre processus l'intercepte et se ferme proprement. Ajustez le délai d'attente si nécessaire :
[Service]
TimeoutStopSec=30
KillSignal=SIGINT
Les problèmes les plus fréquents : un mauvais chemin (ExecStart doit être absolu), une erreur de permission (le binaire doit appartenir à l'utilisateur gameserver et être exécutable) et un mauvais Type (utiliser Type=simple pour un processus qui se fork lui-même fait que le service semble « redémarrer » sans cesse). N'oubliez pas d'exécuter sudo systemctl daemon-reload après chaque modification.
Questions fréquentes
Que faire après avoir modifié le service ?
Chaque fois que vous changez le fichier .service, exécutez d'abord sudo systemctl daemon-reload, puis sudo systemctl restart gameserver. Sinon systemd continue d'utiliser l'ancienne définition.
Puis-je lancer plusieurs instances du jeu ?
Oui. Écrivez le même modèle sous forme d'unité template nommée gameserver@.service et lancez des instances comme systemctl start gameserver@1, gameserver@2. Chaque instance reçoit son propre port ou sa propre configuration via la variable %i.
Pourquoi le processus redémarre-t-il sans cesse ?
Cela signifie généralement que le binaire se ferme immédiatement. Lisez le vrai message d'erreur avec journalctl -u gameserver -f ; la cause est souvent un fichier de configuration manquant, un port indisponible ou un mauvais répertoire de travail.
Vous voulez renforcer votre infrastructure serveur ? Si vous avez besoin d'aide pour l'installation d'un serveur de jeu, les services systemd ou l'administration Linux, contactez-moi.