Satisfactory Field guide

How to set up a Satisfactory dedicated server on Ubuntu

Install a Satisfactory dedicated server on Ubuntu 24.04 with SteamCMD, current ports, Server Manager and save backups.

How to set up a Satisfactory dedicated server on Ubuntu

This setup installs the PC dedicated server, claims it through Server Manager and moves it into systemd without changing the account that owns its saves. It uses Ubuntu 24.04 x86_64, default ports and the networking scheme introduced in Satisfactory 1.1.

You need a public IPv4 address, SSH with sudo, access to the provider firewall and a licensed PC game client. Check uname -m before choosing a VPS; these commands target x86_64. Leave storage for updates and multiple backups. A machine's suitability depends on the factory you actually load, so inspect resource use during play rather than treating a player-count formula as a capacity guarantee.

Install SteamCMD as the game account#

From your normal SSH account, install dependencies, create the unprivileged user and switch to it:

bash
sudo apt update
sudo apt install curl ca-certificates tar ufw nano lib32gcc-s1 lib32stdc++6
sudo adduser --disabled-password --gecos '' satisfactory
sudo -iu satisfactory
mkdir -p /home/satisfactory/steamcmd /home/satisfactory/server
cd /home/satisfactory/steamcmd
curl -fL -o steamcmd.tar.gz \
  https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz
tar -xzf steamcmd.tar.gz
./steamcmd.sh +force_install_dir /home/satisfactory/server \
  +login anonymous +app_update 1690800 validate +quit

The standalone download follows Valve's SteamCMD method. Its 32-bit support libraries are needed even on this 64-bit host. Wait for a successful app 1690800 installation; that is the dedicated server application, not the game client. Keep this account out of the sudo group.

Start in the foreground before adding a service#

Still in the satisfactory shell:

bash
cd /home/satisfactory/server
./FactoryServer.sh -unattended -log -Port=7777 -ReliablePort=8888

Keep this window open. Use a second SSH session under your normal sudo account for administration.

Three protocol rules reach one server process. A manual save persists the world under the service account's HOME, alongside server identity settings.
Inbound portProtocolRole
7777UDPGame traffic and lightweight queries
7777TCPHTTPS management API
8888TCPReliable messaging

The dedicated-server API reference describes query and API traffic; Coffee Stain's 1.1 announcement adds reliable TCP messaging. Explicit -ReliablePort=8888 makes startup fail if that port is unavailable, which is easier to diagnose than an automatically selected replacement.

This table assumes one server at its public IPv4 address with no external port remapping. Permit every rule in the provider firewall and Ubuntu. First inspect sudo ufw status verbose. If UFW is already active, add:

bash
sudo ufw allow 7777/udp
sudo ufw allow 7777/tcp
sudo ufw allow 8888/tcp
sudo ufw status verbose

If UFW is inactive and you intend to enable it, replace 22 below with the port used by your SSH session. Add rules for any other existing services before continuing. Then add the SSH and game rules:

bash
sudo ufw allow 22/tcp
sudo ufw allow 7777/udp
sudo ufw allow 7777/tcp
sudo ufw allow 8888/tcp

Only after every required rule succeeds, enable UFW:

bash
sudo ufw enable
sudo ufw status verbose

Keep this SSH session open and test a second connection using the same port and key. Check the Ubuntu firewall instructions when adapting existing rules. UFW does not change the provider's security group.

Claim the server and make a checkpoint#

Open Server Manager → Add Server in the game. Enter the VPS public address and port 7777. Check the address before confirming the initial self-signed certificate prompt. Name the server and set unique administrator and player passwords.

Create a session, or upload an existing save through Manage Saves, as described in the server guide. Join, place a recognisable object and make a named manual save, such as before-service.

From the administrator SSH window, inspect sudo ss -lntup for TCP and UDP 7777 and TCP 8888. If connection fails, use the connection diagnostic sequence before reinstalling.

Move into systemd with the same HOME#

After the manual save finishes, press Ctrl+C in the foreground window and wait for exit. Under your normal sudo account, open sudo nano /etc/systemd/system/satisfactory.service and paste:

ini
[Unit]
Description=Satisfactory dedicated server
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=satisfactory
Group=satisfactory
Environment=HOME=/home/satisfactory
WorkingDirectory=/home/satisfactory/server
ExecStart=/home/satisfactory/server/FactoryServer.sh -unattended -log -Port=7777 -ReliablePort=8888
KillSignal=SIGINT
TimeoutStopSec=120
Restart=on-failure
RestartSec=15

[Install]
WantedBy=multi-user.target

HOME=/home/satisfactory keeps service and foreground launches pointed at the same persistent data. The service reference recommends SIGINT; graceful shutdown still does not replace a manual save.

bash
sudo systemctl daemon-reload
sudo systemctl enable --now satisfactory
sudo systemctl status satisfactory --no-pager
sudo journalctl -u satisfactory -n 80 --no-pager

Reconnect and verify your checkpoint. The process starting successfully is only the first check; confirm that it loaded the expected factory. Updates are kept out of the unit so restarting cannot silently replace the build.

Archive persistent data before updating#

With this account, world saves are in /home/satisfactory/.config/Epic/FactoryGame/Saved/SaveGames/server. Its parent SaveGames also contains server identity settings and any blueprint directory. These are the documented Linux file locations; they are separate from the installation directory.

Make a named manual save and wait for it to finish. Under your normal sudo account, run the backup block below. The subshell ends on a failed stop, archive, inspection, restart or copy; its set -e does not change your interactive shell:

bash
(
  set -e
  sudo systemctl stop satisfactory
  if sudo systemctl is-active --quiet satisfactory; then
    printf 'Server is still running; archive aborted.\n' >&2
    exit 1
  fi
  sudo install -d -o root -g root -m 700 /var/backups/satisfactory
  satisfactory_archive="/var/backups/satisfactory/satisfactory-$(date -u +%Y%m%dT%H%M%SZ).tar.gz"
  sudo tar -C /home/satisfactory/.config/Epic/FactoryGame/Saved \
    -czf "$satisfactory_archive" SaveGames
  sudo tar -tzf "$satisfactory_archive"
  sudo chmod 600 "$satisfactory_archive"
  sudo systemctl start satisfactory
  sudo install -o "$(id -un)" -g "$(id -gn)" -m 600 \
    "$satisfactory_archive" "$HOME/satisfactory-download.tar.gz"
)

If a command fails, inspect the journal before proceeding. Do not download a partial archive or assume the last factory state was saved. Recover the service separately after diagnosing the failure. A successful block lists archive members under SaveGames; look for your world in SaveGames/server and the settings file.

On your own computer, substitute your SSH username/address and download into a dated local filename:

bash
(
  set -e
  satisfactory_local_archive="satisfactory-$(date -u +%Y%m%dT%H%M%SZ).tar.gz"
  scp YOUR_SSH_USER@YOUR_SERVER_IP:satisfactory-download.tar.gz \
    "$satisfactory_local_archive"
  tar -tzf "$satisfactory_local_archive"
)

For a custom SSH port, add -P YOUR_SSH_PORT to the scp line, replacing the placeholder; -P is uppercase. Reuse your configured SSH host alias or add the same -i /path/to/key if your normal SSH login needs it. These options are documented by OpenSSH.

tar -tzf checks that the archive can be read and shows its members. It does not prove a successful game restore or that the last intended checkpoint is present. Only after successful transfer and inspection, remove the temporary VPS copy with rm "$HOME/satisfactory-download.tar.gz" in your SSH session; retain the root-owned dated original. Keep downloaded copies private: settings can contain credentials.

Update from the SteamCMD directory#

After a manual save and a completed backup, stop the service from your normal sudo shell and switch user:

bash
sudo systemctl stop satisfactory
sudo -iu satisfactory

Only if the stop succeeded, run as satisfactory:

bash
cd /home/satisfactory/steamcmd
./steamcmd.sh +force_install_dir /home/satisfactory/server \
  +login anonymous +app_update 1690800 validate +quit

Wait for SteamCMD to report successful completion. If it fails, diagnose the update before restarting. On success, return to your administrator shell:

bash
exit

Then start and inspect the service:

bash
sudo systemctl start satisfactory
sudo systemctl status satisfactory --no-pager
sudo journalctl -u satisfactory -n 80 --no-pager

Compare the client/server build and branch, reconnect and verify the intended factory checkpoint.

Rehearse restoration before relying on the archive#

With a matching game build, stop the service and preserve the current persistent directory. Extract the selected archive into /home/satisfactory/.config/Epic/FactoryGame/Saved, so its SaveGames directory lands beneath Saved, then restore ownership to satisfactory:satisfactory. Start, select the intended session and find the checkpoint in-game. This rehearsal verifies more than an archive listing. Custom certificate files and installation config need separate preservation if you add them later.

For supported instances across your VPS, a server management panel can organise daily controls. Connecting the machine to a panel is a separate setup step; keep the backup copies and network rules from this walkthrough documented.