Ran a Valheim server for a group of friends for about a year. Biggest lesson: back up the world file before you do literally anything else. Second lesson: SteamAppId=892970 is not a typo.
The whole thing in four commands:
sudo apt install steamcmd
sudo adduser --system --group --home /opt/valheim valheim
sudo -u valheim -H steamcmd +force_install_dir /opt/valheim +login anonymous +app_update 896660 validate +quit
sudo ufw allow 2456:2458/udp
Then a systemd unit, then you're done. Rest of this is the stuff the Steam wiki won't tell you.
The SteamAppId gotcha
App ID for the Valheim server is 896660. The env var SteamAppId has to be 892970 (the game's ID). If you copy-paste the server ID into both places — which is the obvious thing to do — the server boots, immediately exits, and the log looks fine until you squint.
This trips up everybody. Look:
Environment=SteamAppId=892970
ExecStart=/opt/valheim/valheim_server.x86_64 -nographics -batchmode ...
SteamAppId=892970, not 896660. Burn it into memory.
The systemd unit I actually run
/etc/systemd/system/valheim.service:
[Unit]
Description=Valheim Dedicated Server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=valheim
Group=valheim
WorkingDirectory=/opt/valheim
Environment=LD_LIBRARY_PATH=/opt/valheim/linux64
Environment=SteamAppId=892970
ExecStart=/opt/valheim/valheim_server.x86_64 -nographics -batchmode \
-name "MyServer" -port 2456 \
-world "Midgard" -password "changeme" \
-savedir /opt/valheim/saves -public 1
Restart=on-failure
RestartSec=10
RuntimeMaxSec=604800
[Install]
WantedBy=multi-user.target
RuntimeMaxSec=604800 forces a restart once a week. Valheim leaks memory slowly — after two weeks uptime the thing eats 6 GB on a 4 GB box and OOMs. Weekly restart is free insurance. State survives.
-password has to be ≥ 5 chars or the server refuses to start. Error message isn't obvious — it just dies.
More on unit files in general: systemd service unit files.
Backups — do this before you let anyone on
Valheim world files get corrupted. Player disconnects mid-save, server panics on the next write, you reload and half the base is gone. Happened to us twice in the first month.
What you actually need to back up:
<worldname>.db— the world<worldname>.fwl— metadata (seed, name)<worldname>.db.old+.fwl.old— previous save, Valheim auto-rotates on clean write
All of those live in whatever -savedir points to (I use /opt/valheim/saves). If you skip -savedir, it's ~/.config/unity3d/IronGate/Valheim/worlds_local/ — less convenient to back up.
Cron, nightly:
rsync -a --delete /opt/valheim/saves/ /backup/valheim/$(date +%F)/
Keep 7 days. If the live save is corrupt, swap in the .old files. If those are also bad, pull yesterday's backup. I use the rotation pattern from rsync backups on Linux.
Ports
UDP 2456 through 2458. Open all three:
sudo ufw allow 2456:2458/udp
Valheim only uses 2456 for the game itself, but the other two are used for Steam server-query and voice. Open only 2456 and players can join but the server won't show up in the community list. UFW reference: UFW firewall rules on Ubuntu.
Steam query on 27015 — only open if you want the public server browser to list you. I run -public 0 (direct-IP only) and skip it.
Updates
Valheim drops a patch roughly once a month, and clients can't join a server running the old version. Workflow:
sudo systemctl stop valheim
sudo -u valheim -H steamcmd +force_install_dir /opt/valheim +login anonymous +app_update 896660 validate +quit
sudo systemctl start valheim
The validate flag re-checks file hashes. Skip it if you're in a hurry, add it if something feels weird after an update.
Always back up before the update. Schema migrations are rare but not impossible, and there's no downgrade path.
The two failure modes you'll hit
"Server is starting up" forever. World file is loading, or it's corrupt. Small worlds take 10 seconds, big ones (years of play, lots of structures) take up to a minute. Past two minutes → corrupt, restore from backup.
Port 2456 open, players can't connect. Almost always SteamAppId wrong or LD_LIBRARY_PATH not pointing at /opt/valheim/linux64. journalctl -u valheim -n 50 — if you don't see "Game server connected" within 30 seconds of start, one of those two is off.
Why this and not a hosting panel
I ran this on a Proxmox VM with 4 GB RAM alongside other stuff. Hosting panels want €10–15/month for a comparable box and lock you into their update cadence. A VM plus the five commands above is €3/month on Hetzner and you own everything. For one group of friends, the math is obvious.
Same SteamCMD pattern applies to Palworld — different app ID, same skeleton. Once you've done one, the second one is 10 minutes.