RE:NODE
Обзор хостинга

Эксплуатация13 мин чтения

SteamCMD explained: app ids, updates, betas and scripts

What SteamCMD is, how app ids work, anonymous versus account logins, what validate really does, beta branches, unattended update scripts and every common error.

Эта статья пока на английском. Мы её переводим.

0 прочтений

SteamCMD is the Steam client with the shop, the friends list and the graphics removed. It exists to do one job on servers: download and update the free dedicated-server applications that Valve and other publishers put on Steam, and fetch Workshop content for them. Nearly every install guide you will read for a Steam game opens with the same four arguments in the same order, and once you understand what each one does - and what the manifest file it leaves behind is for - you can install, pin, branch and script any of them. This is that explanation, plus the errors that account for most of the failures.

What SteamCMD is, and when you touch it#

A dedicated server for a Steam game is usually a separate free "application" on Steam with its own app id. It is not the game. You do not need to own the game to download most of them, and you cannot download them from the store page, because they are tools rather than products. SteamCMD is how you get them.

You will use it in four situations:

  • First install. Download the server application into a folder you choose.
  • Updates. The same command run again fetches only what changed, which is why it appears in every restart script people write.
  • Workshop content. workshop_download_item pulls a specific Workshop item down by id, which is how Arma 3, DayZ and Squad servers get their mods.
  • Repair. Adding validate re-checks every file against the manifest and replaces anything that does not match.

If you run servers on a panel, you may never type any of it. On RE:NODE the install runs when the server is created - usually within a minute of payment clearing - and the values SteamCMD would take as arguments appear as fields on the Startup tab instead. Understanding what those fields do is still worth ten minutes, because the day something goes wrong the console is showing you SteamCMD's output verbatim, and reading the console is a lot easier when you know what the lines mean.

Installing it#

SteamCMD is a small bootstrapper that updates itself on every launch. Download it, extract it, run it once, and let it finish before you ask it to do anything.

bash
$ sudo useradd -m steam && sudo su - steam$ mkdir ~/steamcmd && cd ~/steamcmd$ curl -sL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar zxf -$ ./steamcmd.sh +quit

On Windows the equivalent is steamcmd.zip from the same path, extracted anywhere and run as steamcmd.exe. On macOS it is steamcmd_osx.tar.gz, though almost nobody hosts from macOS.

Two things bite people on Linux. The first is that SteamCMD is a 32-bit binary, so a 64-bit system needs 32-bit libraries before it will start at all:

bash
# Debian and Ubuntu$ sudo dpkg --add-architecture i386 && sudo apt update$ sudo apt install lib32gcc-s1          # lib32gcc1 on older releases# RHEL, Rocky, AlmaLinux$ sudo dnf install glibc.i686 libstdc++.i686

The second is ownership. Run SteamCMD as an ordinary user that owns the install directory, not as root. Root installs leave files a service account cannot write to, and the update that fails six weeks later reports a permissions error that looks like a disk problem.

The anatomy of an install command#

This is the line, and every Steam game guide is a variation on it:

bash
$ ./steamcmd.sh +force_install_dir /srv/valheim \    +login anonymous \    +app_update 896660 validate \    +quit

Each + runs one command at startup, in the order written, and then SteamCMD would drop into an interactive prompt if +quit were not there.

ArgumentWhat it does
+force_install_dir <path>Where the server files go. Must come before app_update
+login anonymousLog in with no account. Must come before app_update
+login <user>Log in as a real account; prompts for the password
+app_update <id>Install or update that application
validateRe-check every file against the manifest and repair it
-beta <branch>Use a named branch instead of the default public
-betapassword <pw>Password for a private branch
+quitExit instead of opening a prompt
+runscript <file>Run a file of commands instead of typing them

force_install_dir is the one that catches people. A relative path resolves against SteamCMD's own directory, not your shell's working directory, so +force_install_dir ../valheim means something different depending on where SteamCMD lives. Use an absolute path. Leave it out entirely and the files land in steamapps/common/<AppName> under the SteamCMD folder, which is fine for one server and unmanageable for three.

When the download finishes, look at what is in the install directory besides the game:

code
/srv/valheim/  valheim_server.x86_64  steamapps/    appmanifest_896660.acf      installed build id, depots, size

appmanifest_<appid>.acf is SteamCMD's record of what it thinks is installed. It is a plain text file and it holds the build id, which is the only reliable way to answer "which version is this server on". Delete it and the next app_update re-downloads everything from scratch, which is occasionally the fastest fix for an install that has got itself into a state no amount of validate will resolve.

credentialsdepot filesbuild recordedworkshop_download_itemsteamcmdupdates itself firstSteamanonymous or an accountforce_install_dirthe server filessteamapps/workshopcontent per app idappmanifest.acfthe installed build id
Where SteamCMD puts what

App ids, and the three kinds you will meet#

An app id is a number, and a single game can have several. Getting the wrong one is the most common mistake in this whole area, because the wrong number often produces a plausible-looking failure rather than an obvious one.

  • The server app id is what you pass to app_update. It usually belongs to a separate "Dedicated Server" tool.
  • The game app id is what you pass to workshop_download_item, because Workshop content belongs to the game rather than the server tool, and it is also the id you use when creating a Steam game server login token.
  • Occasionally they are the same. Counter-Strike 2 is the notable one: the server installs from app 730, the same id as the game.
GameServer app idGame app id
Counter-Strike 2730730
Team Fortress 2232250440
Garry's Mod40204000
Left 4 Dead 2222860550
Valheim896660892970
Unturned1110390304930
Palworld23940101623730
Project Zomboid380870108600
7 Days to Die294420251570
DayZ223350221100
Arma 3233780107410
Rust258550252490
Satisfactory1690800526870
ARK: Survival Ascended24309302399830

When you cannot find an id, SteamDB is the usual reference, and SteamCMD itself will tell you:

code
Steam> app_info_update 1Steam> app_info_print 896660

That prints the application's metadata, including the list of branches and each one's current build id. It is verbose and it is the authoritative answer when a wiki page disagrees with reality.

Anonymous login, and the games that refuse it#

login anonymous works for the large majority of dedicated server tools. A minority require a Steam account that owns the game, and there is no way around it: Arma 3, DayZ and Project Zomboid are the ones you will meet most often, and Workshop downloads for those games need the same account.

bash
$ ./steamcmd.sh +force_install_dir /srv/dayz \    +login myspareaccount \    +app_update 223350 validate +quit

The symptom of getting this wrong is a specific message:

code
ERROR! Failed to install app '223350' (No subscription)

"No subscription" means the logged-in identity does not have a licence for that app. Either you used anonymous for something that will not accept it, or the account you logged in with does not own the game.

Three things to know before you type real credentials into a server:

  1. Use a spare account. Buy the game on an account that holds nothing else. A game-server install has no business holding the account you buy things with.
  2. Steam Guard has to be satisfied once, interactively. With the mobile authenticator you approve the login on your phone the first time; SteamCMD then caches the credential in its own config directory and subsequent runs are unattended. This is why an unattended script must have been run by hand at least once.
  3. Do not pass the password on the command line. It lands in shell history and is visible in the process list. Let SteamCMD prompt for it.

On RE:NODE, games that need your own Steam login - Arma 3, DayZ, Project Zomboid and 7 Days to Die among them - are created immediately and then wait on the Setup tab until you supply the credentials. They are stored as you typed them, which is the honest description of what any host must do to run SteamCMD on your behalf, and the reason the advice above about a spare account is not optional.

Updates, validate, and beta branches#

Updating is the same command again. SteamCMD compares the manifest against what is installed and fetches only the changed chunks, so a routine update on a 20 GB game might move a few hundred megabytes.

validate is different. It hashes every file in the install and replaces anything that does not match the manifest. It is the correct response to a server that crashes at startup after an interrupted update, a disk that filled mid-download, or a game whose developer tells you to. It is not something to run on every restart of a large install, because it reads the entire game from disk each time.

Branches are how publishers ship experimental builds. The default branch is called public, and a named branch is selected on the update line:

bash
# switch to a public test branch$ ./steamcmd.sh +force_install_dir /srv/7dtd +login anonymous \    +app_update 294420 -beta latest_experimental validate +quit# switch back$ ./steamcmd.sh +force_install_dir /srv/7dtd +login anonymous \    +app_update 294420 -beta public validate +quit

Some branches need -betapassword, which the developer publishes alongside the branch name. Two rules apply to all of them. Clients and servers must be on the same branch, and the error when they are not is usually a version mismatch that does not mention branches at all. And a branch is the only supported way to pin a version - SteamCMD has no "install build 12345" argument, so if a game does not publish an older branch, you cannot roll back with it. Plan around that before an update day rather than during one, and read what to do when a mod update breaks if the server is modded.

Scripted installs and unattended updates#

Typing the same long line repeatedly is how typos get into production. SteamCMD reads a script file, in which commands have no + prefix:

/home/steam/update-valheim.txt
@ShutdownOnFailedCommand 1@NoPromptForPassword 1force_install_dir /srv/valheimlogin anonymousapp_update 896660 validatequit
bash
$ ./steamcmd.sh +runscript /home/steam/update-valheim.txt

The two @ lines are settings rather than commands. @ShutdownOnFailedCommand 1 makes SteamCMD stop at the first error instead of carrying on to quit and exiting as if all was well - without it, a failed download in a cron job looks exactly like a successful one. @NoPromptForPassword 1 stops an unattended run hanging forever on a login prompt.

Two more settings are worth knowing:

  • @sSteamCmdForcePlatformType windows downloads the Windows build of an application on a Linux host. This is how servers that only ship a Windows binary - The Forest is the usual example - get installed on Linux to run under Wine.
  • @sSteamCmdForcePlatformBitness 64 forces the 64-bit depot where an application offers both.

Do not trust SteamCMD's exit code as your only success check. Historically it has not been reliable across versions. The dependable test is the line it prints on completion:

code
Success! App '896660' fully installed.

Grep for that in a wrapper script, and treat its absence as a failure. If you are automating this from a panel rather than cron, scheduled tasks worth having covers what a sensible update and restart schedule looks like.

One sizing note that causes more failed updates than anything else: SteamCMD stages the download inside the same volume it is updating, so an update needs roughly the size of the changed files free on top of the existing install. A disk sized exactly to fit the game is a disk whose next update fails, often with a misleading error about the app manifest. Leave 20 to 30 per cent free.

Workshop downloads from the command line#

Workshop items are downloaded by id, against the game's app id:

bash
$ ./steamcmd.sh +force_install_dir /srv/arma3 +login myspareaccount \    +workshop_download_item 107410 463939057 +quit

The item lands in steamapps/workshop/content/<gameappid>/<itemid>/ under the install directory, and a manifest at steamapps/workshop/appworkshop_<gameappid>.acf records what was fetched and when. Deleting that file forces a re-download of everything, which is the standard fix for an item that has updated on Steam and refuses to update locally.

Anonymous login works for Workshop content in some games and not others, and the games that require an owning account for the server usually require one here too. SteamCMD also cannot expand a collection - it only understands individual item ids. The mechanics of all of this, including how content reaches players and what happens when an author unlists an item you depend on, are in Steam Workshop mods on dedicated servers.

Errors and what they actually mean#

MessageWhat it means
Failed to install app 'X' (No subscription)The login does not own it, or the app refuses anonymous
Failed to install app 'X' (Invalid Platform)No build of that depot for this OS. Try @sSteamCmdForcePlatformType
Failed to install app 'X' (Disk write failure)Full disk, or a directory the user cannot write to
Failed to install app 'X' (Missing file permissions)Wrong owner on the install directory, usually a root install
Failed to install app 'X' (Timeout downloading item)Slow or interrupted transfer. Retry; large Workshop items often need two attempts
Rate Limit ExceededToo many login attempts. Wait; retrying faster makes it longer
error while loading shared libraries: libstdc++.so.6Missing 32-bit libraries
Failed to load steamclient.soSame cause, or a partly extracted SteamCMD
Update state (0x61) downloading and no progressDisk or network, not Steam. Check free space first

Two patterns cover most of what is left. A command that appears to do nothing usually ran before login, because force_install_dir and app_update both depend on being logged in. And an install that repeatedly fails part-way through on the same file is a disk problem far more often than a Steam problem.

On a container-based host there is one extra failure mode worth naming. If a server hits its memory limit during an install, the container is stopped rather than left to swap, and what you see afterwards is a half-written install directory. Re-running the install with validate is the fix; the general shape of that behaviour is covered in why your game server keeps restarting.

FAQ#

Do I need to own a game to run its dedicated server?

Usually not. Most dedicated-server applications download with login anonymous. Arma 3, DayZ and Project Zomboid are the common exceptions: their server tools need a Steam account that owns the game, and so do their Workshop downloads.

What does validate actually do?

It hashes every installed file against Steam's manifest and replaces anything that does not match. It repairs corruption and half-finished updates, and it also reverts any file you edited that shipped with the application. Use it after a failure, not on every restart of a large install.

Can I install a specific old version?

Only if the publisher offers it as a named branch, selected with -beta. SteamCMD has no argument for an arbitrary build id. If you need to be able to roll back, check whether the game publishes a legacy branch before you update.

Where do the files go if I do not set force_install_dir?

Into steamapps/common/<AppName> inside SteamCMD's own folder. That is fine for one server and confusing for several, which is why every guide sets the directory explicitly. Use an absolute path, because relative paths resolve against SteamCMD's directory rather than your shell's.

Why does my scripted update report success when nothing downloaded?

Because SteamCMD's exit code is not a reliable signal. Add @ShutdownOnFailedCommand 1 to the script so it stops at the first error, and have your wrapper check the output for Success! App 'X' fully installed. rather than checking $?.

How do I know which build my server is on?

Read steamapps/appmanifest_<appid>.acf in the install directory. It records the build id that is installed. app_info_print <appid> inside SteamCMD shows the build ids currently published on each branch, which is what you compare it against.


Комментарии

Полностью анонимно: без аккаунта, без почты, без cookie. Мы храним имя, которое вы ввели, текст и время - больше ничего. Количество ссылок ограничено, разметка не отображается.

0/2000