TeamSpeak 3 en Docker — migrer un serveur vocal standalone vers Docker Compose
TeamSpeak 3 en Docker — migration serveur vocal avec {{TAILLE_DONNEES}} de fichiers
Huitième étape : migrer TeamSpeak 3.13.7 ({{TAILLE_DONNEES}} de fichiers transférés, base SQLite,
licence payante) depuis une installation standalone vers Docker Compose sur le serveur
centralisé, avec transfert progressif rsync.
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_TS}} |
Domaine TeamSpeak | exemple-gaming.fr |
{{SERVERQUERY_PASSWORD}} |
Mot de passe admin ServerQuery | MyS3cur3P@ss! |
{{USER_VESTA}} |
Utilisateur MyVestaCP | admin |
{{TAILLE_DONNEES}} |
Taille des fichiers transférés | 50 Go |
{{TAILLE_DONNEES_PRECEDENT}} |
Taille données article précédent | 100 Go |
Contexte
Le serveur TeamSpeak 3 tourne actuellement sur l’ancien serveur dédié
({{IP_ANCIEN}}, {{HOSTNAME_ANCIEN}}) sous le chemin /home/teamspeak3/,
en tant qu’utilisateur système teamspeak3 via un service systemd.
Il utilise une base SQLite (~4,5 Mo), stocke {{TAILLE_DONNEES}}
de fichiers transférés par les utilisateurs (icônes, avatars, fichiers de channels),
et possède une licence payante (licensekey.dat).
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 et ownCloud.
Architecture cible : 2 conteneurs —
teamspeak:3.13.7 (serveur vocal, ports exposés directement)
et joni1802/ts3-manager (interface web d’administration via reverse proxy Nginx).
Différence clé avec les applications web :
contrairement à Odoo, Akeneo ou ownCloud, TeamSpeak n’utilise pas
de reverse proxy Nginx. Les clients se connectent directement via UDP (voix)
et TCP (transfert de fichiers, query). Les ports doivent donc être ouverts
dans le firewall du serveur.
Stratégie rsync 2 passes : avec {{TAILLE_DONNEES}} de fichiers sur HDD,
un transfert complet prend plusieurs heures. On fait un premier rsync pendant
que l’ancien serveur est encore en production (aucune interruption du vocal),
puis un second rsync rapide (delta seulement) après l’arrêt du serveur.
Fenêtre de coupure réduite à quelques minutes au lieu de plusieurs heures.
1) Collecter les informations sur l’ancien serveur
1.1 Version et processus
|
1 2 3 4 5 |
# Version /home/teamspeak3/ts3server version # Processus en cours ps aux | grep ts3 |
Résultat attendu : TeamSpeak 3 Server 3.13.7 (2022-06-20 12:21:53).
1.2 Ports utilisés
|
1 |
ss -tlnup | grep -E '9987|10011|30033|8767|10044|30034' |
Vérifier les ports réels : le fichier ts3server.ini
de notre serveur contient des ports personnalisés (8767, 10044,
30034), mais le serveur écoute en réalité sur les ports standards
(9987, 10011, 30033).
Cette incohérence peut venir du fait que le fichier ini n’est pas chargé
ou que la base de données prévaut sur la configuration ini pour les serveurs virtuels existants.
Vérifier avec ss quels ports sont réellement utilisés
et les noter — ce sont ceux que les clients TeamSpeak utilisent.
1.3 Contenu du fichier de configuration
|
1 |
cat /home/teamspeak3/ts3server.ini |
1.4 Taille des données
|
1 2 3 4 5 |
# Base de données SQLite ls -lh /home/teamspeak3/ts3server.sqlitedb # Fichiers transférés (icônes, avatars, fichiers de channels) sudo du -sh /home/teamspeak3/files/ |
Résumé de notre installation :
- Version : TeamSpeak 3 Server 3.13.7
- Base de données : SQLite (
ts3server.sqlitedb, ~4,5 Mo) - Fichiers transférés : {{TAILLE_DONNEES}} dans
/home/teamspeak3/files/ - Licence : payante (
licensekey.dat) - Identité serveur :
serverkey.dat - Ports actifs : UDP
9987+9988(voix, 2 serveurs virtuels), TCP10011(query), TCP30033(transfert fichiers) - Domaine :
{{DOMAINE_TS}}(port 9988) - Utilisateur système :
teamspeak3 - Service systemd :
teamspeak3.service
1.5 Fichiers critiques à préserver
ts3server.sqlitedb— la base de données complète (utilisateurs, channels, permissions, bans, tokens)serverkey.dat— identité cryptographique du serveur.
Sans ce fichier, le serveur apparaît comme un NOUVEAU serveur pour tous les clients.
Les favoris/bookmarks ne fonctionnent pluslicensekey.dat— licence payante TeamSpeak. Sans elle, le serveur repasse en licence gratuite (limité à 32 slots)ssh_host_rsa_key— clé SSH pour les connexions ServerQuery via SSH (optionnel mais pratique)files/— tous les fichiers transférés dans les channels ({{TAILLE_DONNEES}})query_ip_whitelist.txt— IPs autorisées pour ServerQuery
serverkey.dat est irremplaçable. Il contient la clé privée
qui génère l’identité unique du serveur. Si ce fichier est perdu, le serveur
aura une nouvelle identité et tous les clients recevront un avertissement
« Server identity changed » et devront re-valider la connexion.
Les bookmarks avec « Connect only to known servers » refuseront de se connecter.
Phase 1 : Préparation (ancien serveur en production)
Toutes les étapes suivantes se font sans interrompre le serveur vocal.
Les utilisateurs continuent à parler normalement.
2) Créer la structure des répertoires Docker
Sur le nouveau serveur :
|
1 2 |
mkdir -p /home/docker/teamspeak3/data mkdir -p /home/docker/teamspeak3/backup |
Docker Compose v2 : si Docker Compose v2 est déjà installé (vérifier avec
docker compose version), pas besoin de le réinstaller.
3) Créer le docker-compose.yml
|
1 |
nano /home/docker/teamspeak3/docker-compose.yml |
Contenu :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
services: teamspeak: image: teamspeak:3.13.7 container_name: teamspeak3-server restart: always ports: - "9987:9987/udp" - "9988:9988/udp" - "30033:30033" - "10011:10011" environment: TS3SERVER_LICENSE: accept volumes: - ./data:/var/ts3server networks: - teamspeak-network ts3-manager: image: joni1802/ts3-manager container_name: ts3-manager restart: always ports: - "127.0.0.1:8080:8080" environment: - JWT_SECRET=<votre_secret_jwt> - WHITELIST=teamspeak,{{IP_NOUVEAU}} networks: - teamspeak-network networks: teamspeak-network: name: teamspeak-network |
Points clés :
teamspeak:3.13.7— image Docker officielle TeamSpeak, même version que l’ancien serveur
pour éviter les problèmes de compatibilité de base de données9987:9987/udp— port voix du serveur virtuel 1, exposé en UDP sur toutes les interfaces9988:9988/udp— port voix du serveur virtuel 2 ({{DOMAINE_TS}}:9988)30033:30033— port transfert de fichiers, exposé en TCP10011:10011— port ServerQuery, exposé sur toutes les interfaces
pour permettre le monitoring LGSL depuis l’hôte. Protégé par la whitelist
TeamSpeak (query_ip_whitelist.txt) et le firewall VestaCPTS3SERVER_LICENSE: accept— acceptation automatique de la licence (obligatoire depuis TS 3.1.0)./data:/var/ts3server— bind mount pour la base SQLite, les fichiers transférés ({{TAILLE_DONNEES}}),
la licence et l’identité serveur
TS3 Manager :
joni1802/ts3-manager— interface web d’administration TeamSpeak (ts3.app)127.0.0.1:8080:8080— port web restreint à localhost, accès via reverse proxy NginxWHITELIST— autorise les connexions ServerQuery vers le conteneurteamspeak
(nom DNS Docker) et l’IP du serveur hôteteamspeak-network— réseau Docker partagé permettant à TS3 Manager
d’atteindre le port ServerQuery (10011) du conteneur TeamSpeak par son nom de service
Pas de serveradmin_password dans le docker-compose.
L’ancien serveur passait serveradmin_password={{SERVERQUERY_PASSWORD}} en paramètre de démarrage,
ce qui réinitialise le mot de passe admin à chaque redémarrage.
Après migration, le mot de passe est stocké dans la base SQLite importée.
Il n’est plus nécessaire (ni souhaitable) de le passer en paramètre —
il serait visible dans la liste des processus (ps aux).
Port ServerQuery (10011) exposé sur toutes les interfaces :
le port 10011 est ouvert pour permettre le monitoring LGSL depuis le serveur hôte
(PHP tourne sur l’IP publique, pas sur 127.0.0.1). La sécurité est assurée par :
(1) la whitelist TeamSpeak (query_ip_whitelist.txt limitée à 127.0.0.1,
::1 et {{IP_NOUVEAU}}),
(2) le firewall VestaCP qui ne laisse pas passer le port 10011 depuis l’extérieur.
Ne jamais ouvrir le port 10011 dans le firewall.
4) Lancer le rsync initial (en arrière-plan)
Cette étape est la plus longue (plusieurs heures pour {{TAILLE_DONNEES}}).
On la lance pendant que l’ancien serveur est encore en production —
les utilisateurs continuent à utiliser le vocal normalement.
4.1 Préparer l’accès SSH
Depuis le nouveau serveur :
|
1 2 3 |
# Si pas encore fait pour les migrations précédentes ssh-keygen -t ed25519 -C "migration-teamspeak" ssh-copy-id -p {{PORT_SSH_ANCIEN}} root@{{IP_ANCIEN}} |
4.2 Lancer le premier rsync
Depuis le nouveau serveur :
|
1 2 3 4 5 6 7 8 9 10 |
# Lancer dans un screen pour ne pas perdre le transfert screen -S rsync-teamspeak # Rsync initial : copie complète des fichiers transférés ({{TAILLE_DONNEES}}) rsync -avt --progress -e "ssh -p {{PORT_SSH_ANCIEN}}" \ root@{{IP_ANCIEN}}:/home/teamspeak3/files/ \ /home/docker/teamspeak3/data/files/ # Détacher le screen : Ctrl+A puis D # Rattacher plus tard : screen -r rsync-teamspeak |
Estimation de durée : entre serveurs OVH (réseau interne ~1 Gbps),
{{TAILLE_DONNEES}} prennent environ 1h à 2h30.
Le flag -t préserve les timestamps des fichiers.
Pas de risque de corruption : les fichiers dans files/
sont des fichiers statiques (uploads des utilisateurs dans les channels).
Ils ne sont jamais modifiés après l’upload, seulement ajoutés ou supprimés.
Le rsync pendant que le serveur tourne est donc sans risque.
Phase 2 : Basculement (fenêtre de coupure)
À partir d’ici, le serveur vocal est interrompu.
Objectif : terminer en 5 à 10 minutes
(la base SQLite fait seulement 4,5 Mo, le rsync delta est très rapide).
5) Arrêter TeamSpeak sur l’ancien serveur
|
1 2 3 4 5 6 |
# Sur l'ancien serveur sudo systemctl stop teamspeak3 # Vérifier qu'il est bien arrêté sudo systemctl status teamspeak3 ps aux | grep ts3 |
Prévenir les utilisateurs avant l’arrêt.
On peut envoyer un message global depuis ServerQuery avant la coupure :
|
1 2 3 |
# Optionnel : prévenir les utilisateurs connectés # (depuis l'ancien serveur, avant l'arrêt) echo -e "login serveradmin {{SERVERQUERY_PASSWORD}}\nuse sid=1\nsendtextmessage targetmode=3 target=1 msg=Maintenance\\sen\\scours\\s-\\smigration\\sdu\\sserveur.\\sReconnexion\\sdans\\s10\\sminutes." | nc 127.0.0.1 10011 |
6) Rsync final + fichiers critiques
Depuis le nouveau serveur :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# Rsync final des fichiers (delta uniquement, très rapide) rsync -avt --delete --progress -e "ssh -p {{PORT_SSH_ANCIEN}}" \ root@{{IP_ANCIEN}}:/home/teamspeak3/files/ \ /home/docker/teamspeak3/data/files/ # Copier la base de données SQLite rsync -avt -e "ssh -p {{PORT_SSH_ANCIEN}}" root@{{IP_ANCIEN}}:/home/teamspeak3/ts3server.sqlitedb \ /home/docker/teamspeak3/data/ # Copier les fichiers critiques (identité, licence, clés) rsync -avt -e "ssh -p {{PORT_SSH_ANCIEN}}" root@{{IP_ANCIEN}}:/home/teamspeak3/serverkey.dat \ /home/docker/teamspeak3/data/ rsync -avt -e "ssh -p {{PORT_SSH_ANCIEN}}" root@{{IP_ANCIEN}}:/home/teamspeak3/licensekey.dat \ /home/docker/teamspeak3/data/ rsync -avt -e "ssh -p {{PORT_SSH_ANCIEN}}" root@{{IP_ANCIEN}}:/home/teamspeak3/ssh_host_rsa_key \ /home/docker/teamspeak3/data/ rsync -avt -e "ssh -p {{PORT_SSH_ANCIEN}}" root@{{IP_ANCIEN}}:/home/teamspeak3/query_ip_whitelist.txt \ /home/docker/teamspeak3/data/ |
Arrêter le serveur AVANT de copier la base SQLite.
Les fichiers ts3server.sqlitedb-shm et ts3server.sqlitedb-wal
(shared memory + write-ahead log) contiennent des données non encore écrites dans le fichier
principal. Copier la base pendant que le serveur tourne peut donner une base corrompue.
Après l’arrêt propre (systemctl stop), le WAL est flushé dans le fichier principal.
Ne PAS copier les fichiers -shm et -wal :
après un arrêt propre du serveur, ces fichiers sont vides ou inexistants.
Le fichier ts3server.sqlitedb seul est suffisant.
6.1 Vérifier les fichiers copiés
|
1 2 |
ls -la /home/docker/teamspeak3/data/ ls -la /home/docker/teamspeak3/data/files/ | head -10 |
On doit voir :
ts3server.sqlitedb(~4,5 Mo)serverkey.dat(112 octets)licensekey.dat(~1,6 Ko)ssh_host_rsa_keyquery_ip_whitelist.txtfiles/(répertoire avec les sous-dossiersvirtualserver_1/, etc.)
7) Corriger les permissions
L’image Docker officielle teamspeak s’exécute en tant qu’utilisateur
ts3server. Il faut que tous les fichiers lui appartiennent.
7.1 Déterminer l’UID du conteneur
|
1 2 |
# Démarrer temporairement le conteneur pour vérifier l'UID docker run --rm teamspeak:3.13.7 id |
Noter le uid affiché (typiquement 1000).
7.2 Appliquer les permissions
|
1 2 |
# Adapter l'UID si différent de 1000 chown -R 1000:1000 /home/docker/teamspeak3/data/ |
Cette commande prend du temps sur {{TAILLE_DONNEES}} de fichiers (5-15 minutes sur HDD).
C’est une opération unique.
8) Ouvrir les ports dans le firewall
Contrairement aux applications web (routées via le reverse proxy Nginx de MyVestaCP),
TeamSpeak a besoin que ses ports soient ouverts directement dans le firewall du serveur.
8.1 Ajouter les règles dans MyVestaCP
|
1 2 3 4 5 6 7 8 9 |
# Ports voix (UDP) - 2 serveurs virtuels /usr/local/vesta/bin/v-add-firewall-rule ACCEPT 0.0.0.0/0 9987 UDP TeamSpeak-Voice1 /usr/local/vesta/bin/v-add-firewall-rule ACCEPT 0.0.0.0/0 9988 UDP TeamSpeak-Voice2 # Port transfert de fichiers (TCP) /usr/local/vesta/bin/v-add-firewall-rule ACCEPT 0.0.0.0/0 30033 TCP TeamSpeak-FileTransfer # Appliquer les règles /usr/local/vesta/bin/v-update-firewall |
Ces commandes sont l’équivalent CLI de MyVestaCP → Firewall → Add Rule.
Les règles sont stockées dans /usr/local/vesta/data/firewall/
et persistent après un redémarrage.
8.2 Vérifier que les règles sont actives
|
1 2 |
# Vérifier les règles iptables générées par MyVestaCP iptables -L INPUT -n | grep -E '9987|9988|30033' |
On doit voir :
|
1 2 3 |
ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:9987 ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:9988 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:30033 |
Port 10011 (ServerQuery) : pas besoin de l’ouvrir dans le firewall.
Il est déjà restreint à 127.0.0.1 dans le docker-compose
et dans la whitelist TeamSpeak. L’administration se fait uniquement depuis le serveur.
Ne pas ajouter les règles via iptables directement.
MyVestaCP stocke ses règles dans /usr/local/vesta/data/firewall/
et les régénère via v-update-firewall.
Toute règle ajoutée manuellement sera perdue au prochain redémarrage de VestaCP
ou lors d’un v-update-firewall.
9) Démarrer TeamSpeak
|
1 2 |
cd /home/docker/teamspeak3/ docker compose up -d |
Vérifier l’état du conteneur :
|
1 |
docker compose ps |
Le conteneur doit être en état Up.
Consulter les logs :
|
1 |
docker compose logs teamspeak |
On doit voir :
|
1 2 3 4 5 6 |
TeamSpeak 3 Server 3.13.7 Using SQLite database plugin Listening on 0.0.0.0:9987, [::]:9987 FileTransfer listener listening on 0.0.0.0:30033, [::]:30033 ServerQuery listener listening on 0.0.0.0:10011, [::]:10011 Server started |
Si le serveur affiche « Server created » au lieu de « Server started »,
cela signifie que la base de données n’a pas été trouvée et le serveur a créé
une nouvelle instance vierge. Vérifier que ts3server.sqlitedb est bien
dans /home/docker/teamspeak3/data/ et que les permissions sont correctes.
10) Tester
10.1 Tester le ServerQuery
|
1 2 |
# Depuis le serveur (localhost) echo "version" | nc 127.0.0.1 10011 |
Réponse attendue :
|
1 2 3 4 |
TS3 Welcome to the TeamSpeak 3 ServerQuery interface... version=3.13.7 build=... platform=Linux error id=0 msg=ok |
10.2 Tester la connectivité UDP (voix)
|
1 2 |
# Depuis une machine externe nc -zuv {{IP_NOUVEAU}} 9987 |
Doit afficher Connection to {{IP_NOUVEAU}} 9987 port [udp/*] succeeded!
(ou open).
10.3 Se connecter avec le client TeamSpeak
Ouvrir le client TeamSpeak 3 et se connecter à {{IP_NOUVEAU}} (port par défaut 9987).
Vérifier :
- Les channels sont présents avec leur hiérarchie
- Les permissions et groupes de serveur sont intacts
- Les icônes de channels et de groupes s’affichent
- Les fichiers dans les channels sont accessibles (onglet « Files »)
- Le micro et le son fonctionnent
10.4 Vérifier la licence
|
1 2 |
# Vérifier que la licence est bien chargée echo -e "login serveradmin {{SERVERQUERY_PASSWORD}}\nserverinfo" | nc 127.0.0.1 10011 | grep -i licen |
Si la licence n’est pas détectée, le serveur sera limité à 32 slots.
Vérifier que licensekey.dat est bien dans /home/docker/teamspeak3/data/.
11) Mettre un serveur TeamSpeak de migration sur l’ancien serveur
Rediriger les utilisateurs vers la nouvelle IP.
Avant de couper l’ancien serveur, il est recommandé de lancer un serveur TeamSpeak
temporaire (« trash ») sur l’ancienne IP ({{IP_ANCIEN}})
qui affiche un message de migration indiquant la nouvelle IP.
Ainsi, les utilisateurs qui se connectent encore à l’ancienne adresse
voient immédiatement où aller.
En mode gratuit (sans licence), TeamSpeak limite à 1 serveur virtuel
et 32 slots par instance. Pour couvrir les deux ports (9987 et 9988),
il faut lancer deux instances séparées du binaire ts3server,
chacune avec sa propre base de données, ses propres ports et son propre utilisateur système.
Pourquoi deux utilisateurs système ?
TeamSpeak utilise un fichier de verrouillage dans /dev/shm/ pour empêcher
de lancer deux instances sans licence sur la même machine. Le paramètre
machine_id ne suffit pas à contourner ce verrou dans la version 3.13.7.
La solution : isoler le /dev/shm de la seconde instance via
TemporaryFileSystem=/dev/shm dans le service systemd.
12) Désactiver l’ancien serveur
Une fois la migration validée, empêcher l’ancien serveur de redémarrer :
|
1 2 3 |
# Sur l'ancien serveur sudo systemctl disable teamspeak3 sudo systemctl stop teamspeak3 |
Bascule DNS : mettre à jour l’enregistrement A de {{DOMAINE_TS}}
pour qu’il pointe vers {{IP_NOUVEAU}} (au lieu de l’ancien serveur).
Les clients qui se connectent via {{DOMAINE_TS}}:9988 seront automatiquement redirigés.
13) TS3 Manager — interface web d’administration
TS3 Manager (v2.2.5) est une interface web légère
pour administrer TeamSpeak 3 via le protocole ServerQuery. Il permet de gérer
les utilisateurs, channels, permissions, bans et groupes depuis un navigateur.
L’application est stateless (pas de base de données propre).
13.1 Prérequis
- Le service
ts3-managerest déjà défini dans ledocker-compose.yml(section 3) - Un sous-domaine (ex.
ts3.{{DOMAINE_TS}}) avec enregistrement DNS A vers{{IP_NOUVEAU}}
13.2 Créer le template Nginx reverse proxy dans VestaCP
TS3 Manager utilise des WebSockets. On crée un template réutilisable pour
tout reverse proxy sur le port 8080 :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# Template HTTP cat > /usr/local/vesta/data/templates/web/nginx/reverse-proxy-8080.tpl << 'EOF' server { listen %ip%:%web_port%; server_name %domain_idn% %alias_idn%; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 600s; proxy_send_timeout 600s; proxy_connect_timeout 75s; proxy_buffering off; proxy_request_buffering off; # WebSocket proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } EOF # Template HTTPS (même contenu avec SSL) cat > /usr/local/vesta/data/templates/web/nginx/reverse-proxy-8080.stpl << 'EOF' server { listen %ip%:%web_ssl_port% ssl; server_name %domain_idn% %alias_idn%; ssl_certificate %ssl_pem%; ssl_certificate_key %ssl_key%; ssl_stapling on; ssl_stapling_verify on; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_read_timeout 600s; proxy_send_timeout 600s; proxy_connect_timeout 75s; proxy_buffering off; proxy_request_buffering off; # WebSocket proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } EOF |
13.3 Créer le domaine et appliquer le template
|
1 2 3 4 5 6 7 8 9 10 11 |
# Ajouter le domaine dans VestaCP v-add-web-domain {{USER_VESTA}} ts3.{{DOMAINE_TS}} # Appliquer le template reverse proxy v-change-web-domain-proxy-tpl {{USER_VESTA}} ts3.{{DOMAINE_TS}} reverse-proxy-8080 # Ajouter le certificat SSL Let's Encrypt v-add-letsencrypt-domain {{USER_VESTA}} ts3.{{DOMAINE_TS}} # Tester et recharger Nginx nginx -t && systemctl reload nginx |
13.4 Se connecter à TS3 Manager
Accéder à https://ts3.{{DOMAINE_TS}} et renseigner :
- Server :
teamspeak(nom du service Docker, pas l’IP) - Port :
10011 - SSH : décoché (ServerQuery utilise telnet)
- Name :
serveradmin - Password : le mot de passe serveradmin (stocké dans la base SQLite)
TS3 Manager se connecte via le réseau Docker interne (teamspeak-network).
Il utilise le nom de service teamspeak pour atteindre le port 10011 du conteneur,
sans passer par le réseau de l’hôte. C’est pourquoi le champ Server est teamspeak
et non 127.0.0.1 ou l’IP publique.
Dépannage
Le serveur crée une nouvelle instance au lieu de charger l’ancienne
Les logs affichent « Server created » et un nouveau token admin est généré.
Diagnostiquer :
|
1 2 3 4 5 |
# Vérifier que la base est présente dans le bon répertoire ls -la /home/docker/teamspeak3/data/ts3server.sqlitedb # Vérifier les permissions (doit appartenir à l'UID du conteneur) docker compose exec teamspeak ls -la /var/ts3server/ts3server.sqlitedb |
Cause : la base SQLite n’est pas au bon emplacement
ou n’est pas lisible par l’utilisateur du conteneur.
Corriger les permissions : chown 1000:1000 /home/docker/teamspeak3/data/ts3server.sqlitedb.
Licence non détectée (limité à 32 slots)
Vérifier que licensekey.dat est dans le répertoire de données :
|
1 2 |
ls -la /home/docker/teamspeak3/data/licensekey.dat docker compose exec teamspeak ls -la /var/ts3server/licensekey.dat |
Si le fichier est présent mais la licence n’est pas chargée, vérifier
les logs pour des erreurs de lecture. Redémarrer le conteneur après avoir
corrigé les permissions.
Impossible de se connecter en UDP (voix)
Diagnostiquer :
|
1 2 3 4 5 |
# Vérifier que le port est bien ouvert ss -ulnp | grep 9987 # Vérifier le firewall iptables -L INPUT -n | grep 9987 |
Cause fréquente : le firewall bloque le port UDP 9987.
Ajouter la règle (section 8) et vérifier qu’elle n’est pas écrasée par MyVestaCP.
Transfert de fichiers échoue
Les fichiers ne se téléchargent pas ou ne s’uploadent pas.
|
1 2 3 4 5 6 |
# Vérifier que le port 30033 est ouvert ss -tlnp | grep 30033 iptables -L INPUT -n | grep 30033 # Vérifier les permissions du répertoire files docker compose exec teamspeak ls -la /var/ts3server/files/ |
Erreur database is locked dans les logs
Vérifier qu’il n’y a pas de fichiers -shm ou -wal résiduels :
|
1 |
ls -la /home/docker/teamspeak3/data/ts3server.sqlitedb* |
Si les fichiers -shm et -wal existent et sont non vides,
la base a été copiée pendant que le serveur tournait encore.
Recopié la base après arrêt propre du serveur (section 6).
Perte de données après docker compose run
NE JAMAIS utiliser docker compose run avec TeamSpeak.
Cette commande crée un conteneur éphémère avec un volume temporaire.
TeamSpeak détecte l’absence de base de données et en crée une nouvelle,
écrasant potentiellement les données existantes (serveurs virtuels, channels, permissions).
Exemple de commande à ne pas faire :
|
1 2 |
# DANGER : crée un nouveau conteneur avec une base vierge ! docker compose run --rm teamspeak sh -c '...' |
Pour modifier la configuration de TeamSpeak, toujours utiliser docker compose exec
qui s’exécute dans le conteneur existant :
|
1 2 |
# Correct : exécuter dans le conteneur en cours docker compose exec teamspeak sh -c '...' |
En cas de perte de données, restaurer ts3server.sqlitedb depuis une sauvegarde,
arrêter le conteneur, remplacer la base, corriger les permissions
(chown 1000:1000) et redémarrer.
Identité serveur différente (clients affichent un warning)
Le client affiche « Server identity changed » à la connexion.
|
1 |
ls -la /home/docker/teamspeak3/data/serverkey.dat |
Cause : serverkey.dat est manquant ou différent.
Le serveur a généré une nouvelle identité au premier démarrage.
Arrêter le conteneur, remplacer serverkey.dat par celui de l’ancien serveur,
et redémarrer.
Récapitulatif de l’architecture finale
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
Nouveau serveur ({{IP_NOUVEAU}}) ┌────────────────────────────────────────────────────────────────────────────────────────┐ │ │ │ Docker : /home/docker/teamspeak3/ (réseau: teamspeak-network) │ │ ┌───────────────────────────────────────────────────────────────────────────┐ │ │ │ teamspeak3-server (teamspeak:3.13.7) │ │ │ │ UDP :9987 → voix serveur virtuel 1 │ │ │ │ UDP :9988 → voix serveur virtuel 2 ({{DOMAINE_TS}}) │ │ │ │ TCP :30033 → transfert de fichiers │ │ │ │ TCP :10011 → ServerQuery (whitelist + firewall) │ │ │ │ bind: ./data → /var/ts3server (SQLite + {{TAILLE_DONNEES}} files + licence) │ │ │ └───────────────────────────────────────────────────────────────────────────┘ │ │ │ réseau Docker interne (port 10011) │ │ ┌───────────────────────────────────────────────────────────────────────────┐ │ │ │ ts3-manager (joni1802/ts3-manager, ts3.app v2.2.5) │ │ │ │ TCP :8080 → interface web (127.0.0.1 seulement) │ │ │ │ accès via reverse proxy Nginx : https://ts3.{{DOMAINE_TS}} │ │ │ └───────────────────────────────────────────────────────────────────────────┘ │ │ │ │ Aussi sur ce serveur (via reverse proxy MyVestaCP) : │ │ Odoo 17 (:8069-8369), Odoo 8 (:8469), Akeneo PIM (:8480), ownCloud (:8490) │ └────────────────────────────────────────────────────────────────────────────────────────┘ |
Ports utilisés sur le serveur :
8069-8369— Odoo 17 (4 instances, via reverse proxy)8469— Odoo 8 (via reverse proxy)8480— Akeneo PIM 7 (via reverse proxy)8490— ownCloud 10 (via reverse proxy)8080— TS3 Manager (127.0.0.1, via reverse proxy →ts3.{{DOMAINE_TS}})9987/udp— TeamSpeak 3 voix, serveur virtuel 1 (direct)9988/udp— TeamSpeak 3 voix, serveur virtuel 2 (direct)10011/tcp— TeamSpeak 3 ServerQuery (whitelist + firewall, utilisé par LGSL et TS3 Manager)30033/tcp— TeamSpeak 3 transfert de fichiers (direct)
Mettre à jour le DNS de {{DOMAINE_TS}}
Le domaine {{DOMAINE_TS}} pointe actuellement vers l’ancien serveur.
Mettre à jour l’enregistrement A pour pointer vers la nouvelle IP :
- Type : A
- Nom : @ (racine)
- Valeur :
{{IP_NOUVEAU}}
Les clients se connectent à {{DOMAINE_TS}}:9988.
Après propagation DNS, ils atteindront automatiquement le nouveau serveur.
SRV record (optionnel) :
pour éviter que les clients doivent spécifier le port 9988 manuellement,
créer un enregistrement SRV :
_ts3._udp.{{DOMAINE_TS}} 0 5 9988 {{DOMAINE_TS}}.
Le client TeamSpeak résoudra automatiquement le bon port.
À suivre
TeamSpeak 3 est maintenant opérationnel en Docker avec TS3 Manager
pour l’administration web et LGSL pour le monitoring.
Dans les prochains articles :
- Serveurs de jeux Counter-Strike 1.6 (Pterodactyl Panel)
- LGSL — monitoring des serveurs de jeux et TeamSpeak
- Sauvegardes automatisées et stratégie de rétention
0 commentaire