Run a new, unmodded Valheim world as a Linux service, choose how players connect and keep its saves outside the directory SteamCMD updates. You need a fresh Ubuntu 24.04 x86_64 VPS, a public IPv4 address, SSH access and a user with sudo. This guide targets the stable server distributed through Steam, with sources checked on October 12, 2026.
Use a VPS region close to your group. Leave memory and disk space for the operating system, world growth and backups; advertised player slots do not prove a particular VPS can sustain them. Valheim's 1.0 FAQ describes the game as designed for 1–10 players.
Choose Steam or crossplay first#
For a Steam-only group, omit -crossplay. For players using other supported platforms, add it. These modes have different connection paths:
| Mode | Connection path | VPS inbound rule |
|---|---|---|
| Steam | Direct game connection | UDP 2456–2457 for the example below |
| Crossplay | PlayFab relay; use a join code or public address | No game-port forwarding is needed for relay access |
The dedicated-server manual specifies the base port and base+1. Crossplay does not accept local or loopback addresses. Keeping outbound networking available matters for the relay; opening arbitrary inbound ports does not fix its registration.
Install SteamCMD under a game account#
Run the following on the VPS. The 32-bit library supports SteamCMD; the audio and atomic libraries support Valheim's Linux server:
sudo apt update
sudo apt install -y ca-certificates curl lib32gcc-s1 libatomic1 libpulse0 libpulse-dev nano ufw
sudo adduser --system --group --home /srv/valheim valheim
sudo install -d -o valheim -g valheim -m 750 /srv/valheim/steamcmd /srv/valheim/server /srv/valheim/data
sudo -u valheim -H curl -fsSLo /srv/valheim/steamcmd/steamcmd.tar.gz https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz
sudo -u valheim -H tar -xzf /srv/valheim/steamcmd/steamcmd.tar.gz -C /srv/valheim/steamcmd
sudo -u valheim -H /srv/valheim/steamcmd/steamcmd.sh +force_install_dir /srv/valheim/server +login anonymous +app_update 896660 validate +quit
The account owns the installation and has a persistent HOME; it does not need administrator rights. Confirm that /srv/valheim/server/start_server.sh and the dedicated-server executable exist. A failed download is not a reason to continue into service setup. Keep the reported build information in your administration notes.
Configure a launcher that updates will preserve#
Copy the shipped Linux launcher outside the downloaded directory:
sudo -u valheim cp /srv/valheim/server/start_server.sh /srv/valheim/start.sh
sudo chmod 700 /srv/valheim/start.sh
sudo -u valheim nano /srv/valheim/start.sh
Keep the environment exports from the installed build, including its Steam and library settings. Replace its server-launch command with the following. Replace the example password before starting; keep it distinct from the server name. Remove any duplicate launch command or interactive wait after it. The final launch should use exec so systemd tracks the actual server process:
exec /srv/valheim/server/valheim_server.x86_64 -nographics -batchmode -name "Our Valheim World" -port 2456 -world "Friends" -password "REPLACE_WITH_RANDOM_SECRET" -savedir /srv/valheim/data -public 0
This creates a new world called Friends. -savedir explicitly separates persistent data from program files; -public 0 keeps the example out of the public list. For crossplay, append -crossplay to this same command. Use a join code from the crossplay workflow.
Inspect the manual supplied alongside the installed server if its launcher differs. Preserve its environment setup rather than replacing it with an old script from a hosting tutorial.
Start once in the foreground from the server directory:
sudo -u valheim -H /bin/bash -c 'cd /srv/valheim/server && /bin/bash /srv/valheim/start.sh'
Wait for startup, then press Ctrl+C and wait for the process to finish. No player needs to join during this first run. If a library is missing, fix that error before continuing.
Install the service#
Create sudo nano /etc/systemd/system/valheim.service:
[Unit]
Description=Valheim dedicated server
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=valheim
Group=valheim
WorkingDirectory=/srv/valheim/server
Environment=HOME=/srv/valheim
ExecStart=/bin/bash /srv/valheim/start.sh
KillSignal=SIGINT
TimeoutStopSec=180
SendSIGKILL=no
Restart=no
UMask=0027
[Install]
WantedBy=multi-user.target
SIGINT follows the documented Ctrl+C shutdown path. Automatic restarts are disabled so a repeated startup or save failure remains visible. If shutdown times out, investigate the process and logs before archiving; this unit does not force-kill it at the timeout.
sudo systemctl daemon-reload
sudo systemctl enable --now valheim
sudo systemctl status valheim --no-pager
sudo journalctl -u valheim -n 100 --no-pager
Open the correct route and test a join#
First allow your actual SSH port. The example assumes port 22; substitute yours before enabling UFW. Check the provider firewall too. For Steam mode:
sudo ufw allow 22/tcp
sudo ufw allow 2456:2457/udp
sudo ufw enable
sudo ufw status verbose
sudo ss -lunp
For crossplay, omit the 2456:2457 rule when initially configuring the firewall. If switching an existing Steam server, leave the known-working route until the relay join succeeds, then remove the obsolete rule deliberately.
For Steam, enter VPS_IP:2456 in the game's address entry. For crossplay, use the active join code, or the public address as documented. A Steam Deck running the Steam version does not by itself require switching to the crossplay backend.
An active service and UDP socket establish only local readiness. Join from a player's external connection, enter the password, make a small world change, disconnect and rejoin. After a controlled service restart, check that the change remains:
sudo systemctl restart valheim
sudo journalctl -u valheim -n 100 --no-pager
Back up the complete save directory#
Stop the service and confirm both service state and process exit:
sudo systemctl stop valheim
sudo systemctl is-active valheim
sudo systemctl show valheim -p MainPID -p SubState
sudo journalctl -u valheim -n 60 --no-pager
inactive, MainPID=0 and completed shutdown in the log are the expected checks. If the server is still stopping or failed to stop, resolve that first. Do not archive a moving save.
Archive the whole data directory and launcher. Iron Gate's release notes confirm a changed save format in 1.0. A recipe that copies only an old .db/.fwl pair is not a general current backup procedure.
set -e
sudo install -d -m 700 /var/backups/valheim
VALHEIM_BACKUP="/var/backups/valheim/valheim-$(date -u +%Y%m%dT%H%M%SZ).tar.gz"
sudo tar -czf "$VALHEIM_BACKUP" -C /srv/valheim data start.sh
sudo tar -tzf "$VALHEIM_BACKUP"
install -d -m 700 "$HOME/gamehost-backup-export"
sudo install -m 600 -o "$(id -u)" -g "$(id -g)" "$VALHEIM_BACKUP" "$HOME/gamehost-backup-export/valheim-backup.tar.gz"
sudo systemctl start valheim
Run the archive block together; set -e stops it on an error before restarting the service. The export file is created with mode 600 inside your own private directory, while the dated archive remains root-private.
On your computer, retrieve that copy over SSH; use the same SSH login that ran the archive commands and substitute the public address. For a custom SSH port add -P YOUR_SSH_PORT:
scp SSH_USER@VPS_IP:gamehost-backup-export/valheim-backup.tar.gz ./valheim-backup.tar.gz
Then run rm -- "$HOME/gamehost-backup-export/valheim-backup.tar.gz" on the VPS. Keep the dated archive, service file and installed-build record elsewhere too. Listing an archive is not a restore test: rehearse restoration on a separate instance, with the matching server version and an isolated port, before relying on it.
Update deliberately and diagnose failures#
Before an update, repeat the stopped backup, omitting the final sudo systemctl start valheim in the archive block. Confirm MainPID=0 again before running the same SteamCMD installation command. Inspect the updated launcher/manual for environment changes, then start the service and repeat the client check. If you already restarted after the backup, stop the service and verify shutdown again first. Updates belong in a maintenance window, not every service startup.
| Observation | Next check |
|---|---|
| Server does not start | Read journalctl; confirm installed executable, retained environment exports and libraries. |
| Steam player times out | Confirm UDP 2456–2457 in both firewalls and the public address; a TCP web-port test does not check this route. |
| Crossplay fails with a local address | Use the join code or public address; inspect relay registration and outbound access. |
| A new world appears | Stop before making progress; compare -world, -savedir and the selected backup. Keep a copy of all existing data before changing paths. |
| Update appears ineffective | Confirm SteamCMD targets /srv/valheim/server and the service starts that same installation. |
These checks narrow the failure without deleting the world or opening an unrelated range of ports.




