Use case · Game server

Starbound dedicated server on Linux: SteamCMD login, config, mods

A Starbound dedicated server is the starbound_server program that ships inside the game's own Steam app, 211820, so SteamCMD can only download it with a Steam account that owns Starbound: Valve's list of dedicated servers marks it "Game Purchase Required" and anonymous login as unavailable. On Linux it runs as linux/starbound_server, listens on TCP 21025, reads its settings from storage/starbound_server.config and keeps its worlds under storage/universe.

See the game servers

What the server is made of

PartValueStated by
Steam app211820, the game; anonymous login: noValve's dedicated servers list
Binarylinux/starbound_server, 64-bit onlyCommunity wiki
Game portTCP 21025 (gameServerPort)Community wiki
RCONPort 21026, off by default, empty password by defaultCommunity wiki
Query serverOff by default, port 21025Community wiki
Settingsstorage/starbound_server.config, JSONCommunity wiki
Worldsstorage/universeChucklefish post (universe folder); storage/ path per community wiki
Modsmods/: .pak files or unpacked mod foldersCommunity wiki

Chucklefish publishes little about the server itself. Its FAQ sends multiplayer questions to the wiki that playstarbound.com links, starbounder.org, which players edit; the rows marked community wiki come from there. Check them against the file your install writes on its first start.

The Steam ownership requirement

Valve's list names the entry "Starbound Dedicated server", app 211820, with anonymous login marked No. login anonymous cannot fetch it. SteamCMD has to sign in as an account that owns Starbound, and the download is the full game, server included.

  • Steam Guard. Valve's SteamCMD page says that with Steam Guard on, SteamCMD asks for the access code (Valve mentions the one sent by email) on the first login only, and again only if the files where SteamCMD stores the login information are deleted.
  • One session per account. Valve notes an account can be logged in once at a time, counting the desktop client and SteamCMD. Every update signs the server in, which can push your own game session off. Valve recommends a separate account for servers; for Starbound that account needs its own copy of the game.
  • What is cached. After one interactive login, SteamCMD keeps its saved login in its own data folder. For Ubuntu's steamcmd package that is ~/.local/share/Steam in the server user's home; the package's wrapper script sets that path. Valve does not say this outright, but its wording implies that this saved login lets later runs sign in with the account name alone; the update service below relies on it. Anyone who copies that folder can act as that account, so it stays out of the backup archive below; deleting it signs the machine out, and the next login asks for the password and the Steam Guard code again.
  • What is never stored. In these steps the password is typed once at SteamCMD's own prompt. It goes into no script, no unit file and no command line. The account name sits in a root-only file and in a private update log.

Sizing the machine

Chucklefish gives no hardware figures for the server alone. The store page's Linux requirements cover the whole game: a Core 2 Duo minimum and a Core i3 recommended, 2 GB of memory minimum and 4 GB recommended, 3 GB of storage minimum and 4 GB recommended, on Debian Stable or Ubuntu 12.04 LTS or later. Our reading: a server skips the rendering, so treat those as a floor, and size for what moves the load, which is how many worlds your players keep loaded at once and which mods run. Measure with top while the group is online.

Check the architecture before anything else. Valve's install steps add the i386 architecture because SteamCMD is 32-bit x86 software, and the server's startup line in the community guide reads linux x86_64. Our inference, not a Chucklefish statement: put it on an x86 line. Our ARM cartridge (X-Gene) is out anyway: it boots only Ubuntu 16.04 and 18.04.

Our bare metal game servers come in custom configurations with any operating system on them, in New York, Miami, San Francisco, Amsterdam or Bucharest; ping each city's test IP on the data center page before you pick. A ready server goes live about 30 minutes from payment approval, and builds to order take 4-24 hours. The port is unmetered, 1 Gbps on 10 of the 18 dedicated lines and 500 Mbps on the rest, with one IPv4, and IPv6 added free at checkout. Rack servers and blades each carry an out-of-band controller (HPE iLO, Dell iDRAC or a Supermicro BMC), published once you add a console login; on most Moonshot cartridges you get power control and nothing more.

Installing on Ubuntu 24.04

Firewall first, then a dedicated user. Valve warns against running SteamCMD as root, and Chucklefish's own server exploit notice told admins to run the server under a heavily restricted account. Run this as your sudo user; it ends with the steamcmd install because apt asks you to accept Steam's licence there.

sudo sed -i 's/^IPV6=.*/IPV6=yes/' /etc/default/ufw
sudo ufw allow OpenSSH
sudo ufw --force enable
sudo ufw allow 21025/tcp
sudo useradd -m -s /bin/bash starbound
sudo add-apt-repository -y multiverse
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install -y libvorbisfile3
sudo apt install steamcmd

The community guide lists libvorbisfile3 as a library the server needs. Its Linux guide also gives 21025 as TCP and UDP, but the server's startup log shows it listening on TCP only, and the query server that shares 21025 is off by default. If you set runQueryServer to true, also run sudo ufw allow 21025/udp. Then download the game as the starbound user, logging in by hand once:

  1. Start SteamCMD as that user: sudo -u starbound -H /usr/games/steamcmd.
  2. At the Steam> prompt, point it at the install folder first (Valve wants this ahead of the login): force_install_dir /home/starbound/server.
  3. Type login your_steam_name, then the password and the Steam Guard code when SteamCMD asks for them.
  4. Type app_update 211820 validate, wait for the success line, then quit.
  5. Store the account name for the service in a file that is private from the moment it exists: sudo install -d -m 700 /etc/starbound, then sudo install -m 600 /dev/null /etc/starbound/steam.env, then echo 'STEAM_USER=your_steam_name' | sudo tee /etc/starbound/steam.env > /dev/null.

Running it under systemd

# /etc/systemd/system/starbound.service
[Unit]
Description=Starbound dedicated server
Wants=network-online.target
After=network-online.target

[Service]
User=starbound
Group=starbound
UMask=0077
EnvironmentFile=/etc/starbound/steam.env
WorkingDirectory=/home/starbound/server/linux
ExecStartPre=-/bin/bash -c '/usr/games/steamcmd +@NoPromptForPassword 1 +force_install_dir /home/starbound/server +login "$STEAM_USER" +app_update 211820 +quit > /home/starbound/steamcmd-update.log 2>&1'
ExecStart=/home/starbound/server/linux/starbound_server
TimeoutStartSec=1800
KillSignal=SIGINT
TimeoutStopSec=60
Restart=always
RestartSec=15

[Install]
WantedBy=multi-user.target
  • The - before the update command lets the server start on the installed version when SteamCMD exits with an error, for example after the cached login has lapsed. It does not cover an update that hangs: TimeoutStartSec=1800 gives the start 30 minutes, then systemd fails the attempt and Restart=always tries again.
  • @NoPromptForPassword 1 is from Valve's script example: SteamCMD does not wait for a password nobody is there to type. Its output goes to steamcmd-update.log in the server user's home rather than the journal. If that log shows a failed login, repeat the interactive login above.
  • Restart=always restarts the process after a crash; systemctl stop still stops it for good. KillSignal=SIGINT matches the Ctrl+C shutdown the community guide uses.
  • Run sudo systemctl daemon-reload, then sudo systemctl enable --now starbound, and follow journalctl -u starbound -f until the universe server reports it is listening on 21025.
  • Every start runs the update, so after a Starbound release a sudo systemctl restart starbound brings the server level with the Steam clients of your players.

starbound_server.config

The server writes the file on its first start. Edit it with the server stopped: the community guide says a file with a JSON syntax error is renamed to starbound_server.config.old and replaced with defaults. Defaults below are from the community wiki's table.

KeyDefaultSet it to
serverNameemptythe name players see
maxPlayers8the size of your group
serverUsers{}one entry per player, e.g. "fred": {"admin": false, "password": "..."}
allowAnonymousConnectionstruefalse once every player has an entry
allowAdminCommandsFromAnyonefalseleave false; grant admin per user
runRconServer, rconServerPortfalse, 21026on only if you need remote commands
rconServerPassword, rconServerBindempty, ::a long password and 127.0.0.1
gameServerPort21025change only for a second instance
  1. sudo systemctl stop starbound
  2. sudo -u starbound -H nano /home/starbound/server/storage/starbound_server.config
  3. sudo -u starbound python3 -m json.tool /home/starbound/server/storage/starbound_server.config > /dev/null && echo valid
  4. sudo chmod 600 /home/starbound/server/storage/starbound_server.config, then sudo systemctl start starbound

serverUsers passwords sit in that file in plain text, which is why it is mode 600 and why the unit sets UMask=0077. With RCON on and bound to 127.0.0.1, reach it through your own login, ssh -L 21026:127.0.0.1:21026 you@your-server, and never add 21026 to ufw. A second universe on the same machine needs its own install folder, unit, config and ports (gameServerPort, queryServerPort, rconServerPort), plus a ufw rule for its game port; all three are settable, so one IP serves both.

Mods on the server

The server loads .pak files or unpacked mod folders from /home/starbound/server/mods, the folder the community modding guide names. Steam Workshop subscriptions belong to a Steam client, and the SteamCMD install subscribes to nothing, so copy each mod's .pak in yourself and restart.

Keep the server and every client on the same set. Chucklefish's 1.2 notes say some changes, such as player inventory size, must be applied on both server and client. The community table lists allowAssetsMismatch as true by default, so a mismatched client is not turned away: publishing the exact list to your players is on you. After any change, read storage/starbound.log; Chucklefish's FAQ says JSON errors almost always come from mods. Take a backup before adding one, so the universe can be rolled back.

Backups that cover everything

Everything the server keeps lives in two folders: storage (the universe, player files, the log and the config with its serverUsers) and mods. The script stops the server, archives both, and starts it again, which also runs the update. It keeps 14 days and runs at 04:30 from cron.

sudo install -d -m 700 /var/backups/starbound
sudo tee /usr/local/sbin/starbound-backup.sh > /dev/null <<'EOF'
set -euo pipefail
umask 077
ARCHIVE=/var/backups/starbound/starbound-$(date +%F-%H%M).tar.gz
systemctl stop starbound
trap 'systemctl start starbound' EXIT
tar -C /home/starbound/server -czf "$ARCHIVE" storage mods
find /var/backups/starbound -name 'starbound-*.tar.gz' -mtime +14 -delete
EOF
printf '%s\n' '30 4 * * * root bash /usr/local/sbin/starbound-backup.sh >> /var/log/starbound-backup.log 2>&1' | sudo tee /etc/cron.d/starbound-backup > /dev/null

To restore, set the archive name once and check it exists before touching anything:

  1. List the archives with sudo ls -lt /var/backups/starbound, then set the one you want and the server folder, once: A=/var/backups/starbound/starbound-2026-10-20-0430.tar.gz and D=/home/starbound/server.
  2. sudo test -f "$A" && echo found must print found; if not, stop here.
  3. sudo systemctl stop starbound
  4. Never delete or overwrite an earlier rescue copy. If storage.old or mods.old is still there from a previous restore, give it a dated name: for x in storage.old mods.old; do sudo test -e "$D/$x" && sudo mv "$D/$x" "$D/$x-$(date +%F-%H%M%S)"; done
  5. Move the live data aside only if nothing is in the way: sudo test ! -e "$D/storage.old" && sudo test ! -e "$D/mods.old" && sudo mv "$D/storage" "$D/storage.old" && sudo mv "$D/mods" "$D/mods.old" && echo moved. If it does not print moved, stop and look before going on.
  6. Only now extract: sudo tar -C "$D" -xzf "$A", then sudo chown -R starbound:starbound "$D/storage" "$D/mods".
  7. sudo systemctl start starbound, join, and check your worlds and characters.
  8. When you are sure the restore is good, you may remove this restore's rescue copies: sudo rm -rf "$D/storage.old" "$D/mods.old".

Copy archives off the machine yourself. On the server, sudo cp "$A" ~/ && sudo chown "$USER": ~/"$(basename "$A")"; from your own computer, scp you@your-server:starbound-*.tar.gz .; then delete the copy in your home folder. The archives hold serverUsers passwords, so keep them private wherever they land.

When this is the wrong setup

  • A few friends who always play together can skip the server: since 1.0, Chucklefish says players can join a friend's game from the Steam friends list.
  • No Steam account that owns Starbound means no SteamCMD download; that is the game's rule, not ours.
  • The ARM cartridge is out, as above. Pick an x86 machine.
  • This page assumes you run the game yourself: SteamCMD, config, mods and backups are yours. For a machine to run it on, start from our Linux servers.

Questions

Can SteamCMD fetch the Starbound server with an anonymous login?

No. Valve's dedicated servers list gives Starbound app 211820, marks anonymous login as unavailable and notes that a game purchase is required. Log in once by hand with an account that owns Starbound; later updates reuse SteamCMD's cached login.

Should the server use its own Steam account?

It can use yours. Valve notes an account can only be logged in once at a time, so each server update can sign your desktop session out, and Valve recommends a separate account for servers. For Starbound that separate account must own the game too.

What port does the server listen on?

TCP 21025: the community wiki gives it as the default gameServerPort, and the startup log shows the server listening there on TCP. UDP matters only if you switch on the query server (runQueryServer), which is off by default; then add sudo ufw allow 21025/udp. Allow it in ufw before the first start. RCON uses 21026 when switched on; keep that one closed; an SSH tunnel reaches it.

Where does the server keep the worlds?

In the universe folder inside storage, which on this layout is /home/starbound/server/storage/universe. Player files, the log and starbound_server.config live in storage too, so back up the whole folder with mods beside it.

Do players need the same mods as the server?

Yes, keep both on one set. Chucklefish's 1.2 notes say some changes must be applied on server and client alike, and the community table shows mismatched clients are allowed in by default, so nothing enforces it for you. Share the exact .pak list with your players.

What keeps the server current after a Starbound release?

Restart the service. The unit runs SteamCMD's app_update 211820 before every start using the cached login, and if that step fails the server still starts on the installed version. Check steamcmd-update.log in the server user's home to see what the update did.

Put your universe on a whole machine

Pick a city, an x86 configuration and the OS, then install Starbound with the steps above.

See the game servers

Related on Server Room

Other use cases