Installer un serveur de jeu avec SteamCMD
SteamCMD est le socle commun de presque tous les serveurs de jeu sur Steam. Ce guide montre l'installation, la connexion anonyme, app_update avec validate, l'exploitation en service systemd et les erreurs les plus fréquentes.
Si vous exploitez un serveur de jeu sur votre propre serveur root, vous tombez presque toujours sur le même outil : SteamCMD. Valheim, Rust, Counter-Strike 2, Palworld, Enshrouded ou ARK, les fichiers serveur sont hébergés chez Valve et se téléchargent tous via le même client en ligne de commande. Une fois SteamCMD mis en place proprement, chaque jeu supplémentaire s'installe en changeant un simple numéro.
Ce guide couvre précisément les points où les tutoriels plus courts s'arrêtent : les bibliothèques 32 bits sur les systèmes 64 bits, les différences entre Debian, Ubuntu et la famille Red Hat, les messages d'erreur mot pour mot, une procédure de mise à jour qui ne redémarre pas le serveur à chaque passage de cron, et l'exploitation en tant que service systemd.
Ce que SteamCMD est et ce qu'il n'est pas
SteamCMD est le Steam Console Client, une version en ligne de commande allégée du client Steam, sans interface graphique. Il fait une seule chose, mais il la fait bien : télécharger des applications depuis le réseau Steam, les mettre à jour et vérifier leurs fichiers. Il ne démarre aucun serveur, il ne configure rien et il ne connaît pas la logique du jeu. Une fois le téléchargement terminé, les fichiers serveur se trouvent dans un répertoire, et c'est au jeu concerné de prendre le relais.
Un point essentiel pour comprendre toute la problématique des bibliothèques : le bootstrapper de SteamCMD reste à ce jour un programme 32 bits. Sur un système purement 64 bits, les bibliothèques d'exécution correspondantes lui manquent, et c'est exactement là que le premier lancement échoue chez la plupart des gens. Les fichiers serveur téléchargés, eux, sont presque toujours en 64 bits pour les jeux modernes.
Préparation : un utilisateur dédié plutôt que root
Un processus de serveur de jeu ne tourne jamais sous root. Il accepte des connexions venues d'Internet, télécharge pour de nombreux titres des mods depuis le Steam Workshop et exécute donc du code tiers. Un utilisateur dédié non privilégié coûte trois commandes et limite les dégâts.
useradd -m -d /home/steam -s /bin/bash steam
mkdir -p /home/steam/steamcmd
chown -R steam:steam /home/steam/steamcmd
SteamCMD affiche d'ailleurs un avertissement explicite lorsqu'il est lancé sous root. Ignorer cet avertissement se paie plus tard : dès qu'un répertoire appartient à root, l'exécution ultérieure sous steam échoue avec une erreur d'écriture, et le message affiché ne pointe pas vers la cause réelle.
Toutes les commandes de cet article se saisissent en tant que root et basculent vers l'utilisateur de service via runuser -u steam --. Sur les systèmes équipés de sudo, sudo -u steam fonctionne tout aussi bien. Si vous souhaitez d'abord vous occuper de la sécurisation de base, vous en trouverez les fondamentaux dans Configurer un nouveau serveur root et Sécuriser SSH.
Les bibliothèques 32 bits, différentes selon le système
C'est ici que les distributions divergent, et les listes de commandes toutes faites que l'on trouve sur le web sont régulièrement fausses sur ce point.
Debian 12, Debian 13, Ubuntu 22.04 et Ubuntu 24.04
Sur ces quatre systèmes, le paquet lib32gcc-s1 de l'archive principale suffit. C'est un paquet amd64 qui embarque l'environnement d'exécution 32 bits, et il ne demande aucune architecture i386 supplémentaire :
apt update
apt install -y ca-certificates curl tar file lib32gcc-s1 lib32stdc++6
lib32stdc++6 n'est pas toujours indispensable pour SteamCMD lui-même, mais bon nombre d'anciens binaires serveur (tout ce qui repose sur le moteur Source, les titres HLDS, certains serveurs Unity) l'exigent. L'installer tout de suite évite une séance de dépannage plus tard. file n'est présent dans aucune image minimale et servira plus bas au diagnostic, d'où sa présence dans la liste.
AlmaLinux 9, Rocky Linux 9, RHEL 9 et Oracle Linux 9
Ici, les paquets portent d'autres noms et le suffixe .i686 :
dnf -y update
dnf install -y --allowerasing glibc.i686 libstdc++.i686 tar file curl
Ces deux ajouts sont nécessaires sur une installation minimale fraîche, faute de quoi la commande s'interrompt. La raison de --allowerasing : EL9 embarque curl-minimal, et le paquet curl complet entre en conflit avec lui. Sans cette option, l'appel se termine sur AlmaLinux 9 et Rocky Linux 9 par package curl-minimal ... conflicts with curl provided by curl ... conflicting requests. Retirer complètement curl de la liste mène aussi au but, car curl-minimal fournit déjà /usr/bin/curl. La raison du dnf -y update placé en amont : si l'état du système est plus ancien que les dépôts, le nouveau paquet i686 entre en conflit avec le paquet 64 bits installé, mesuré sur Rocky Linux 9 sous la forme file /usr/share/gcc-11/python/libstdcxx/v6/printers.py from install of libstdc++-11.5.0-14.el9.i686 conflicts with file from package libstdc++-11.4.1-2.1.el9.x86_64. Sur Oracle Linux 9, aucun de ces deux conflits ne se produit, car le paquet curl complet y est déjà installé.
EPEL n'est pas nécessaire, les paquets se trouvent dans les dépôts standard. Si vous voulez en plus des outils comme htop, la marche à suivre est décrite dans Installer htop sur AlmaLinux, Rocky et RHEL.
AlmaLinux 10, Rocky Linux 10 et RHEL 10 ne conviennent pas à SteamCMD
Ce n'est pas un problème de configuration, c'est une impasse : RHEL 10 et les distributions qui en dérivent ont entièrement supprimé l'architecture x86 32 bits. Aucun dépôt n'y propose de paquets i686, pas même avec --enablerepo=*, et la commande d'installation se termine par No match for argument: glibc.i686. Comme steamcmd.sh appelle toujours le bootstrapper 32 bits linux32/steamcmd, il n'existe aucun contournement. Pour un serveur de jeu du côté Red Hat, il faut donc choisir la famille EL9, c'est-à-dire AlmaLinux 9, Rocky Linux 9 ou Oracle Linux 9.
Deuxième piège sur les installations EL très épurées : si seul util-linux-core est installé, runuser manque, alors qu'il est utilisé tout au long de ce guide. Exécutez dans ce cas dnf install -y util-linux au préalable. Sur AlmaLinux 9, Rocky Linux 9, Oracle Linux 9 ainsi que sur tous les systèmes Debian et Ubuntu, runuser est déjà présent.
Pourquoi ne pas simplement prendre le paquet steamcmd ?
Ubuntu propose steamcmd dans le composant multiverse, Debian dans non-free, et dans les deux cas le paquet n'est compilé que pour l'architecture i386. Sur un serveur 64 bits fraîchement installé, on tombe donc immanquablement sur :
E: Unable to locate package steamcmd
Pour qu'il devienne ne serait-ce qu'un candidat, il faut d'abord activer le composant et l'architecture étrangère. Sur Ubuntu, multiverse est déjà actif dans l'installation par défaut, et ces trois lignes suffisent :
dpkg --add-architecture i386
apt update
apt-cache policy steamcmd
Sur Debian, il manque en plus le composant. Sans lui, apt-cache policy steamcmd ne renvoie strictement aucune sortie, pas même un message d'erreur. Il faut au préalable ajouter contrib et non-free aux sources de paquets, depuis Debian 12 généralement dans /etc/apt/sources.list.d/debian.sources à la ligne Components:. Ce n'est qu'ensuite que la requête aboutit et signale sur Debian 12 le candidat 0~20180105-5 issu de bookworm/non-free i386. Le apt update entre le changement d'architecture et la requête est obligatoire : sans ce passage, les listes de paquets i386 n'existent pas et le candidat reste (none).
L'effort en vaut rarement la peine. Le paquet Debian est un wrapper très ancien (version 0~20180105-5 dans Debian 13) qui, de toute façon, se contente de télécharger le même bootstrapper que l'on récupère soi-même en deux lignes. L'installation manuelle est identique sur tous les systèmes, ce qui la rend bien plus facile à documenter.
Installer SteamCMD et interpréter le premier lancement
runuser -u steam -- curl -sSLo /home/steam/steamcmd/steamcmd_linux.tar.gz https://media.steampowered.com/client/installer/steamcmd_linux.tar.gz
runuser -u steam -- tar -xzf /home/steam/steamcmd/steamcmd_linux.tar.gz -C /home/steam/steamcmd
runuser -u steam -- /home/steam/steamcmd/steamcmd.sh +quit
La troisième commande est le véritable test. Au tout premier appel, SteamCMD se télécharge lui-même, affiche une barre de progression puis se termine. Cela ressemble à ceci :
[ 0%] Checking for available update...
[----] Downloading update (0 of 58,393 KB)...
[100%] Download complete.
[----] Extracting package...
[----] Installing update...
[----] Verifying installation...
Steam Console Client (c) Valve Corporation - version 1751...
Loading Steam API...OK
Critère de réussite : la dernière ligne affiche Loading Steam API...OK. Si vous voyez à la place Loading Steam API...FAILED, ou si le processus s'arrête immédiatement, ce sont les bibliothèques 32 bits de la section précédente qui manquent. Le message typique est le suivant :
steamcmd.sh: line 41: /home/steam/steamcmd/linux32/steamcmd: No such file or directory
Ce message induit en erreur, car le fichier existe bel et bien. Ce qui n'est pas trouvé, c'est l'interpréteur 32 bits dont le binaire a besoin. Vous pouvez le vérifier avec file /home/steam/steamcmd/linux32/steamcmd : la sortie indique ELF 32-bit LSB shared object, Intel 80386, ... interpreter /lib/ld-linux.so.2 et nomme donc exactement l'interpréteur manquant. Si file lui-même répond command not found, c'est qu'il a été oublié à l'étape d'installation ci-dessus. La variante error while loading shared libraries: libstdc++.so.6 traduit le même problème, simplement un cran plus loin.
Connexion anonyme ou connexion avec un compte
La très grande majorité des serveurs dédiés est publiée sous forme d'application Steam distincte et gratuite, téléchargeable sans identifiants :
+login anonymous
C'est le cas normal, et la voie qu'il faut toujours essayer en premier. Aucun mot de passe sur le serveur, pas de Steam Guard, pas de compte bloqué après un déménagement de serveur.
Une connexion avec un compte n'est nécessaire que lorsque la version serveur est liée à la possession du jeu. Cela se reconnaît à ce message :
ERROR! Failed to install app 'ID' (No subscription)
No subscription signifie toujours la même chose : ce compte n'a pas le droit de télécharger cette application. Avec une connexion anonyme, cela veut dire qu'un vrai compte possédant le jeu est nécessaire. Avec un vrai compte, cela veut dire que la licence manque ou que le mauvais App ID a été utilisé.
La connexion avec un compte se déroule de façon interactive, car Steam Guard réclame un code :
/home/steam/steamcmd/steamcmd.sh +login monnomutilisateur
Après cette validation unique, un fichier sentry est déposé dans ~/.steam, et les appels non interactifs fonctionnent ensuite eux aussi. Trois points qui font mal en pratique : utilisez pour cet usage un compte Steam séparé qui ne détient que la licence du serveur. N'inscrivez jamais le mot de passe dans un script cron. Et attendez-vous à ce que Steam redemande une validation après une longue inactivité ou un changement d'IP, ce qui bloque silencieusement une mise à jour automatique.
À distinguer complètement de cela, le Game Server Login Token (GSLT). Il n'a rien à voir avec le téléchargement, mais détermine si le serveur en cours d'exécution apparaît publiquement dans la liste des serveurs. Pour Counter-Strike 2 et les autres titres Valve, il se génère dans le compte Steam et s'inscrit dans la configuration du serveur, pas dans SteamCMD.
Installer un jeu : ordre des arguments, validate et branches
SteamCMD traite les arguments + strictement de gauche à droite. Il en découle la règle la plus importante de toutes :
+force_install_dirdoit se trouver avant+app_update. Placé après, les fichiers atterrissent dans le chemin par défaut et le répertoire indiqué reste vide.
Voici un appel complet, ici avec l'exemple du serveur Valheim et de son App ID 896660 :
runuser -u steam -- mkdir -p /home/steam/valheim
runuser -u steam -- /home/steam/steamcmd/steamcmd.sh +force_install_dir /home/steam/valheim +login anonymous +app_update 896660 validate +quit
Notez que validate s'écrit sans signe plus, car c'est un argument de app_update et non une commande à part entière. validate compare chaque fichier à la somme de contrôle du dépôt et retélécharge les écarts. C'est utile lors de la première installation, après un téléchargement interrompu et en cas de plantages inexpliqués. Pour une mise à jour de routine, c'est superflu et coûteux, car l'intégralité des données est relue. Deux effets secondaires méritent d'être connus : les fichiers appartenant au dépôt que vous avez modifiés vous-même sont réinitialisés, et pour les jeux dont les mods se trouvent dans le répertoire d'installation, validate peut supprimer des fichiers étrangers.
Le contrôle de réussite se fait sur la dernière ligne :
Success! App '896660' fully installed.
Une autre branche, par exemple une branche de test publique, s'accroche directement à app_update :
+app_update 896660 -beta public-test validate
Pour une branche protégée par mot de passe, -betapassword vient s'y ajouter. Le retour à la version standard se fait avec -beta none, car omettre simplement le paramètre ne suffit pas : le choix de la branche reste enregistré dans le manifeste.
Quand ça tourne mal : les messages d'erreur mot pour mot
SteamCMD signale les problèmes sous forme d'un statut hexadécimal qui ne dit rien sans traduction. Voici les plus fréquents :
Error! App '...' state is 0x202 after update job: espace de stockage insuffisant. Vérifiez avecdf -h /home/steam. N'oubliez pas que SteamCMD a besoin, en plus du répertoire cible, de place pour le cache de téléchargement, en règle générale dans le même système de fichiers soussteamapps/downloading. Pour les gros titres, le pic de consommation pendant la mise à jour peut atteindre près du double de la taille finale. Si le disque est plein, consultez Nettoyer un disque plein sous Linux.Error! App '...' state is 0x606 after update job: erreur d'écriture. Dans neuf cas sur dix, il s'agit de droits d'accès et non du matériel. Le grand classique : la première exécution a eu lieu sous root, la seconde soussteam. Réparation avecchown -R steam:steam /home/steam. En cas de liens symboliques vers un second disque, la cible doit elle aussi appartenir à l'utilisateur de service.Error! App '...' state is 0x402 after update job: aucune connexion exploitable vers les serveurs de contenu Steam. Le plus souvent une règle de pare-feu sortante ou un problème de serveur de noms. SteamCMD a besoin en sortie du TCP 443 ainsi que des ports 27015 à 27050.No subscription: question de licence, voir la section précédente.Failed to load steamclient.soou[S_API FAIL] SteamAPI_Init(): le binaire du serveur cherche la bibliothèque Steam à un emplacement fixe que SteamCMD ne remplit pas. Sont concernés pratiquement tous les serveurs Unreal Engine, ainsi que Rust, Palworld et V Rising. La solution tient en deux liens dans le répertoire personnel de l'utilisateur de service.
runuser -u steam -- mkdir -p /home/steam/.steam/sdk64
runuser -u steam -- ln -sf /home/steam/steamcmd/linux64/steamclient.so /home/steam/.steam/sdk64/steamclient.so
runuser -u steam -- mkdir -p /home/steam/.steam/sdk32
runuser -u steam -- ln -sf /home/steam/steamcmd/linux32/steamclient.so /home/steam/.steam/sdk32/steamclient.so
Comme il s'agit de liens vers le répertoire de SteamCMD, ils restent valides après une mise à jour automatique de SteamCMD. Une erreur consécutive fréquente consiste à créer ces répertoires sous root, si bien que le service ne peut plus les lire par la suite.
Lorsqu'un téléchargement reste durablement bloqué, le dernier levier consiste à supprimer steamapps/appmanifest_<ID>.acf dans le répertoire d'installation. SteamCMD considère alors l'application comme non installée et la retélécharge intégralement.
Automatiser les mises à jour sans redémarrer le serveur pour rien
La recommandation courante consiste à lancer app_update une fois par jour via cron et à redémarrer le service. Cela coûte une interruption quotidienne, même lorsqu'il n'y a aucune mise à jour. Mieux vaut comparer le build ID. Celui qui est installé figure dans le fichier manifeste, le plus récent est fourni par app_info_print :
runuser -u steam -- /home/steam/steamcmd/steamcmd.sh +login anonymous +app_info_update 1 +app_info_print 896660 +quit
On en tire un script placé dans /usr/local/sbin/steam-update.sh :
#!/bin/bash
set -euo pipefail
APPID=896660
DIR=/home/steam/valheim
CMD=/home/steam/steamcmd/steamcmd.sh
UNIT=valheim
MANIFEST="$DIR/steamapps/appmanifest_${APPID}.acf"
installed=$(awk '/"buildid"/ {gsub(/"/,"",$2); print $2; exit}' "$MANIFEST" 2>/dev/null || echo 0)
latest=$(runuser -u steam -- "$CMD" +login anonymous +app_info_update 1 +app_info_print "$APPID" +quit \
| awk '/"public"/{f=1} f && /"buildid"/ {gsub(/"/,"",$2); print $2; exit}')
if [ -z "$latest" ]; then
echo "Impossible de déterminer le build ID actuel, abandon."
exit 1
fi
if [ "$installed" = "$latest" ]; then
echo "À jour (build $installed), pas de redémarrage."
exit 0
fi
echo "Mise à jour de $installed vers $latest"
systemctl stop "$UNIT"
runuser -u steam -- "$CMD" +force_install_dir "$DIR" +login anonymous +app_update "$APPID" +quit
systemctl start "$UNIT"
Le script ne redémarre que lorsque quelque chose a réellement changé, et il s'interrompt proprement lorsque Steam ne répond pas. Sans ce contrôle, un résultat de requête vide serait interprété comme une mise à jour et le serveur serait arrêté sans raison. Il s'exécute via cron ou, mieux encore, via un timer systemd, dont les bases sont expliquées dans Configurer une tâche cron sous Linux.
Gardez à l'esprit que de nombreux jeux exigent aussi des clients à jour après une mise à jour du serveur. Une mise à jour automatique en pleine heure de pointe éjecte tous les joueurs. Placez donc l'exécution au petit matin.
Exploiter le serveur comme service systemd
Un serveur de jeu lancé dans une session screen ne survit pas à un redémarrage. Une unité placée dans /etc/systemd/system/valheim.service règle le problème :
[Unit]
Description=Valheim Dedicated Server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=steam
Group=steam
WorkingDirectory=/home/steam/valheim
Environment=LD_LIBRARY_PATH=/home/steam/valheim/linux64
Environment=SteamAppId=892970
ExecStart=/home/steam/valheim/valheim_server.x86_64 -nographics -batchmode -name "KernelHost" -port 2456 -world "Dedicated" -password "aChanger"
Restart=on-failure
RestartSec=10
KillSignal=SIGINT
TimeoutStopSec=90
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now valheim
systemctl status valheim
Deux lignes y sont plus importantes qu'elles n'en ont l'air. KillSignal=SIGINT fait en sorte que le serveur sauvegarde à l'arrêt, car bon nombre de serveurs de jeu ignorent SIGTERM et perdent, en cas d'arrêt brutal, la progression des dernières minutes. TimeoutStopSec lui en laisse le temps. Vous trouverez une explication détaillée de tous les champs dans Créer un service systemd, et la marche à suivre pour un serveur Java dans Démarrer automatiquement un serveur Minecraft.
Si le serveur meurt immédiatement au démarrage par manque de RAM, jetez un œil à Configurer le swap. Les ports doivent ensuite être ouverts dans le pare-feu, voir Configurer UFW, sachant que les serveurs de jeu ont presque toujours besoin d'UDP et qu'une entrée purement TCP explique typiquement pourquoi le serveur tourne alors que personne n'arrive à s'y connecter.
App IDs des jeux les plus courants
L'ID est le seul élément qui change d'un jeu à l'autre. Peuvent notamment être téléchargés de façon anonyme :
- 232250 Team Fortress 2
- 4020 Garry's Mod
- 222860 Left 4 Dead 2
- 730 Counter-Strike 2 (depuis le passage de CS:GO, le client et le serveur forment une seule et même application, d'où un téléchargement volumineux)
- 258550 Rust
- 376030 ARK: Survival Evolved
- 896660 Valheim
- 2394010 Palworld
- 2278520 Enshrouded
- 1829350 V Rising
- 294420 7 Days to Die
- 380870 Project Zomboid
- 1690800 Satisfactory
- 581330 Insurgency: Sandstorm
- 233780 Arma 3
- 1007 Steamworks SDK Redistributables, minuscule et donc idéal pour tester le bon fonctionnement de l'installation
Ne confondez pas l'application serveur avec l'application du jeu. Pour ARK par exemple, 346110 est le jeu et 376030 le serveur. Si vous cherchez un ID, vous le trouverez dans la Dedicated Servers List du Valve Developer Wiki ou via SteamDB. Le test rapide est toujours le même : un app_update anonyme, et si No subscription apparaît, c'était l'ID du client.
Comment savoir que tout fonctionne vraiment
Quatre vérifications, dans cet ordre :
- Les fichiers sont présents.
du -sh /home/steam/valheimdoit afficher une taille plausible, etsteamapps/appmanifest_896660.acfdoit contenir unbuildid. Un répertoire de quelques mégaoctets signifie que le téléchargement a été interrompu. - Le processus vit plus d'une minute.
systemctl status valheimafficheactive (running). Un service qui redémarre à la seconde reste suractivating (auto-restart), et dans ce casjournalctl -u valheim -n 50en donne la raison. - Le port est ouvert, et en UDP.
ss -ulpn | grep 2456doit nommer le processus. S'il n'affiche rien, le serveur est encore en cours d'initialisation ou lié à la mauvaise adresse. - Accessible depuis l'extérieur. Ce n'est qu'ensuite qu'il faut vérifier le pare-feu et se connecter depuis le jeu. De nombreux titres nécessitent en plus un port de requête, et pour Valheim c'est le port du serveur plus un.
Si ces quatre points sont réunis, l'infrastructure sous-jacente est saine et tout le reste relève de la configuration du jeu. Sur un serveur root KernelHost hébergé dans le datacenter maincubes de Francfort-sur-le-Main, la protection DDoS issue de notre propre réseau vient s'y ajouter, ce qui compte justement pour les serveurs de jeu listés publiquement, puisqu'une liste publique rend l'adresse IP visible de tous. Vous trouverez les explications de fond dans Protéger un serveur contre les attaques DDoS.
Questions fréquentes
Pourquoi SteamCMD ne démarre-t-il pas sur mon serveur 64 bits ?
Ai-je besoin d'un compte Steam pour un serveur de jeu ?
Que signifie "App state is 0x606 after update job" ?
Faut-il passer validate à chaque mise à jour ?
Comment mettre à jour automatiquement sans redémarrer le serveur tous les jours ?
Pourquoi apt ne trouve-t-il pas le paquet steamcmd ?
2026 KernelHost GmbH. Tous droits réservés. Ce guide est protégé par le droit d'auteur. Sa republication sur d'autres sites web, même partielle ou sous une forme modifiée, n'est pas autorisée sans notre accord écrit. Les citations accompagnées de la source et d'un lien sont expressément les bienvenues.

