Migrer un serveur EmuLinker Kaillera vers Docker Compose avec network_mode host

Published by David on






EmuLinker en Docker — migration serveur Kaillera vers Docker Compose

EmuLinker en Docker — migration serveur Kaillera vers Docker Compose

Neuvième étape : migrer EmuLinker (serveur Kaillera pour le jeu rétro en ligne)
depuis une installation Java standalone vers Docker Compose, avec conservation de la
configuration et des sessions.

Paramètres à personnaliser

Remplacez chaque {{VARIABLE}} par vos propres valeurs avant d’utiliser ce guide.

Variable Description Exemple
{{IP_ANCIEN}} IP du serveur source 203.0.113.10
{{IP_NOUVEAU}} IP du serveur cible 198.51.100.20
{{HOSTNAME_ANCIEN}} Hostname de l’ancien serveur ns1234567
{{HOSTNAME_NOUVEAU}} Hostname du nouveau serveur ns7654321
{{PORT_SSH_ANCIEN}} Port SSH de l’ancien serveur 22222
{{PORT_SSH_NOUVEAU}} Port SSH du nouveau serveur 22223
{{DOMAINE_GAMING}} Domaine gaming exemple-gaming.fr
{{NOM_SERVEUR_KAILLERA}} Nom affiché dans la master list Mon Serveur Kaillera - Europe
{{TAILLE_DONNEES_PRECEDENT}} Taille données article précédent 50 Go

Contexte

EmuLinker est un serveur Kaillera pour le jeu rétro en ligne. Le protocole Kaillera
permet aux joueurs de jouer à des jeux multijoueur locaux via Internet en utilisant
des émulateurs comme MAME, Project64, ePSXe, ZSNES, Snes9k, et bien d’autres.
Contrairement à d’autres protocoles de jeu en ligne, Kaillera synchronise les entrées
des joueurs en temps réel pour simuler une session de jeu local.

Actuellement, EmuLinker (version originale, classe org.emulinker.kaillera.pico.PicoStarter)
tourne comme un processus Java 11 (OpenJDK 11.0.30) sur l’ancien serveur
dédié ({{IP_ANCIEN}}, {{HOSTNAME_ANCIEN}}) dans /home/emulinker/,
lancé via systemd (emulinker.service).
On migre vers Docker Compose sur le nouveau serveur ({{IP_NOUVEAU}}, {{HOSTNAME_NOUVEAU}},
SSH port {{PORT_SSH_NOUVEAU}}), où tournent déjà Odoo 17, Odoo 8, Akeneo PIM, ownCloud et TeamSpeak 3.

Architecture cible : 1 conteneur Docker (OpenJDK + jar EmuLinker) en mode
network_mode: host pour optimiser la latence UDP.
Les serveurs de jeux Kaillera utilisent plus de 70 ports UDP dynamiques (27886-27944 + 54715-54730).
Le NAT Docker ajoute de la latence sur chaque paquet UDP, ce qui dégrade l’expérience de jeu.
En mode host, le conteneur partage directement le réseau de l’hôte, éliminant cette surcharge.
Domaine : {{DOMAINE_GAMING}}.

1) Identifier l’installation existante

Première étape : se connecter à l’ancien serveur et identifier la version d’EmuLinker,
la version Java, la structure des fichiers, et le mode de lancement.

Notre installation : c’est l’EmuLinker original (pas un fork K, SF ou X).
Le serveur est lancé avec un classpath complexe incluant 13 jars de dépendances
dans lib/, et la configuration est dans emulinker.cfg à la racine
(pas dans conf/). Le répertoire conf/ est inclus dans le classpath
pour access.cfg et la configuration log4j.

1.1 Résumé de l’installation

Résumé de notre installation :

  • Version : EmuLinker original (org.emulinker.kaillera.pico.PicoStarter)
  • Runtime : OpenJDK 11.0.30 (image Docker : eclipse-temurin:11-jre)
  • JVM : -Xms64m -Xmx128m
  • Configuration principale : emulinker.cfg (à la racine, pas dans conf/)
  • Configuration accès : conf/access.cfg
  • Lancement : classpath complexe avec 13 jars dans lib/
  • Service : emulinker.service (systemd, enabled)
  • Port principal : 27888 (Kaillera standard)
  • Ports jeux : 27886-27944 (UDP dynamique)
  • Ports P2P : 54715-54730 (UDP peer-to-peer)
  • Domaine : {{DOMAINE_GAMING}}
  • Nom serveur : {{NOM_SERVEUR_KAILLERA}}
  • Utilisateur système : emulinker
  • Répertoire : /home/emulinker/
  • Max joueurs : 100

1.2 Fichiers critiques à préserver

  • lib/emulinker.jar + 13 jars de dépendances dans lib/
    (commons-collections, commons-configuration, commons-lang, commons-logging,
    dom4j, log4j, picocontainer, etc.)
  • emulinker.cfg — configuration principale du serveur (nom, ports,
    master list, limites de connexion, messages)
  • conf/access.cfg — règles d’accès et permissions
  • conf/log4j.xml — configuration des logs (si présent dans le classpath)
  • wordlist.txt, questions.txt — listes pour les mini-jeux intégrés
  • scores.txt, scores_scrambler.txt — scores des joueurs
  • launch.sh — script de lancement (pour référence, remplacé par Docker)

2) Créer la structure des répertoires Docker

Sur le nouveau serveur :

  • server/ — contiendra tous les fichiers EmuLinker (jar, configuration, logs)
  • backup/ — pour stocker les sauvegardes avant migration

3) Transférer les fichiers depuis l’ancien serveur

Depuis le nouveau serveur :

EmuLinker est extrêmement léger comparé à TeamSpeak (quelques Mo contre {{TAILLE_DONNEES_PRECEDENT}}).
Le transfert devrait prendre quelques secondes seulement.

4) Créer le docker-compose.yml

Contenu :

Points clés :

  • eclipse-temurin:11-jre — correspond à l’OpenJDK 11 utilisé sur l’ancien serveur
  • network_mode: host — le conteneur partage directement le réseau de l’hôte,
    pas de NAT Docker. Optimal pour les serveurs de jeux avec beaucoup de ports UDP
  • command — reproduit le classpath complexe du launch.sh original :
    le répertoire conf/ + tous les jars dans lib/ via le wildcard ./lib/*
  • ./server:/opt/emulinker — tout le répertoire EmuLinker monté dans le conteneur

Classpath Java : EmuLinker ne se lance pas avec un simple java -jar.
Il nécessite un classpath qui inclut conf/ (pour access.cfg et log4j)
et les 13 jars de lib/. Le wildcard ./lib/* fonctionne avec Java 6+
et évite de lister chaque jar individuellement (comme le faisait le launch.sh original).
La classe principale est org.emulinker.kaillera.pico.PicoStarter.

Mode réseau host : network_mode: host signifie que le conteneur
partage directement le réseau de l’hôte. Pas besoin de mapper les ports individuellement
— tous les ports sur lesquels EmuLinker écoute sont directement accessibles.
C’est le choix optimal pour les serveurs de jeux avec beaucoup de ports UDP
(27886-27944 + 54715-54730 = plus de 70 ports), car le NAT Docker ajoute de la latence
sur les paquets UDP, ce qui dégrade l’expérience de jeu.

5) Adapter la configuration EmuLinker

Après le transfert, certains paramètres de configuration doivent être mis à jour
pour refléter le nouveau serveur.

Modification obligatoire — adresse IP du serveur :

Critique : si masterList.serverConnectAddress n’est pas mis à jour,
les serveurs master list Kaillera continueront de pointer les joueurs vers l’ancienne IP.
Le serveur apparaîtra dans la liste publique mais les connexions échoueront.

Autres paramètres à vérifier (normalement OK sans modification) :

  • masterList.serverName={{NOM_SERVEUR_KAILLERA}} — nom affiché dans la liste publique
  • masterList.serverWebsite=http://{{DOMAINE_GAMING}} — site web du serveur
  • server.port=27888 — port principal Kaillera (ne pas changer)
  • server.maxUsers=100 — limite de joueurs simultanés
  • server.maxGames=50 — limite de parties simultanées

Configuration accès : le fichier conf/access.cfg contient les règles
d’accès (bans, admins, etc.). Il est transféré automatiquement avec le rsync de l’étape 3
et ne nécessite normalement aucune modification.

Serveurs master list Kaillera : les IPs 216.189.101.117 et
50.203.71.60 sont les serveurs master list Kaillera historiques
(anti3d.com et kaillera.com). Ils permettent aux joueurs de trouver votre serveur
dans la liste publique des clients Kaillera. Si votre serveur est privé
(connexion directe par IP/domaine), ces règles firewall ne sont pas strictement nécessaires.

6) Vérifier les règles firewall

Les règles firewall sont déjà configurées sur le nouveau serveur via MyVestaCP.
Vérifions qu’elles sont bien en place :

Résultat attendu :

Explication des règles :

  • Emulinker-Master-List / Master-List-2 — TCP port 80 restreint aux IPs
    des serveurs master list Kaillera (216.189.101.117 et 50.203.71.60). Permet à ces serveurs
    de vérifier que notre serveur est en ligne et de l’afficher dans la liste publique
  • Emulinker-Classic-Kaillera — UDP 27888 (port principal) + 27889-27944
    (ports de jeu dynamiques) — ouverts à tous pour que les joueurs puissent se connecter
  • Emulinker-p2p — UDP 27886-27887 + 54715-54730 — ports pour le mode
    peer-to-peer, permettant le jeu direct entre joueurs sans transiter par le serveur

Règles déjà en place : les règles firewall sont déjà en place
sur le nouveau serveur. Si ce n’est pas le cas, les ajouter via MyVestaCP CLI :

Format des commentaires MyVestaCP : les commentaires ne doivent pas contenir
d’espaces. Utiliser des tirets (Emulinker-Kaillera-Main) au lieu d’espaces
(Emulinker Kaillera Main), sinon l’erreur
Error: invalid comment format apparaît.

7) Arrêter l’ancien serveur

Avant de démarrer le nouveau serveur Docker, arrêter l’ancien pour éviter
les conflits de port et de master list :

Si la dernière commande ne retourne rien, le port est bien libéré.

8) Démarrer EmuLinker en Docker

Retour sur le nouveau serveur :

Vérifier que le conteneur est en cours d’exécution :

Vérifier que le port 27888 est bien en écoute :

Résultat attendu :

Redémarrage en boucle : si le conteneur redémarre en boucle,
vérifier les logs : docker compose logs --tail=100.
Les causes les plus fréquentes sont : mauvais nom de jar dans command,
version Java incompatible, ou fichier de configuration manquant.

9) Tester la connexion

Tester que les ports sont bien accessibles depuis l’extérieur :

Test avec un client Kaillera :

  1. Ouvrir un émulateur compatible Kaillera (MAME, Project64, ePSXe avec plugin Kaillera, ZSNES, Snes9k, etc.)
  2. Dans le client Kaillera, ajouter le serveur manuellement : {{IP_NOUVEAU}}:27888
  3. Ou une fois le DNS mis à jour : {{DOMAINE_GAMING}}:27888
  4. Vérifier que le serveur apparaît et que la connexion fonctionne
  5. Tenter de créer une salle de jeu et de démarrer une partie pour valider le fonctionnement complet

Master list publique : si le serveur est enregistré sur la master list Kaillera,
il devrait apparaître automatiquement dans la liste publique du client après quelques minutes
(une fois que les serveurs master list ont détecté le nouveau serveur).

10) Désactiver définitivement l’ancien serveur

Une fois la migration validée :

DNS partagé : le domaine {{DOMAINE_GAMING}} est partagé entre
TeamSpeak (port 9988) et EmuLinker (port 27888). Si l’enregistrement A a déjà été
mis à jour pour TeamSpeak (vers {{IP_NOUVEAU}}), EmuLinker en bénéficie
automatiquement. Les joueurs pourront se connecter via {{DOMAINE_GAMING}}:27888.


Dépannage

EmuLinker ne démarre pas : « ClassNotFoundException » ou « NoClassDefFoundError »

Cause : le classpath dans command ne trouve pas les classes nécessaires.

EmuLinker ne démarre pas : « UnsupportedClassVersionError »

Cause : la version Java dans l’image Docker ne correspond pas.
Notre installation utilise Java 11 (eclipse-temurin:11-jre).

Le serveur n’apparaît pas dans la master list

Causes possibles :

  • Les règles firewall TCP port 80 pour les IPs master list ne sont pas actives
  • La configuration EmuLinker ne contient pas les bonnes URLs de master list
  • Les serveurs master list Kaillera sont hors ligne (ce sont des infrastructures anciennes, parfois instables)

Les joueurs ne peuvent pas se connecter

Latence élevée en jeu

Causes possibles :

  • Le mode network_mode: host n’est pas activé (le NAT Docker ajoute de la latence)
  • Le serveur est surchargé (CPU/RAM)
  • Problème réseau entre les joueurs et le serveur

Sensibilité à la latence : le protocole Kaillera est très sensible
à la latence. Le mode network_mode: host minimise la surcharge réseau
en évitant le NAT Docker. Si la latence reste élevée malgré cette configuration,
le problème vient probablement de la distance géographique entre les joueurs
ou de la qualité de leur connexion Internet.


Récapitulatif de l’architecture finale

Liste complète des ports utilisés :

  • 8069/8169/8269/8369 — Odoo 17 (via reverse proxy)
  • 8469 — Odoo 8 (via reverse proxy)
  • 8480 — Akeneo PIM (via reverse proxy)
  • 8490 — ownCloud (via reverse proxy)
  • 9987/udp + 9988/udp — TeamSpeak 3 voix (direct)
  • 10011/tcp — TeamSpeak 3 ServerQuery (localhost seulement)
  • 30033/tcp — TeamSpeak 3 transfert fichiers (direct)
  • 27886-27944/udp — EmuLinker Kaillera (direct, host network)
  • 54715-54730/udp — EmuLinker P2P (direct, host network)

À suivre

EmuLinker est maintenant opérationnel en Docker avec une configuration optimisée
pour la latence minimale (mode host network).
Dans les prochains articles :

  • Counter-Strike 1.6 en Docker — migration du serveur de jeu CS 1.6
  • Sauvegardes automatisées — stratégie de backup pour tous les services Docker
  • Monitoring et alertes — surveillance centralisée des conteneurs

Article précédent : TeamSpeak 3 en Docker — migration serveur vocal avec {{TAILLE_DONNEES_PRECEDENT}} de fichiers.



Catégories : Non classé

0 commentaire

Laisser un commentaire

Emplacement de l’avatar

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *