Documentation

Version 0.6. This covers only what works today. What is still missing is listed at the end of "What it is".

What it is

Stokehold GSM is a web panel for game servers on top of LinuxGSM. One binary and SQLite, no Docker, PHP or database server. The panel runs the LinuxGSM scripts and shows the result, so it supports whatever LinuxGSM supports (143 games when checked). Game servers run under ordinary Linux users, just like in LinuxGSM itself.

Two parts: the panel (web interface, no root rights) and the helper (a root service with a fixed set of operations; it is what actually runs the LinuxGSM commands). The panel can do nothing the helper does not allow.

Not yet: S3 backups, moving a server between machines, customer accounts for hosts. The game tools and server data parsing are verified on samples and in tests; runs against live game servers are coming gradually.

Install

You need Linux with systemd and OpenSSL 3 (Ubuntu 22.04 or newer, Debian 12 or newer), an x86_64 or ARM64 CPU and root access. On Windows and macOS the panel cannot be installed directly: use a Linux VPS or WSL2 (see the home page).

sudo apt install -y curl openssl && curl -fsSL https://dl.stokehold.online/install.sh | sudo bash

What the installer does:

  1. verifies the release signature and file hashes; on any error it stops without changing anything;
  2. installs stokehold and stokehold-helper into /usr/local/bin;
  3. creates the stokehold user, /var/lib/stokehold and the settings file /etc/stokehold/stokehold.env;
  4. creates and starts the stokehold-helper and stokehold services;
  5. opens port 8443 in ufw if it is active and prints the first-setup link.

To read the installer first, download install.sh and run sudo bash install.sh. Installer options: --channel stable|beta, --version vX.Y.Z, --no-start.

First sign-in

  1. At the end of the install a link like https://ADDRESS:8443/setup?code=… appears in the console. Open it in a browser. The code in the link is single-use.
  2. The browser warns about the certificate: the panel makes its own until you have a domain. Choose "Advanced" and continue. The installer prints the certificate fingerprint next to the link so you can compare.
  3. Enter the owner's email and a password (at least 10 characters). The page works once: after the owner exists it cannot be opened again.
  4. Turn on two-factor authentication right away: Security → Start setup. Add the secret to an authenticator app (Aegis, FreeOTP, any TOTP), enter the six-digit code and press Enable.
Lost the link? The code is always in the log: sudo journalctl -u stokehold | grep "setup code". Every restart of the service before the owner exists prints a new code. If the page does not open, open TCP port 8443 at your host.

Adopting existing servers

If a LinuxGSM server already runs on the machine, there is nothing to reinstall. The panel may not manage other accounts on its own: the machine's owner adds the user name to a file that the helper reads and the panel cannot change.

echo factorio | sudo tee -a /etc/stokehold/adopt.conf

Then on the Add server page enter that Linux user name, press "Find servers" and add the script you need (fctrserver, mcserver, and so on). The file is read on every request, no restart needed. An adopted server gets the mode adopted. The panel installs nothing into such an account and creates no users. Names: one per line, no spaces, not root.

New server from the catalogue

"Install new server": pick a game from the LinuxGSM catalogue and a name. The panel creates a separate gs_… user, installs the packages LinuxGSM lists for the game (on Ubuntu and Debian) and installs the server. Progress is shown on the page, one install at a time. If it fails the reason is in the log: retry with the same or another name.

  • For Steam games LinuxGSM sometimes asks for extra packages: install them by hand as it suggests.
  • For Minecraft accept the EULA before the first start: open serverfiles/eula.txt in the file editor and set eula=true.

Server actions

Every server in the list has buttons. The command output is shown on the page and every action is written to the log.

ButtonLinuxGSM commandWhat it does
Statusdetailsshows the state and parameters of the server
Startstartstarts the server
Stopstopstops the server; right after a start it may not manage a clean stop and the process is killed
Restartrestartstops and starts
Backupbackupmakes a copy; LinuxGSM stops the server during the backup and starts it again
Check updatecheck-updatechecks whether a new game version is out

Schedules

Each server has a Schedule page: a backup, a restart or an update check every day at a set time (UTC) or every N hours. If the panel was off at the scheduled time the action runs once after it starts. The result of the last run is on the same page. Owners and admins can change schedules, viewers can only look.

A LinuxGSM backup stops the game server, so pick a time without players.

Config editor

The Files link of a server opens config editing. Only serverfiles and lgsm/config-lgsm are reachable, and only text files up to 256 KB. Before saving the panel keeps a copy of the previous version next to the file (.stokehold-bak). Changes take effect after the server restarts. The editor creates no new files and does not follow symbolic links. Only owners and admins see and change files: configs often hold passwords.

File manager

The Files link of a server opens the whole folder of the game user: walk through folders, create folders and empty files, upload and download files, rename, move and delete. It is available to owners and admins. The table sorts by name, size and modification date, folders always come first.

  • Upload: several files at once, up to 256 MB per go. A file appears in place only after the last part, so a broken upload never damages the old version.
  • Download: streamed, no size limit.
  • Editing: text files inside serverfiles and lgsm/config-lgsm (up to 256 KB) have an Edit link that keeps the previous version as .stokehold-bak.
  • Delete: always with a separate confirmation, several items can be selected (up to 200). There is no recycle bin and folders go with everything inside.
The manager sees only the game user's home folder and cannot leave it, neither through .. nor through symbolic links. .ssh, .bashrc, .profile and authorized_keys are hidden. Every change and download is written to the log.

Monitoring

The Monitoring page shows CPU, memory, disk, the one-minute load and the state of every server (including the player count when LinuxGSM prints it for that game). Once a minute the panel takes a sample and asks LinuxGSM for details. The last 60 samples are kept in memory, so the graph restarts with the panel. It works on Linux because it reads /proc. Monitoring is open to every plan.

Users and roles

RoleWhat it can do
ownereverything: users, licence, servers, schedules, files
adminmanage servers, schedules and files
viewerread only: status and update check

The owner creates users on the Users page: the password is generated and shown once, hand it over in person. The same page resets passwords and 2FA and deletes users. The last owner cannot be deleted. Everyone changes their own password on the Security page, which ends their other sessions. The interface language is switched with RU/EN in the header.

Security

  • Passwords are stored as argon2id. After several wrong passwords an account is locked for 15 minutes and attempts per address are limited.
  • TOTP two-factor: each code works once. Turning it off needs the password.
  • CSRF protection, a strict content policy for pages, cookies with HttpOnly, SameSite and Secure flags.
  • The privileged helper accepts a fixed set of operations only and runs them for allowed users. All its operations are logged (journalctl -u stokehold-helper).
  • Server files are opened through a single module that cannot escape the server directory.
  • Game servers run under ordinary users without containers: simpler and lighter, but weaker isolation than Docker.

HTTPS and a domain

Right after the install the panel answers over HTTPS on port 8443 with its own certificate (the browser warns once). That is the fallback entrance until you have a domain.

A domain from the settings (Let's Encrypt)

Settings → Domain and HTTPS: enter the domain and press Get a certificate. The panel checks that the domain's A record points to this server, opens ports 80 and 443 (in ufw, if active) and gets a trusted Let's Encrypt certificate by itself; it renews by itself too. The panel then opens at https://domain without warnings, and the phone app and notifications work there.

  • If port 80 or 443 is taken by another program (Caddy, nginx), the panel says so. Stop it, or keep it as a proxy to the panel (below).
  • A domain behind a proxy (such as Cloudflare's orange cloud) fails the DNS check: tick Skip the DNS check.
  • The fallback entrance on 8443 keeps working.

Your own reverse proxy

If the machine already runs Caddy or nginx, you can keep it:

panel.example.com {
    reverse_proxy 127.0.0.1:8080
}

Then in /etc/stokehold/stokehold.env replace -tls-listen :8443 with -trust-proxy and restart:

sudo systemctl restart stokehold

Do not enable -trust-proxy without a proxy: the address header can be forged.

Phone app and notifications

The panel installs like an app: an icon on the home screen, its own window, notifications. It needs trusted HTTPS, that is, the domain from the section above.

  • Android (Chrome): menu ⋮ → Install app.
  • iPhone (Safari): Share → Add to Home Screen. On iPhone notifications work only in the installed app, iOS 16.4 or newer.
  • Computer (Chrome, Edge): the install icon in the address bar.

Notifications are turned on per device: Security → Notifications on this device. You get: a server crashed or started, a new panel version (owners only), an account locked after wrong passwords (owners only). They travel encrypted through the browser's push service (Google, Mozilla, Apple); our server takes no part.

Restart after a crash

If a server stops by itself, without a command from the panel, a schedule or the API, the panel starts it again. At most three times an hour: after that the server is marked Crashed, auto-restart waits for you, and owners and admins get a notification. Stops, restarts, backups and updates from the panel are not crashes. It is set per server on the Overview tab and is on by default.

Sign-in from allowed addresses only

Settings → Sign in only from: one address or network per line (203.0.113.7, 10.0.0.0/8). Empty means from anywhere. From other addresses the panel refuses both sign-in and every page. A list that leaves out your current address cannot be saved, so you cannot lock yourself out.

Activity log

Log (owner only): every sign-in, failed attempt, server command, file edit and settings change. Filters by user, action, text (such as a server name) and dates, paging, and a CSV export for spreadsheets.

Licence and plans

The Licence page shows the plan, the included features and the term. Free: the whole open core (AGPL-3.0) with no server limit, no key, no contact with the licence server. Pro and Hosting are a closed build with extra features (below); Hosting adds several machines. Prices are not announced yet.

  • The owner enters the key on the Licence page. What is sent to the licence server (the key, an instance fingerprint, the panel version) is written on the page itself.
  • If the licence server is unreachable game servers keep running; paid features work until the end of the last confirmed term plus 30 days.
  • If a licence ends only the paid features go away; game servers are never stopped.

REST API Pro

API keys → create a key. It is shown once and stored only as a hash. A key acts with the role of the person who created it: a viewer's key can only read, an owner's or admin's can also control. Every action by a key is logged; after five wrong keys from one address within a minute a rate limit kicks in.

curl -H "Authorization: Bearer shapi_..." https://panel.example.com/api/v1/servers
curl -X POST -H "Authorization: Bearer shapi_..." https://panel.example.com/api/v1/servers/3/restart
curl -H "Authorization: Bearer shapi_..." https://panel.example.com/api/v1/metrics
RequestWhat it does
GET /api/v1/serverslist of servers, state, players, machine
GET /api/v1/servers/{id}one server
POST /api/v1/servers/{id}/{action}details, start, stop, restart, backup, check-update
GET /api/v1/metricsthe latest sample of the machine

Several machines Hosting

Game servers on other machines are managed from the same panel through a small agent, stokehold-agent. The agent accepts the panel's requests over HTTPS on port 9443 (open it for the panel's address only), makes a self-signed certificate on first start and prints its fingerprint; the secret is in /var/lib/stokehold-agent/secret. For existing LinuxGSM accounts on that machine create /etc/stokehold/adopt.conf as on the main one.

In the panel: Machines → add, enter the address, the fingerprint and the secret. The panel checks the fingerprint on every connection, so no certificate authority is needed. After that installing and adding a server offers a choice of machine. Schedules, the config editor and the state work for servers on any machine. A machine that still has servers cannot be removed.

Not yet: moving a server between machines; monitoring shows the main machine only.

Factorio mods Pro

A Factorio server has a Mods link in the list. It reads serverfiles/mods/mod-list.json and turns mods on or off, leaving the other fields of the file (a version, say) alone. You place the mod files yourself: the panel does not download from the mod portal because the portal needs your login and token and we do not want to keep those in the panel. For other games the page says so.

Game tools Pro

The "Game tools" link in a server's "⋯" menu opens a page with tabs. It works for Minecraft Java (mcserver and PaperMC pmcserver) and Factorio, for owners and admins.

Minecraft version and core

  • Changing the version. The list comes from Mojang (releases or snapshots) or PaperMC. The panel writes the version to the LinuxGSM settings (mcversion, and branch for Vanilla) and runs update; LinuxGSM itself does the download.
  • Another core. On an mcserver server you can install Paper, Purpur or Fabric: the panel downloads the core file over minecraft_server.jar and records it in serverfiles/stokehold-core.json. Forge and NeoForge are marked "soon": they need an installer run.
  • Careful. The LinuxGSM update command may replace an installed core with vanilla. For Paper and Purpur the panel pins the version so that does not happen; Fabric has no such protection, so do not run update by hand. You can go back to Vanilla on the same page.
  • Before a change the panel offers a backup and asks you to confirm the restart. Progress is shown step by step, and if something fails a server that was stopped is started again.

Plugins and mods

Search the Modrinth catalogue filtered by the core (plugins for Paper and Purpur, mods for Fabric) and the game version. "Install" downloads the file into serverfiles/plugins or serverfiles/mods and checks its checksum. Installed files can be removed on the same page. The panel only names required dependencies; install them separately. Restart the server afterwards. Vanilla has no plugins or mods.

Quick settings

Forms with validation for Minecraft's server.properties (description, player count, difficulty, mode, PvP, online-mode, view distance, whitelist, world seed) and for Factorio settings (name, description, players, password, visibility, commands). Only the listed values change; the rest of the file stays. The Factorio password is never sent back to the page: an empty field keeps the old one. Changes take effect after the server restarts.

Mods and plugins for other games

These LinuxGSM servers get a "Mods and plugins" tab. The mod framework is installed with one button (the server is stopped and started again); plugins can be disabled (they move to a sibling …-disabled folder), enabled again and removed.

GameFrameworkPlugins and mods
RustOxide (uMod), from GitHubuMod search, the .cs file checked against its checksum into oxide/plugins; reinstall Oxide after a Rust update
Counter-Strike 2Metamod:Source 2.0 (the gameinfo.gi line is added for you) and CounterStrikeSharpchecked: MatchZy, CS2-SimpleAdmin; upload your own through the file manager
ValheimBepInExPack Valheim from ThunderstoreThunderstore search, each mod in its own folder under BepInEx/plugins; dependencies are named
SCP: Secret LaboratoryEXILED, from GitHubyour own .dll into the EXILED and LabAPI folders through the file manager
Project Zomboidnone neededSteam Workshop: add by link, reorder, remove; the Mod ID is read from the item page
Garry's Modnone neededSteam Workshop collection (wscollectionid) and its items

Not yet tried on live game servers: paths and keys come from LinuxGSM and the frameworks' own documentation.

Version lists and downloads come only from official sources (Mojang, PaperMC, Purpur, Fabric, Modrinth) through the helper.

Player hub Pro

The Players section shows who is playing on all servers now, keeps the join history and how long everyone has played. Once a minute the panel asks the running servers in their own protocol: Steam A2S (CS2, Garry's Mod, Rust, Valheim, ARK, 7 Days to Die), Minecraft status (up to 12 names at a time), RCON for Factorio (the password comes from the LinuxGSM config). If a game does not report names, the server page keeps the player count only.

  • Player profile: total playtime, sessions per server, admin notes and tags (VIP, suspect).
  • Actions go to the game console: kick, ban, unban, whitelist (commands exist for Minecraft, Factorio, Project Zomboid, Rust, CS2 and Garry's Mod). The name and the reason are checked, the panel asks for confirmation and logs everything. Ban and whitelist lists are read from the game's files (Minecraft, Factorio), otherwise the bans issued from the panel are shown.
  • Discord: an admin makes a code on the profile and the player types the bot command /link CODE. The owner can set rules "role after N hours played": the community bot grants earned roles every 15 minutes and removes only roles from that list. The Discord token stays with the bot.

Discord and the public page Pro

Notifications

Integrations → webhook address. The panel posts there when a server starts or stops. Only discord.com/api/webhooks/… addresses are accepted.

Bot commands

The commands /servers, /server and /metrics come from your community's own bot. Create an application in the Discord Developer Portal and an API key on the panel, then run stokehold-bot with these variables:

DISCORD_BOT_TOKEN=...  DISCORD_PUBLIC_KEY=...  DISCORD_APP_ID=...
STOKEHOLD_PANEL_URL=https://panel.example.com
STOKEHOLD_PANEL_TOKEN=shapi_...
STOKEHOLD_CONTROL_ROLE="Server Admin"

Any member can call /servers; /server <name> <action> and /metrics are for members with the role from STOKEHOLD_CONTROL_ROLE. The bot reaches the panel only through an API key and needs no passwords.

Public status page

Integrations → Public status page. Without signing in, the address /status shows server names and states and nothing else.

Time machine Pro

Before every risky change the panel takes a snapshot by itself: a game update (from the panel, a schedule or the API), a config edit in the editor or the quick settings, installing or removing mods, plugins and frameworks, a Minecraft core or version switch. Several actions in a row (within two minutes) make one snapshot.

What is in it: the LinuxGSM config, the game's settings, the mod and plugin folders, frameworks (Oxide, BepInEx, Metamod, CounterStrikeSharp, EXILED). Before an update of a small game (Minecraft, Factorio, Valheim, SCP:SL) also the game files when they fit the cap, otherwise only configs and mods. For CS2, Rust, Project Zomboid and Garry's Mod the game files are too big and are left out. Worlds and saves are never in a snapshot: a rollback never takes the players' progress away.

The Time machine tab on the server page lists the snapshots by time and reason. Compare shows which files go back to how they were, which come back after being removed and which appeared later and will be removed. Restore first keeps the present state as a snapshot of its own (so a restore can be undone), then stops the server, puts the files back and starts it again if it was running.

Snapshots live in the game user's ~/stokehold-snapshots. The owner sets how many to keep per server (10 by default), the cap of one snapshot (2048 MB by default) and can turn automatic snapshots off.

Alerts Pro

The Alerts page (owner only) sends messages to Telegram and the Discord webhook. Rules: a server crashed (stopped by itself, not by a panel command or schedule), stopped, started, a new panel version is out, panel sign-in locked after failed attempts, disk, memory and CPU above a threshold (CPU: N minutes in a row). For disk, memory and CPU the panel writes once and once more when things are back to normal.

Telegram: create a bot with @BotFather (/newbot), message it or add it to a group, find the chat id with getUpdates, paste the token and the chat id, press Send a test message. The token is never shown on the page again. A server that keeps going down and up goes quiet for 30 minutes after one "unstable" message. Each alert links to the server page when the panel address is set.

Scenarios, Rust wipes, votes Pro

Manage → Scenarios (owners and admins). A scenario is "when an event happens, and if a condition holds, do these actions". It is built in a form, no code. Five templates get you started: a nightly restart with a warning, stop an empty server, a backup every 6 hours, bring it back after a crash with a message, a Rust wipe on the first Thursday of the month.

Events: a schedule (every day, on weekdays, the first weekday of the month, every N hours; times in UTC), a server state change (started, stopped, crashed by itself), "empty for N minutes", "N or more players", CPU or memory above a threshold for N minutes, a new panel version, by hand or by a vote. Conditions (optional): the server is running or stopped, players at most or at least a number. Actions (up to eight, in order): a server command (start, stop, restart, backup, update, start if stopped), a message in game, a wait, a countdown ("10, 5 and 1 minutes ahead"), a notice (Telegram, Discord, phone), a Rust wipe.

Every command goes the same way as the panel's buttons: with a time-machine snapshot and an audit entry. One scenario runs on a server at a time, and scenarios wait while an install or a restore runs. "What will happen" shows the steps as they will run, with the exact console command for the game and a warning when the game has no console chat (Valheim, for one). Each scenario lists its latest runs with their log.

In-game messages go through LinuxGSM send: say for Minecraft, Rust, CS2 and Garry's Mod, servermsg for Project Zomboid, bc for SCP:SL, plain text for Factorio.

Rust wipes

The "Rust wipe" action runs LinuxGSM's own map-wipe (map and saves) or full-wipe (blueprints too; Rust+ data stays): it stops the server, deletes the files under serverfiles/server/<identity>/ and starts it again. Before that the panel writes seed (new random, next from a list, or unchanged) and worldsize into the LinuxGSM config, and optionally makes a backup. The "first Thursday of the month at 19:00 UTC" template matches the Facepunch forced wipe. Wipe schedules show on the Rust game tools page.

Player votes

LinuxGSM can type into a game console but cannot read the chat, so a chat vote would need a mod for every game. A vote runs on its own page behind a random link instead: create it under Scenarios (question, server, the scenario to run on "yes", minimum "yes" votes, "yes" share, duration) and send the link to Discord, Telegram and the game (the panel can do that for you). Voting needs no account, once per browser and per address (the address is stored only as a hash); a vote that already passes closes at once, otherwise at its deadline. When it passes, the chosen scenario runs. Set the "Panel address" on the Alerts page so links carry it.

Commands and flags

The panel

stokehold version
stokehold serve [flags]
FlagDefaultWhat it does
-dbpanel.dbpath to the SQLite database
-listen127.0.0.1:8080plain address for a reverse proxy
-tls-listenoffalso serve HTTPS on this address with its own certificate, for example :8443
-secureoffmark cookies Secure (needed with HTTPS)
-trust-proxyofftake the client address from the proxy header (plain address only)
-helper/run/stokehold/helper.sockhelper socket
-license-urlthe project serverlicence server address

On an installed system the flags are in STOKEHOLD_FLAGS in /etc/stokehold/stokehold.env. After editing run sudo systemctl restart stokehold.

The installer

install.sh takes --channel stable|beta, --version vX.Y.Z, --no-start. Uninstall with uninstall.sh (--purge also deletes the panel's data).

Services

systemctl status stokehold stokehold-helper
journalctl -u stokehold -u stokehold-helper -e

Where things live

PathWhat is there
/usr/local/bin/stokehold, stokehold-helperthe programs
/etc/stokehold/stokehold.envpanel flags
/etc/stokehold/adopt.confLinux users whose servers may be adopted
/var/lib/stokehold/panel.dbthe panel database (users, servers, schedules, log)
/var/lib/stokehold/tls/the panel's own certificate
/run/stokehold/helper.sockhelper socket
/usr/local/lib/stokehold/previousthe previous version, for rollback

Update and uninstall

Update: run the install command again. The old files are kept; if the new version does not answer the health check within 20 seconds the installer brings the previous one back, restarts the services and says so. Uninstalling does not touch your game servers or their users.

curl -fsSL https://dl.stokehold.online/uninstall.sh | sudo bash

Without --purge the panel's data stays in /var/lib/stokehold and /etc/stokehold.

Troubleshooting

Look at the log first: journalctl -u stokehold -u stokehold-helper -e.

The panel does not open

  • curl -s http://127.0.0.1:8080/health on the machine itself should answer ok. No answer: systemctl status stokehold.
  • The installer's link does not open: open TCP port 8443 at your host and in the firewall.
  • Sign-in fails with the right password on plain HTTP: cookies with the Secure flag are not sent. Use HTTPS.
  • After several wrong passwords the account is locked for 15 minutes.

Lost the setup code

sudo journalctl -u stokehold | grep "setup code". It is printed at start while there is no user; a restart of the service gives a new one.

"Helper unavailable"

systemctl status stokehold-helper; the socket /run/stokehold/helper.sock must belong to stokehold with mode srw-------. The helper log shows every operation.

"Could not find servers for this user"

The user is not in /etc/stokehold/adopt.conf, or has no lgsm/config-lgsm/<name>server (LinuxGSM is not installed). For accounts made by the helper the name must start with gs_.

A command failed

The output is on the page. Typical causes: missing dependencies (Missing dependencies, install the named packages); the server is already running or stopped; LinuxGSM downloads its modules from GitHub every time, and without access to GitHub commands hang.

Reporting a problem

On GitHub Issues or in Discord: the panel version (stokehold version), OS, game and a log without passwords, tokens or licence keys.

FAQ

Do I need Docker?

No. Game servers run under ordinary Linux users, as in LinuxGSM.

Can I adopt a server that is already running?

Yes, see "Adopting existing servers". Nothing is reinstalled or overwritten.

What about game updates?

The update check is there. Snapshot rollback and version pinning are planned.

What is sent to your servers?

Free never contacts our servers and needs no key. The only outgoing request is a check with GitHub every few hours for a newer version (GitHub sees the server address); you can turn it off in the update settings. Pro sends the key, an instance public key and the panel version to verify the licence.

Do I need Discord for the panel to work?

No. The panel, licences and updates do not depend on Discord.

How do I check that the download is genuine?

The installer verifies the release signature and hashes itself. If the signature does not match, the install stops before any change.