How to Install a Rust Server on Ubuntu (SteamCMD)
Install a Rust dedicated server on Ubuntu with SteamCMD: 32-bit libraries, app 258550, the start command, server.cfg, ufw ports, first boot and connecting.
Last updated Verified on Ubuntu 26.04.1 LTS, Rust build 25581777, 2026-09-28
On this page
This guide sets up a vanilla Rust dedicated server on an Ubuntu machine you control, by hand, with SteamCMD. Every command below is either what the Panelra agent runs when it installs Rust on a real host, something we read off our own test server, or taken from the official Facepunch, Ubuntu and LinuxGSM documentation. The paths match the layout our agent uses (/opt/rust-servers/...), so you can compare against a Panelra host if you ever run both.
You need root or sudo on the box. The commands assume a root shell; prefix them with sudo otherwise.
What you need before you start
- Ubuntu 22.04 or 24.04, or Debian 12, on x86_64, with systemd. We checked the steps in this guide on Ubuntu 26.04.1 LTS as well.
- About 12 GB of RAM and 30 GB of free disk per server. After install, the
Bundlesfolder alone is 5 GB on our test host, and map, save and log files grow from there. - Public UDP and TCP reachability for the game, query and Rust+ ports (covered below).
Rust itself is a 64-bit program, but SteamCMD is a 32-bit tool, which is why the next step installs 32-bit libraries.
Install the 32-bit libraries
These are exactly the packages the Panelra agent installs on Debian and Ubuntu hosts:
apt-get update
apt-get install -y lib32gcc-s1 lib32stdc++6 curl wget tar
lib32gcc-s1 and lib32stdc++6 are the 32-bit runtime SteamCMD needs. Nothing else is required: the server runs as a systemd service later, so there is no need for screen or tmux.
Install SteamCMD
Download Valve's Linux SteamCMD tarball into its own directory:
mkdir -p /opt/rust-servers/steamcmd
cd /opt/rust-servers/steamcmd
curl -sqL 'https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz' | tar zxvf -
The Rust server looks for the Steam client library in ~/.steam/sdk64 of the user that runs it. Link it once:
mkdir -p ~/.steam/sdk64
ln -sf /opt/rust-servers/steamcmd/linux64/steamclient.so ~/.steam/sdk64/steamclient.so
If you run the server as a different user than the one you are logged in as, create this link in that user's home instead.
Download the Rust dedicated server
The Rust dedicated server is Steam app 258550 and downloads with an anonymous login:
/opt/rust-servers/steamcmd/steamcmd.sh \
+force_install_dir /opt/rust-servers/instance-1 \
+login anonymous \
+app_update 258550 validate \
+quit
+force_install_dir must come before +login. validate checks every file against Steam's manifest, which makes the command slower but also repairs a broken install.
To test upcoming changes, install the staging branch into a separate directory, so it never overwrites your live server:
/opt/rust-servers/steamcmd/steamcmd.sh \
+force_install_dir /opt/rust-servers/staging \
+login anonymous \
+app_update 258550 -beta staging validate \
+quit
When the download finishes, check that the binary exists:
ls -l /opt/rust-servers/instance-1/RustDedicated
What the install directory looks like
After the download, the install directory on our test host contains, among others:
| Path | What it is |
|---|---|
RustDedicated | The server binary you start |
RustDedicated_Data/ | Unity data and native plugins |
Bundles/ | Game assets, the bulk of the disk space |
runds.sh | Facepunch's sample start script |
steamapps/appmanifest_258550.acf | Steam manifest; buildid is the installed Rust build |
server/<identity>/ | Created on first start: map, saves, player data, cfg/ |
Everything a running server writes lives under server/<identity>/, where <identity> is whatever you pass as +server.identity. The map file names encode the world size and seed, for example proceduralmap.4000.1420068679.289.map is a 4000 map with seed 1420068679. Configuration goes in server/<identity>/cfg/server.cfg, next to bans.cfg and users.cfg, which the server manages itself.
To see which build you are running:
grep buildid /opt/rust-servers/instance-1/steamapps/appmanifest_258550.acf
First start: the command line
This is the command line the Panelra agent puts in every server's systemd unit, with the default ports. Run it from the install directory:
cd /opt/rust-servers/instance-1
read -rsp 'RCON password: ' RCON_PASSWORD; echo
./RustDedicated \
-batchmode \
-nographics \
+server.identity my_server \
+server.port 28015 \
+server.queryport 28017 \
+app.port 28082 \
+rcon.port 28016 \
+rcon.web 1 \
+rcon.password "$RCON_PASSWORD"
What each argument does:
-batchmode -nographics: run headless, no window and no GPU.+server.identity: the folder name underserver/. Keep it stable; changing it points the server at a new, empty save folder.+server.port: the game port players connect to, UDP.+server.queryport: the Steam server browser query port, UDP. It cannot be the same asserver.port.+app.port: the Rust+ companion port, TCP. Facepunch's default is the game port or the RCON port plus 67, whichever is larger, so 28082 with default ports.+rcon.port,+rcon.web 1,+rcon.password: WebSocket RCON for admin tools.
Ports live on the command line so that two servers on one box cannot accidentally share them. Everything else goes in server.cfg, which is easier to edit and back up. Reading the RCON password with read -s keeps it out of your shell history. In the systemd unit below it comes from a file only root can read. It still ends up in the process command line, so any local user can see it with ps: keep other accounts off the box.
This first run is only to prove the install works and to create the server/my_server/ folder. Stop it with Ctrl+C once you see Server startup complete, then write the config.
server.cfg basics
Create server/my_server/cfg/server.cfg. These are the core lines the Panelra agent writes, with the values from our test server:
server.hostname "Rust Server"
server.maxplayers 100
server.worldsize 4000
server.seed 1420068679
server.saveinterval 600
server.secure 1
server.ip 0.0.0.0
server.tickrate 30
The two settings that decide your map:
server.worldsizeis the map size in meters. Facepunch recommends 1000 to 6000. Bigger maps take longer to generate and use more RAM.server.seedpicks the procedural map. Choose a number from 1 to 2147483647 and write it down.
server.saveinterval is how often, in seconds, the world is saved to disk. server.secure 1 enables Easy Anti-Cheat. server.ip 0.0.0.0 listens on all interfaces; set a specific address only if the box has several.
When you later change the seed or world size, the server generates a new map on the next start. That is effectively a map wipe for players, even though the old files stay on disk until you delete them.
Open the firewall ports with ufw
Open the game and query ports as UDP and the Rust+ port as TCP. Allow SSH first, or enabling ufw over an SSH session can lock you out:
ufw allow 22/tcp
ufw allow 28015/udp
ufw allow 28017/udp
ufw allow 28082/tcp
ufw enable
ufw status
Do not open the RCON port (28016). Anyone who reaches it can try passwords against full admin access. Use RCON from the box itself or through an SSH tunnel. If your provider has a separate network firewall in its control panel, open the same ports there too.
Rust+ has two extra rules from Facepunch: the app.port must be reachable over TCP from the internet, and it must be 10000 or higher. The server also needs outbound access to companion-rust.facepunch.com.
First boot: map generation takes minutes
On the first start with a new seed or world size, the server generates the map from scratch. These lines are from a fresh 4000 map on our test host (shortened):
Generating procedural map of size 4000 with seed 424242
[3.0s] Loading Monument Prefabs
[4.4s] Height Map
...
[203.5s] Terrain Erosion
...
[14.3s] Main Monuments
...
Server startup complete
SteamServer Connected
The Generating procedural map line is printed on every start, even when the server loads a cached map. A fresh map is the one where you see the generation steps above, with Terrain Erosion usually the longest.
On our 4 vCPU test host, a brand new 4000 map took about 8 minutes from Generating procedural map to Server startup complete. Restarts that reuse the cached map took about 1.5 minutes. Until Server startup complete appears, players cannot join and the server is not in the browser. Do not kill the process during generation because it looks stuck.
Connect to your server
Once the log says Server startup complete, open Rust, press F1 for the console and run:
connect 203.0.113.10:28015
Replace the address with your server's public IP and use the server.port you chose. The server also shows up in the in-game Community server list after a short while, as long as the query port is reachable over UDP. If direct connect works but the browser never lists the server, check 28017/udp first.
Keep it running with systemd
Running the server in a terminal is fine for a test. For a real server, use a systemd unit so it starts on boot and comes back after a crash. This is the unit the Panelra agent generates, trimmed to what a hand install needs. Save it as /etc/systemd/system/rust-server.service:
[Unit]
Description=Rust Server
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/rust-servers/instance-1
EnvironmentFile=/opt/rust-servers/instance-1/.env
ExecStart=/opt/rust-servers/instance-1/RustDedicated \
-batchmode \
-nographics \
+server.identity my_server \
+server.port 28015 \
+server.queryport 28017 \
+app.port 28082 \
+rcon.port 28016 \
+rcon.web 1 \
+rcon.password ${RCON_PASSWORD}
StandardOutput=journal
StandardError=journal
Restart=always
RestartSec=5
StartLimitInterval=0
LimitNOFILE=100000
[Install]
WantedBy=multi-user.target
Put the password in the environment file and lock it down:
echo 'RCON_PASSWORD=pick-a-long-random-password' > /opt/rust-servers/instance-1/.env
chmod 600 /opt/rust-servers/instance-1/.env
systemctl daemon-reload
systemctl enable --now rust-server
journalctl -u rust-server -f
Restart=always brings the server back 5 seconds after any exit, and StartLimitInterval=0 stops systemd from giving up after several fast restarts. Logs go to the journal, so journalctl -u rust-server is where you watch map generation and errors. If you run the server as a dedicated user, change User= and make sure that user owns the install directory and has its own ~/.steam/sdk64 link.
Updating the server
When Facepunch ships an update, stop the server, run the same app_update 258550 validate command against the same install directory, and start it again:
systemctl stop rust-server
/opt/rust-servers/steamcmd/steamcmd.sh +force_install_dir /opt/rust-servers/instance-1 +login anonymous +app_update 258550 validate +quit
systemctl start rust-server
Do this soon after the update is out, since your players' clients update automatically. If you run Oxide, keep in mind that it patches game files and validate restores the vanilla ones, so install the matching Oxide build again after every Rust update.
Let Panelra do this for you
Everything above is what the Panelra agent does on your host: it installs the 32-bit libraries and SteamCMD, downloads app 258550 (public or staging), writes server.cfg with a valid seed, creates the systemd unit and keeps the RCON password in a root-only file. On top of that it handles updates with a player warning, scheduled wipes, Oxide or Carbon, backups and crash alerts.
Create an account at app.panelra.io, add a host, and run the install command the dashboard gives you as root on the Linux machine:
curl -sL https://app.panelra.io/install | sudo AGENT_TOKEN=<your-token> bash
The agent only makes outbound HTTPS connections, so you open no extra port for it. You still open the game, query and Rust+ ports for players.
Free during the open beta. Pricing will be announced before the beta ends.
Frequently asked questions
How much RAM does a Rust server need?
Can I run the server as root?
Why does the first start take so long?
Should I use server.seed 0?
How do I install the staging branch?
Skip the manual work: install the Panelra agent
Wipes, updates, restarts, plugins and crash alerts for your Rust servers, from one dashboard. One install command on your Linux host, no inbound ports for the agent.
Free during the open beta. Pricing will be announced before the beta ends.