Skip to content
Current coupon:10% offUse it in your order

Your own Rust server on a VPS (SteamCMD, systemd)

Installing Rust Dedicated Server on a VPS with Ubuntu 24.04 or Debian 13: SteamCMD, a start script, a systemd service, ports and firewall, RCON, updates and Oxide or Carbon.

  • expert
  • ~45 min
  • Updated 2 Oct 2026

We'll set up a Rust server on your own VPS: download it with SteamCMD, prepare a start script, run it as a systemd service, open the ports and set up management over RCON. At the end, you'll find the procedure for monthly updates and for installing Oxide or Carbon.

What you'll need

  • A StormHost VPS with Ubuntu 24.04 or Debian 13, ideally 16 GB RAM or more (see Performance requirements)
  • At least 30 GB of free disk space
  • An SSH connection as root (guide), with the browser console open just in case
  • Rust on your computer (to test the connection)
  • About 45 minutes

Rust at StormHost

We're still preparing Rust servers. Until then, you can build a Rust server on a VPS with this guide. The same steps work on any Linux VPS.

How it will work#

  • The rust user – the server doesn't run as root. If someone attacks it (for example through a bug in a plugin), they only get this user's permissions.
  • SteamCMD – Valve's official tool for downloading game servers. Rust Dedicated Server has the app number 258550 on Steam.
  • Start script /opt/rust/start.sh – contains all server parameters (ports, map, RCON).
  • systemd service rust – starts the server when the VPS boots and restarts it after a crash.
  • RCON – the remote console. The console of a Linux server isn't interactive, so you send commands over RCON.

Folder structure:

PathWhat's there
/opt/rust/steamcmdSteamCMD
/opt/rust/serverThe Rust server (the server root; Oxide or Carbon also go here)
/opt/rust/server/server/rustWorld, players and configuration (identity rust)
/opt/rust/start.shStart script

Performance requirements#

  • RAM: Facepunch states at least 12 GB of free memory for the server, and a size 6000 map needs more. Plugins and players add to that. So plan on a VPS with 16 GB RAM or more. Swap helps get through peaks, but it's no substitute for missing RAM.
  • CPU: the server's main loop mostly uses a single core. Single-core performance matters more than the number of cores.
  • Disk: Facepunch states at least 15 GB of free space, ideally SSD or NVMe. Leave headroom for updates, backups and maps.

Keep an eye on the memory of a busy server with free -h.

Preparing the system#

This applies to both Ubuntu 24.04 and Debian 13. Run the commands as root.

  1. Update the package list and install the required programs:

    bash
    apt update
    apt install -y lib32gcc-s1 curl ca-certificates unzip
    • lib32gcc-s1 – a 32-⁠bit library SteamCMD needs to run (SteamCMD is a 32-⁠bit program).
    • curl – downloads files from the internet.
    • ca-certificates – certificates for secure downloads over HTTPS.
    • unzip – extracts the Oxide archive (if you'll use it).
  2. Create the rust user with the home folder /opt/rust:

    bash
    useradd --create-home --home-dir /opt/rust --shell /bin/bash rust
    • --create-home --home-dir /opt/rust – creates the /opt/rust folder, owned by the rust user.
    • --shell /bin/bash – the user gets a regular shell so you can switch to it. It has no password, so you can't log in as it over SSH; switch to it from root with su - rust.

Installing SteamCMD#

  1. Switch to the rust user:

    bash
    su - rust

    The command prompt changes to rust@…. Run all following commands under this user, up to the systemd service section.

  2. Create a folder for SteamCMD and go into it:

    bash
    mkdir -p ~/steamcmd
    cd ~/steamcmd
  3. Download and extract SteamCMD:

    bash
    curl -sqL "https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz" | tar zxvf -
    • curl -sqL "…" – downloads the archive from Valve's official server; -s is silent mode (no progress bar), -q skips curl's personal config file ~/.curlrc if there is one, -L follows redirects.
    • | tar zxvf - – extracts the downloaded archive straight into the current folder (z gzip, x extract, v list files, f - read from standard input).

    The folder now contains the steamcmd.sh script.

Downloading the Rust server#

Still as the rust user, run:

bash
~/steamcmd/steamcmd.sh +force_install_dir /opt/rust/server +login anonymous +app_update 258550 validate +quit
  • ~/steamcmd/steamcmd.sh – starts SteamCMD. On the first run, SteamCMD updates itself, which takes a moment.
  • +force_install_dir /opt/rust/server – where the server is installed. Use an absolute path and always put it before +login.
  • +login anonymous – anonymous login. You don't need a Steam account to download the server.
  • +app_update 258550 – downloads or updates app 258550 (Rust Dedicated Server).
  • validate – checks all files and restores damaged or modified ones to their original state. Careful: it also restores files overwritten by the Oxide framework.
  • +quit – exits SteamCMD when done.

The download is several gigabytes. At the end you'll see:

Outputtext
Success! App '258550' fully installed.

Test branches

Facepunch also offers test versions of the server (for example the staging branch). You get them by adding -beta staging after +app_update 258550. For a live server, use the default public version.

Start script#

  1. As the rust user, create the file:

    bash
    nano ~/start.sh
  2. Paste the content and adjust the values (explanation below the block):

    /opt/rust/start.shbash
    #!/usr/bin/env bash
    cd /opt/rust/server || exit 1
    export TERM=xterm
    export LD_LIBRARY_PATH="/opt/rust/server:/opt/rust/server/RustDedicated_Data/Plugins/x86_64"
    
    # Carbon: uncomment the next line (remove the #) once Carbon is installed
    # source /opt/rust/server/carbon/tools/environment.sh
    
    exec ./RustDedicated -batchmode \
      +server.identity "rust" \
      +server.port 28015 \
      +server.queryport 28017 \
      +server.level "Procedural Map" \
      +server.seed 12345 \
      +server.worldsize 3000 \
      +server.maxplayers 50 \
      +rcon.port 28016 \
      +rcon.password "<STRONG_PASSWORD>" \
      +rcon.web 1 \
      +app.port 28082 \
      -logfile /opt/rust/rust.log
  3. Save (Ctrl+O, Enter) and close the editor (Ctrl+X).

  4. Set the permissions so the script can be executed and only the rust user can read the password in it:

    bash
    chmod 700 ~/start.sh

What each part does:

  • cd /opt/rust/server || exit 1 – the server is started from its root folder (Oxide creates its oxide folder there). If the folder doesn't exist, the script exits.
  • export TERM=xterm – the terminal type; a systemd service has no terminal, and according to the Carbon documentation some environments require it.
  • export LD_LIBRARY_PATH=… – the folders where the server looks for its libraries (the server root and RustDedicated_Data/Plugins/x86_64).
  • source …/environment.sh – loads Carbon. Leave it commented out until you install Carbon.
  • exec ./RustDedicated – starts the server; exec makes sure systemd tracks the server process directly.
  • The server parameters (+server.port, +server.seed, +rcon.password …) are explained in detail in the server.cfg and launch parameters article.
  • -logfile /opt/rust/rust.log – the server console output is written to this file.

Replace <STRONG_PASSWORD> with an RCON password (without the angle brackets), made only of letters and digits and at least 24 characters long. You can create one with the password generator. Choose the seed (12345), map size (3000) and slot count (50) to suit you. Keep only ports, RCON, identity, map and slot count in the script, so the same setting isn't in two places.

  1. Still as the rust user, create the server.cfg file for the server name, description, tags and other settings:

    bash
    mkdir -p /opt/rust/server/server/rust/cfg
    nano /opt/rust/server/server/rust/cfg/server.cfg
    • mkdir -p … – creates the rust identity folder and its cfg subfolder (the server would create the folder on first start, but not server.cfg).
    • What to put in the file is explained in the configuration article. One line is enough for now, for example server.hostname "My Rust server".

    Create both the folder and the file as the rust user. If root created them, the server couldn't write admin accounts or bans to the cfg folder. The fix (as root): chown -R rust:rust /opt/rust/server/server.

  2. Switch back to root:

    bash
    exit

systemd service#

As root, create the service file with nano /etc/systemd/system/rust.service:

/etc/systemd/system/rust.serviceini
[Unit]
Description=Rust Dedicated Server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=rust
Group=rust
WorkingDirectory=/opt/rust/server
ExecStart=/opt/rust/start.sh
Restart=always
RestartSec=15

[Install]
WantedBy=multi-user.target
DirectiveWhat it doesRecommended valueWhen to change it
After= and Wants=network-online.targetThe server only starts once the network is up.network-online.target–
User=, Group=Which user the server runs as.rustNever root.
WorkingDirectory=The process's working folder./opt/rust/serverIf the server is at a different path.
ExecStart=The start script (absolute path)./opt/rust/start.sh–
Restart=alwaysWhen the process exits, systemd starts it again, even if it exited “cleanly”. This is also what makes the restart command over RCON work (the server exits and systemd starts it again).alwayson-failure if you don't want a restart after shutting it down manually over RCON.
RestartSec=15The pause before a restart.15–
WantedBy=multi-user.targetAfter enable, the server starts when the VPS boots.multi-user.target–

For a more detailed explanation of systemd services, see the Running an app as a systemd service guide.

Load, enable and start the service:

bash
systemctl daemon-reload
systemctl enable --now rust
  • systemctl daemon-reload – systemd reloads the service files (after every change to rust.service).
  • systemctl enable --now rust – enables starting on VPS boot (enable) and starts the service right away (--now).

With Restart=always, the only way to stop the server is systemctl stop rust. If you shut it down over RCON (quit), systemd starts it again.

Ports and firewall#

PortProtocolWhat forOpen to
28015UDPThe game (player connections).Everyone
28017UDPQuery – listing the server in the server browser.Everyone
28082TCPRust+ (mobile app). Must be at least 10000.Everyone (or no one, if you turn Rust+ off)
28016TCPRCON (remote console).Your IP address only

If you use UFW:

bash
ufw allow 28015/udp
ufw allow 28017/udp
ufw allow 28082/tcp
ufw allow from 198.51.100.25 to any port 28016 proto tcp
  • ufw allow 28015/udp – allows the game port over UDP.
  • ufw allow 28017/udp – allows the query port.
  • ufw allow 28082/tcp – allows Rust+.
  • ufw allow from 198.51.100.25 to any port 28016 proto tcp – RCON only from the IP address 198.51.100.25; use your own public IP address.

If the firewall in the customer area is set to Block everything except allowed, add the same rules there (Direction Inbound, Action Allow, the correct Protocol; for RCON, fill in Source IP / range). The port has to be allowed in both firewalls.

Don't need Rust+? In the script, replace +app.port 28082 with +app.port 1- (this turns Rust+ off, according to Facepunch) and don't open port 28082.

Verification#

  1. Check the service status:

    bash
    systemctl status rust

    Look for the line Active: active (running).

  2. Watch the server output:

    bash
    tail -f /opt/rust/rust.log

    The first start takes several minutes (the map is being generated). The server is ready when Server startup complete appears. Stop watching with Ctrl+C.

  3. In the game, open the F1 console and connect:

    text
    connect 203.0.113.10:28015

    Replace 203.0.113.10 with your VPS's IPv4 address from the Network tab.

  4. A few minutes after startup, search for the server by name in the server browser (without a framework in the Community tab, with Oxide or Carbon in Modded).

  5. Connect over RCON (RustAdmin or the web console) to 203.0.113.10:28016 with the password from the script and add yourself as owner – the steps are in the Admin and RCON article.

Updating the server#

A major Rust update comes out once a month (usually on the first Thursday of the month), with smaller fixes in between.

  1. Announce the restart to players and save the world over RCON: server.save.

  2. Stop the service (as root):

    bash
    systemctl stop rust
  3. Update the server as the rust user:

    bash
    su - rust -c "/opt/rust/steamcmd/steamcmd.sh +force_install_dir /opt/rust/server +login anonymous +app_update 258550 validate +quit"
    • su - rust -c "…" – runs a single command as the rust user and returns.
  4. If you use Oxide, upload it again (the update overwrote it) – see the Oxide or Carbon section below. Carbon updates itself on start.

  5. Start the service:

    bash
    systemctl start rust

Don't put the update in the start script if you use Oxide

If SteamCMD with validate ran on every start, every restart would remove Oxide and the server would run without plugins. Facepunch explicitly warns about this in its guide. Update manually using the steps above.

A monthly update usually also means a new world (force wipe). The procedure and what to delete are in the Rust server wipe article.

Oxide or Carbon#

What each one is and which to choose is explained in Oxide and Carbon. Installing on this VPS (the server has to be stopped):

Oxide

  1. Stop the server: systemctl stop rust.

  2. Download and extract Oxide as the rust user:

    bash
    su - rust -c "curl -fL -o /opt/rust/oxide.zip https://github.com/OxideMod/Oxide.Rust/releases/latest/download/Oxide.Rust-linux.zip && unzip -o /opt/rust/oxide.zip -d /opt/rust/server"
    • curl -fL -o /opt/rust/oxide.zip … – downloads the latest stable Oxide for Linux to the rust user's home folder. -f makes the command fail if the file doesn't exist, -L follows GitHub's redirect.
    • && – the next command only runs if the download succeeded.
    • unzip -o … -d /opt/rust/server – extracts the archive into the server root and overwrites the original game files.
  3. Start the server: systemctl start rust.

  4. Check oxide.version over RCON.

After a monthly Rust update, repeat steps 1–⁠3 only once an Oxide version newer than the Rust update is out on GitHub (opens in a new window).

Carbon

  1. Stop the server: systemctl stop rust.

  2. Download and extract Carbon as the rust user:

    bash
    su - rust -c "curl -fL -o /opt/rust/carbon.tar.gz https://github.com/CarbonCommunity/Carbon/releases/download/production_build/Carbon.Linux.Release.tar.gz && tar -xzf /opt/rust/carbon.tar.gz -C /opt/rust/server"
    • Downloads the stable (production) Carbon build for Linux and extracts (-x) it from the gzip-compressed archive (-z, -f file) into the server root (-C).
  3. In the /opt/rust/start.sh file, uncomment the line source /opt/rust/server/carbon/tools/environment.sh (remove the # at the beginning).

  4. Start the server: systemctl start rust.

  5. Check c.version over RCON.

After a Rust update, just start the server; Carbon updates itself.

Backups#

The world and players are in /opt/rust/server/server/rust, plugins and their data in /opt/rust/server/oxide (or carbon). We take care of VPS backups, but for quickly restoring a single world or configuration it's handy to also have your own backup of these folders. Before backing up, save the world (server.save) or stop the server. Backup options are described in Backups on a VPS.

Troubleshooting#

ERROR! Failed to install app '258550' (No subscription)#

The SteamCMD command is missing +login anonymous. You can't download the server without logging in (but you don't need a Steam account).

SteamCMD reports linux32/steamcmd: No such file or directory#

The 32-⁠bit library is missing. Install it as root: apt install lib32gcc-s1.

SteamCMD reports Please use force_install_dir before logon!#

The +force_install_dir parameter has to come before +login in the command. Fix the order as shown in the guide.

The service exits immediately with status=203/EXEC#

systemd can't run the script: it isn't executable (chmod 700 /opt/rust/start.sh), the first line #!/usr/bin/env bash is missing, or the file has Windows line endings (you wrote it on Windows and uploaded it). Other error codes are explained in Running an app as a systemd service. Detailed output: journalctl -u rust -n 50.

error while loading shared libraries: …#

The server is missing a system library; its name is in the message. Check the export LD_LIBRARY_PATH=… line in the script and, if needed, install the library with apt.

The server is running, but you can't connect to it#

  • The server hasn't finished starting yet (Server startup complete isn't in the log).
  • Port 28015/UDP isn't allowed in UFW or in the firewall in the customer area. Note that the game uses UDP, not TCP.
  • You're connecting to the wrong IP address or port.

The server isn't in the server browser#

The query port (28017/UDP) isn't open, or it's the same as the game port. The server only appears in the browser a few minutes after startup. Look in the right tab (Community or Modded).

The server crashes after a while and there's nothing in the log#

Most likely it ran out of memory and the system killed the process. Check:

bash
journalctl -k | grep -i "out of memory"
  • journalctl -k – prints the system kernel's messages (processes killed for lack of memory are logged here too).
  • | grep -i "out of memory" – keeps only the lines containing this text; -i ignores case.

Output mentioning RustDedicated means there isn't enough RAM. Use a smaller map, cut down on plugins, add swap or add more RAM (VPS upgrade).

Rust+ companion server connectivity test failed! Disabling Rust+ features.#

The server checks that the Rust+ port is reachable from the internet. Allow 28082/tcp in both firewalls, or turn Rust+ off (+app.port 1-). Facepunch notes that the port has to be at least 10000 and that the server needs access to companion-rust.facepunch.com.

Plugins don't work after an update#

The update with validate removed Oxide. Upload it again (the Oxide or Carbon section).

Summary

  • The server runs as the rust user in /opt/rust/server and is downloaded with SteamCMD (app 258550).
  • The parameters are in the /opt/rust/start.sh script, and the rust service runs the server (systemctl start|stop|status rust).
  • Open 28015/UDP, 28017/UDP, 28082/TCP, and RCON 28016/TCP only for your IP – in UFW and in the firewall in the customer area.
  • Send commands over RCON; the console on Linux isn't interactive.
  • Updating: save, stop, SteamCMD with validate, Oxide again (Carbon updates itself), start.

Was this guide helpful?

Applies to

  • Ubuntu 24.04
  • Debian 13

Services

Report a mistake in this guide

Search the guides