A control panel for Valheim servers
TL;DR: I got tired of running my Valheim server by hand, so I wrote a web UI for it. It is one Go binary you install with a single command, and it takes care of the whole mess: multiple server instances, every config option as a real form, live logs, backups and worlds, Thunderstore mods, scheduled restarts, Steam updates, and multi-user access with SSO. It is open source: valheim-server-ui.
Running a Valheim dedicated server on Linux is not hard, exactly. It is a hundred small annoyances stacked on top of each other. You install SteamCMD. You write a start script with a long line of quoted flags and try to remember which ones take a value and which are just present-or-absent. The admin list is a text file, the banned list is another text file, and the world is a folder you know you should be backing up and mostly are not. Then Iron Gate ships a patch, the server quietly refuses to let anyone in until you update it, and you are back on the box at an inconvenient hour running SteamCMD again.
I did that for a while. Then a friend wanted a mod, which meant BepInEx, which meant a plugins folder and a stack of .cfg files edited over SSH, and I decided I would rather lose a weekend writing a tool than lose the next year doing this by hand. So I did: point a browser at it, and all of the above turns into forms.
§ What it does

The thing it works in is an instance: one isolated server with its own game install, world folder, ports and systemd unit. You can run several on a single box, each one started, stopped and set to autostart on its own. Creating one is a form, display name, server name, world, password, port, tick "download the game files now", and it goes off and runs SteamCMD while you watch the progress under Jobs.
Configuration is the part I cared about most, because it is where the quoted-flag start script used to live. Every server option is a real control: name, world, password, public or not, crossplay, the difficulty preset and each individual combat, death, resource, raid and portal modifier, the save interval, the world keys. Each one is a switch, a dropdown or a number field, validated with the same rules Valheim itself enforces, so a bad setting gets caught when you save it rather than when a player trips over it. Change something while the server is running and it tells you a restart is due instead of silently drifting.

The live console streams the log as it happens, with filtering, follow, download, and highlighting for the events you actually watch for: world ready, someone joined, someone left, a save finished. Next to it, Players shows who is on now, a history of everyone who has ever joined, and editors for the admin, banned and permitted lists. You promote or ban someone by picking them out of the history rather than pasting a platform id, and Valheim reloads those lists live, so there is no restart.
Backups are one click or a schedule, with a retention policy and a restore that takes a safety backup first and can stop and start the server around itself. Worlds are their own screen: switch the active one, start a fresh world, regenerate the current one with a new seed, upload or download saves. The destructive ones make you type the world name to confirm, because I have fat-fingered enough dialogs in my life.

Mods were the feature I expected to be worst, and they turned out fine. Install BepInEx from a button. Then browse Thunderstore inside the UI, pick a mod and a version, and it resolves the dependencies and installs the whole set, printing the plan into the job log first so you can see what it is about to do. Uploaded zips and loose DLLs work too, and each plugin's .cfg shows up as a typed form instead of a file you edit blind.
Then the boring, load-bearing stuff: restarts, backups and update checks on cron, with an "only when nobody is online" switch so you are not booting your friends off at nine in the evening; automatic detection of new Valheim builds with an optional pre-update backup; a job queue with live logs for every long operation; and an audit log of every change, because when something is wrong the first question is always what changed.
§ How it is built
The whole thing is a single Go binary with the frontend baked into it. No Node process to keep alive, no separate database to run. You copy one file onto the box and that file is the entire application. Installing is one command:
curl -fsSL https://raw.githubusercontent.com/jonasthim/valheim-server-ui/main/deploy/install.sh | sudo bash
which creates a valheim system user, puts the binary in place, installs SteamCMD and the systemd units, checks the release's checksum, and starts the service on localhost. Re-running it upgrades in place and leaves your data alone. Stick a TLS reverse proxy in front when you want to reach it from outside.
The part I was fussy about is privilege. The manager runs as an unprivileged user, and on its own it cannot do the things that need root: writing systemd units, controlling the service, installing game files as another user. Its only route to any of that is a fifteen-line sudo wrapper that checks its own arguments and refuses anything outside a fixed list of operations. So the big, network-facing web app holds no power directly, and the thing that does hold power is short enough to read in one sitting and does exactly one job. Passwords are Argon2id, sessions are hardened cookies, there is a CSRF guard, and there are no default credentials: first run shows a setup wizard, you make the admin account, and the wizard disappears.
Multi-user came out of wanting to hand a friend the console without handing them the whole box. There are three roles, viewer, operator and admin, backed by local accounts or a single OIDC provider, Authentik in my case, mapping an SSO group to a role. It joins the same one-door sign-on the rest of my lab already runs on.
The bit I am quietly pleased with is self-upgrade. The manager watches its own GitHub releases, shows you what changed, and upgrades itself from the UI: a verified download, an atomic swap of the binary, and a rollback if the new one fails to start. The game servers keep running the whole time, because they are their own systemd services rather than children of the manager. The thing that manages your servers can update itself in the middle of a raid without anyone noticing.
§ A couple of things I took away
The first is that a form beats a start script, and not because it looks nicer. A form can refuse. Most of the time I used to lose was typos in flags and settings that were wrong in a way the server would not mention until a player hit the consequence. Teaching the inputs Valheim's own validation moved every one of those mistakes to the moment before saving, which is the only moment a mistake is cheap.
The second is about that sudo wrapper. Running the manager as root would have been less work, but then every bug in a large, changing, exposed web app is a root bug. An afternoon on a tiny, dull, argument-checking wrapper meant the interesting code never needs privilege at all. Something small and boring guarding the one door to the dangerous stuff is a shape I keep ending up at.
§ Get it
It runs on Debian 12 or newer and Ubuntu 22.04 or newer with systemd. One command installs it, --check shows what an install or upgrade would do before it touches anything, and it is all on GitHub: valheim-server-ui. If you keep a Valheim server going for friends, it will spare you the hundred small annoyances it spared me.