docs Game Servers
Game Servers
Run dedicated game servers — Minecraft, Valheim, Counter-Strike 2, Terraria — with a console, file manager, world backups and one-click mods.
What Is a Game Server?
Introduced in v0.6.0, a game server is a third kind of service in a project, next to applications and compose stacks. It has no build and no domains: DeployKit runs a ready-made container image described by a game definition, publishes its ports directly on the host, keeps the world in Docker volumes, and gives you a live console, a file manager, scheduled world backups and (for supported games) mods and modpacks. Each server also gets the usual Logs and Monitoring tabs.
Game Definitions
Games are not bundled with DeployKit. They are fetched at runtime from the public template catalogue (the same registry as templates, set by TEMPLATES_REGISTRY_URL) and cached, so the instance needs outbound access to it. Each definition declares the image, ports, settings form, volumes, console type, stop behaviour, backup scope and minimum memory. When you create a server, its definition is copied into it: later changes to the catalogue only affect new servers. The catalogue currently offers:
| Game | Default ports | Console | Notes |
|---|---|---|---|
| Minecraft: Java Edition | 25565/tcp | RCON | Vanilla, Paper, Fabric or Forge; Java 8–25; mods, plugins and modpacks. Min 1.5 GB RAM |
| Valheim | 2456–2457/udp | None | Downloads ~1 GB from Steam on first start. Min 2 GB RAM |
| Counter-Strike 2 | 27015 udp + tcp | RCON | Downloads ~60 GB on first start; internet play needs a Steam Game Server Login Token. Min 2 GB RAM |
| Terraria | 7777/tcp | stdin | Vanilla dedicated server; world generated on first start. Min 1 GB RAM |
Each game also shows its own notes on the server's General tab — read them, they cover game-specific quirks such as which settings are rewritten on every start.
Creating a Game Server
From your project page click New game server, pick a game from the catalogue and fill in the form:
- Server name — lowercase letters, digits and hyphens, up to 41 characters, unique across the whole instance. It names the container (dk-gs-<name>) and its volumes
- Start from — for games with modpacks, either the plain game or a modpack (see Mods and Modpacks)
- Settings — the game's own form (e.g. EULA, server type, version, MOTD, passwords). Fields such as the world seed or world name are fixed after creation
- Ports — host ports for each game port (see below)
- Memory — a hard limit between 256 MB and 64 GB; the API rejects less than the game's minimum. For Minecraft the JVM heap is set to 75% of it
Secret fields left blank (such as the RCON password) are generated for you and shown once after creation — copy them then. Afterwards they are stored encrypted and only visible to project members who may view secrets. The server then provisions in the background; its status moves through provisioning to running. If Docker fails, the server shows error with the reason, and Start retries. The first start of most games downloads server files and can take minutes.
Creating a game server requires Operator access on the project (starting from a modpack is refused for users whose global role is Viewer). Changing settings on the Settings tab recreates the container, so a running server restarts and disconnects its players. Deleting a game server requires project Admin; by default its world volumes and backups are kept on the host unless you tick Also delete world data and backups.
Ports
Players connect straight to a port on the host — often UDP — not through Traefik. The form pre-fills each port with the game's default host port, and you can change it at creation or later in Settings.
- If a host port is already taken (by another game server, any published container port, or a port DeployKit itself uses such as 22, 80, 443, 5432 or 6379), the API refuses it and suggests a free port
- Suggestions come from GAME_PORT_RANGE (default 20000-40000); set this variable on the API to use another range
- The same number can be used once for TCP and once for UDP
- Some Steam games (Valheim, CS2) listen on the same port number inside the container as on the host, and Valheim's query port is always the game port + 1
- The General tab shows the address players connect to. Set PUBLIC_IP on the DeployKit server so it can show the full address, not just the port
Open the ports in your provider's firewall: Docker bypasses ufw, so a game port is reachable from the internet even if ufw says it is blocked — and a ufw allow rule is not what makes it work. Open (or restrict) each port in your cloud provider's firewall with the correct protocol, TCP or UDP. Cloudflare's proxy does not carry game traffic either, so these ports are exposed directly.
Console
The Console tab shows the server output live and, while the server is running, lets you type commands (with ↑/↓ history). Output from your commands is shown to everyone watching the console. How the command reaches the game depends on its definition:
- RCON (Minecraft, CS2) — sent over the internal game network; the RCON port is never published on the host, and its password is generated per server
- stdin (Terraria) — written to the server process's standard input
- exec — run through an injector inside the container, never through a shell
- None (Valheim) — the game has no remote console, so the Console tab is hidden
Commands are a single line of up to 1000 characters, limited to 20 commands every 10 seconds per user and server, and every command is recorded in the audit log. Sending commands requires the Operator global role and Operator access on the project — a console command can load a plugin, which is code. Stopping a server sends the game's own stop command first (e.g. stop or exit) so the world is saved, and only falls back to a signal if it does not exit in time.
Files
The Files tab browses the server's volumes, whether the server is running or stopped. You can open and edit text files (up to 1 MB; larger or binary files are downloaded instead), create folders, rename, delete, upload and download files or whole folders. Common config files (such as server.properties) have shortcuts at the top.
- Uploads are limited by GAME_UPLOAD_MAX_BYTES (256 MB by default)
- Reading and downloading files requires permission to view secrets (Operator or Admin on the project), because config files contain passwords
- Writing, uploading, renaming and deleting requires the Operator global role and Operator access on the project — an uploaded .jar is code
- Paths are confined to the volume; DeployKit works on files through a short-lived helper container, never directly on the host
Tip: If the panel sits behind Cloudflare, its free plan caps requests at 100 MB, so larger uploads fail regardless of GAME_UPLOAD_MAX_BYTES.
World Backups
The Backups tab takes compressed snapshots of the world (the paths the game definition marks for backup — e.g. only worlds_local/ for Valheim, only the cfg folder for CS2). Backups can be triggered manually or scheduled with a cron preset or a custom cron expression.
- Retention is a number of backups (1–100, default 7), not days — worlds are large
- If the game has a console, saving is paused and flushed during the backup (e.g. save-off / save-all flush / save-on for Minecraft) so the snapshot is consistent
- Restore stops the server, replaces the backed-up paths and starts it again if it was running. By default it first takes a safety backup of the current world
- Backups can be downloaded from the list; completed and failed backups trigger the usual backup notifications
- Backups and restores run one at a time per instance, so a queued backup may wait for another to finish
Warning: Archives are stored on the same disk as the server, under /var/backups/deploykit/@games/. If that disk fails, the backups go with it — copy them off the machine.
Mods and Modpacks
Games whose definition supports mods get a Mods tab — today that is Minecraft: Java Edition, with mods (Fabric, Forge) and plugins (Paper) from Modrinth and CurseForge. DeployKit keeps the list with each version pinned; the game image downloads the files when the container is rebuilt.
- Add mods by searching a catalogue (results are filtered to your server's loader and game version) or by pasting a link or id
- Changes are pending until you click Apply & restart, which takes a backup and recreates the container. Removing or disabling a mod, or changing the modpack, always forces that backup — and if the backup fails, nothing is applied
- Start a new server from a Modrinth or CurseForge modpack, or set one later; the modpack decides the server type and game version
- Check for updates compares your pinned versions with the catalogues
- Jars uploaded by hand to mods/ or plugins/ from the Files tab still work and are listed under On disk
- Adding, updating or removing mods and applying changes requires the Operator global role and Operator access on the project
Modrinth works without configuration. CurseForge search and installs need an API key, and Steam Workshop search needs a Steam Web API key: an Admin adds them in Settings → Game mods. Keys are validated against the provider before saving, stored encrypted, and only their last 4 characters are ever shown.
Gotchas: A modpack sets the Minecraft version but not the Java version — pick the matching Java tag yourself (current releases need Java 25). If the server follows the latest Minecraft version while its mods are pinned, the next game release will break them; the Mods tab warns you to set a fixed version. Client-only Modrinth projects are listed but cannot be installed.
Isolation and Hardening
Mods and plugins are third-party code running inside the container, so game servers are more locked down than applications:
- They run only on their own Docker network, deploykit-games — they cannot reach DeployKit's internal network (Postgres, Redis, your applications), and your applications cannot reach their RCON ports. The API joins this network on start-up to reach RCON
- no-new-privileges is set, the NET_RAW, MKNOD, AUDIT_WRITE, SYS_CHROOT, SETFCAP and SETPCAP capabilities are dropped, and each container is limited to 2048 processes
- Memory is a hard limit on the container
- Game servers on the same instance can see each other on deploykit-games; their RCON is protected by a per-server password
v0.6.0 also hardened the rest of the stack: Traefik now reads Docker through a read-only socket proxy, every service runs with no-new-privileges, and Redis requires a password — production installs must set REDIS_PASSWORD in .env or the stack will not start.
Limitations
- Game servers run only on the local server; remote servers are rejected
- The catalogue is fetched from the template registry; if it is unreachable and nothing is cached, no game can be created
- Server names share the dk-gs- prefix with other services: an application or database named gs-<x> occupies the container name dk-gs-<x>. DeployKit refuses to touch a container it does not own and asks you to rename the game server
- Valheim has no console, so stopping and backups rely on a signal and the game's own save on shutdown; crossplay is not enabled
- Only RAM can be sized from the dashboard; disk usage is not limited, and some games download tens of GB on first start