Process Managers
A process manager is the component GameAP Daemon uses to run game servers on a node. It is responsible for starting, stopping, and restarting game servers, monitoring their status, collecting statistics, and limiting resources (CPU / RAM).
By default the daemon picks the manager itself. On Linux it uses systemd; when the daemon itself runs inside a
container, or systemctl is missing, or systemd is not PID 1, it falls back to tmux, and to simple when tmux is not
installed either. On Windows the default is Shawl, on macOS — tmux.
Configuration
The process manager is configured in the process_manager block of the
GameAP Daemon configuration file. When a node is added through the panel, the manager can be
chosen in advance: expand Additional settings and pick it in the Process Manager field. The Linux tab offers
Auto (Recommended), Simple (Custom scripts controlled), SystemD, Docker, Podman and Tmux; the Windows tab offers
only Auto (Recommended), Simple (Custom scripts controlled), WinSW and Shawl, so Docker on Windows has to be set
in the configuration file by hand.
Basic Structure
process_manager:
name: <manager_name>
config:
<key>: <value>
Available managers:
- Linux:
systemd(default),docker,podman,tmux,simple - macOS:
tmux(default),docker,podman,simple - Windows:
shawl(default),winsw,simple,docker(Podman is not supported on Windows)
The contents of config depend on the manager:
| Manager | Keys in config |
|---|---|
systemd |
scope — system or user, see Systemd Configuration |
docker |
host, cert_path, api_version, plus any container parameter as a node-wide default |
podman |
socket_path, plus any container parameter as a node-wide default |
tmux, simple, shawl, winsw |
none |
scopeis accepted only bysystemd. With any other manager the daemon refuses to start with the errorprocess_manager.config.scope is only valid for process_manager.name=systemd.
Restart After a Crash
Who brings a crashed game server back differs between managers. With systemd it is the unit itself (Restart=always),
with Shawl — the service (--restart), with WinSW — the service’s onfailure actions. With tmux, simple, Docker and
Podman the daemon restarts the server itself: every 5 seconds it checks the state of all servers and starts the ones
that are down. Servers that have been idle for a long time are checked less often, so such a restart can be delayed by
up to about two minutes. In every case the server’s Autostart on crash setting is respected: a server that was
stopped on purpose is never started again.
Statistics
systemd, Docker and Podman report the full set of metrics: CPU, memory usage and limit, network traffic, disk I/O and
process count. tmux, simple, Shawl and WinSW report only whether the server is running. Metric collection is described
in GameAP Daemon.
Linux and macOS
Systemd
Platforms: Linux.
Used by default on Linux. It is a modern process manager that provides high performance and reliability. Isolation capabilities for this process manager are limited.
| Feature | |
|---|---|
| Start, stop, restart servers | ✅ |
| Restart after a crash | ✅ The unit, Restart=always |
| Statistics | ✅ |
| Resource limits (CPU / RAM) | ✅ |
| Console reading | ✅ |
| Sending commands to console | ✅ |
| Isolation | ⚠️ Limited |
Units generated before the daemon started writing the
CPUAccounting=yes,MemoryAccounting=yes,IOAccounting=yes,IPAccounting=yesandTasksAccounting=yesdirectives report zero statistics until the server is restarted and the unit file is regenerated.
Systemd Configuration
Systemd does not require additional configuration. The Daemon automatically creates and manages unit files.
The only parameter is scope:
| Config Key | Description | Default |
|---|---|---|
scope |
Where the units live and who runs them: system or user |
system |
system— units are written to/etc/systemd/system; the daemon needs the rights to manage system units (normally it runs as root). Every unit getsUser=/Group=from the game server’s user (the Su User field), so servers on one node can run under different users.user— units are written to~/.config/systemd/user/and managed withsystemctl --user. The daemon runs as a regular user and all game servers run as that same user. Lingering must be enabled for that user (sudo loginctl enable-linger <user>), otherwise the daemon warns that user services will be killed at logout;XDG_RUNTIME_DIR(usually/run/user/<uid>) must be accessible. A server whose Su User field names a different user fails to start withserver requests user "..." but daemon runs as "...".
Configuration Examples
Default (system scope):
process_manager:
name: systemd
User scope:
process_manager:
name: systemd
config:
scope: user
Docker
Platforms: Linux, macOS, Windows.
Docker runs every game server in its own container, isolating it from the node and from the other servers.
Docker or Podman is required for games imported from Pelican or Pterodactyl eggs. An imported egg carries no GameAP installation rules: its files are installed by a script that runs in the egg’s own container image (
docker_installation_image+docker_installation_script). Undersystemd,tmux,simple,shawlorwinswsuch a server cannot be installed — the installation fails withcould not determine the rules for installing the game. See Games Import.
| Feature | |
|---|---|
| Start, stop, restart servers | ✅ |
| Restart after a crash | ✅ GameAP Daemon |
| Statistics | ✅ |
| Resource limits (CPU / RAM) | ✅ |
| Console reading | ✅ |
| Sending commands to console | ✅ |
| Isolation | ✅ |
Docker Configuration
Connection Parameters
| Config Key | Description | Default |
|---|---|---|
host |
Address of the Docker daemon, for example unix:///var/run/docker.sock or tcp://10.0.0.5:2376 |
— |
cert_path |
Directory with ca.pem, cert.pem and key.pem for a TLS connection |
— |
api_version |
Docker API version to use | — |
If none of the three keys is set, the connection is configured from the standard Docker environment variables
(DOCKER_HOST, DOCKER_CERT_PATH, DOCKER_TLS_VERIFY, DOCKER_API_VERSION) — with none of them set, the local
Docker daemon is used.
Any container parameter can also be placed in config as a default for the whole node, with
or without the docker_ prefix (image and docker_image are equivalent). Do not set container_name node-wide:
every server on the node would get the same container name.
Configuration Examples
Minimal:
process_manager:
name: docker
Remote Docker daemon over TLS:
process_manager:
name: docker
config:
host: tcp://10.0.0.5:2376
cert_path: /etc/gameap-daemon/docker-certs
Node-wide container defaults:
process_manager:
name: docker
config:
image: docker.io/gameap/debian:latest
workdir: /server
dns: 8.8.8.8,1.1.1.1
Container Parameters
Docker and Podman read the container settings from the same keys (Podman keeps the docker_ prefix). The keys are
entered in the panel as metadata: in Administration → Games, both the game form and the mod form have a
Metadata tab. The ? button next to the key field opens the Metadata keys reference with a description and an
example for every key and inserts the chosen key into the field.
| Key | Description | Default |
|---|---|---|
docker_image |
Image the game server runs in. :latest is added when the tag is omitted |
docker.io/gameap/debian |
docker_container_name |
Container name | server XID |
docker_workdir |
Working directory inside the container; the server directory is mounted there | /server |
docker_network_mode |
Network mode. Only the value host has an effect and enables host networking |
bridge |
docker_dns |
DNS servers for the container, comma-separated. IP addresses only | — |
docker_volumes |
Additional mounts in the form source:target[:ro], comma-separated or as a JSON array. A relative source is resolved against the server directory |
— |
docker_capabilities |
Additional Linux capabilities, comma-separated without spaces | — |
docker_privileged |
Privileged mode. Only the exact string true enables it |
— |
docker_installation_image |
Image for the installation step. Works only together with docker_installation_script |
— |
docker_installation_script |
Installation script body. Runs inside the installation container in /mnt/server, where the server directory is mounted |
— |
docker_installation_entrypoint |
Interpreter for the installation script | shebang, otherwise /bin/sh |
docker_installation_user |
User the installation runs as | root |
Resolution order. The daemon looks a key up in this order and takes the first non-empty string value:
- game server variables — the mod’s variable defaults, then the values set for the server itself;
- game mod metadata;
- game metadata;
process_manager.configin the daemon configuration file, where the key may be written with or without thedocker_prefix.
Only string values are used; a number or a boolean in metadata is ignored.
The Metadata block of the game server itself is not read by GameAP Daemon 4.1.2, even though the panel’s reference offers the container keys there. To override a key for a single server, add a mod variable with the same name (for example
docker_image) and set its value in the server’s Settings.
Games imported from Pelican or Pterodactyl eggs get the following keys in the metadata of the Default mod:
docker_image,docker_installation_image,docker_installation_script,docker_installation_entrypoint,docker_installation_user: rootanddocker_workdir: /home/container. The import also storesdocker_startup_done(the egg’s startup-done marker) in the mod metadata andpelican_egg(the original egg JSON) in both the game and the mod metadata. Neither of these two keys is read by GameAP Daemon; they are kept for reference.
How It Works
Applies to Docker and Podman alike unless stated otherwise.
- The container is named after the server XID (
docker_container_nameoverrides it). Containers created by older daemon versions and named after the server UUID are still found. - The server directory is bind-mounted into the container at
docker_workdir(default/server), which is also the working directory. Only this directory and the additionaldocker_volumesmounts survive a restart: the container itself is removed on every stop. - The game process runs as the uid:gid of the game server’s user (the Su User field). That user must exist on the
node even though the server runs in a container, otherwise the start fails with
failed to lookup user. When the field is empty, the daemon’s own user is used. - Ports are published on the server’s IP address: the connect port over TCP and UDP, the query port over UDP and the RCON port over TCP when they differ from the connect port.
- CPU and RAM limits are taken from the server’s resource limits in the panel (CPU in millicores, RAM in bytes). There are no metadata keys for limits.
- Neither Docker nor Podman restarts the container on its own: the Docker container is created with the restart policy
disabled, and the Podman container is created without a restart policy at all (Podman’s own default is
no). A crashed container is restarted by the daemon according to the server’s Autostart on crash setting. - Stopping waits up to 30 seconds for the process to exit, then the container is removed.
- The console shows the last 500 lines of the container log. A command from the console is delivered differently:
Docker attaches to the container’s stdin and writes the command there; Podman runs the command as an
execinside the container, so it does not reach the game process’s stdin.
Installation in a Container
If both docker_installation_image and docker_installation_script are set, the installation runs in a separate
container:
- the installation image is pulled;
- the script is written to
.gameap_install.shin the server directory (the file is removed afterwards); - a temporary container
gameap-install-<XID>is created with the server directory mounted at/mnt/serverand the server’s environment variables; - the script is run by the interpreter from
docker_installation_entrypoint(a bare name such asashis looked up in/bin/), otherwise by the interpreter from the script’s shebang, otherwise by/bin/sh; - the log is streamed live with Docker; with Podman it is collected after the container exits;
- after a successful run the files are chowned to the server’s user, and the container is removed.
The installation runs as root unless docker_installation_user says otherwise. A non-zero exit code fails the
installation.
The container step runs after the regular installation from the game’s repositories or Steam, if the game has any. If
the game has neither installation rules nor both container keys, the installation fails with
could not determine the rules for installing the game. If only one of the two keys is set, the container step is
skipped and the daemon only pulls the runtime image.
Podman
Platforms: Linux, macOS.
Podman is an alternative to Docker that provides isolation of game servers in containers. It reads the same
container parameters as Docker (the keys keep the docker_ prefix) and behaves the same way at
run time, but connects differently: it talks to the libpod REST API (v4.0.0) over a Unix socket, and of the connection
parameters only socket_path is used — host, cert_path and api_version are ignored.
| Feature | |
|---|---|
| Start, stop, restart servers | ✅ |
| Restart after a crash | ✅ GameAP Daemon |
| Statistics | ✅ |
| Resource limits (CPU / RAM) | ✅ |
| Console reading | ✅ |
| Sending commands to console | ⚠️ See How It Works |
| Isolation | ✅ |
Podman Configuration
The Podman API socket must be running. Rootless:
systemctl --user enable --now podman.socket
Root:
sudo systemctl enable --now podman.socket
Specific Parameters
| Config Key | Description | Default |
|---|---|---|
socket_path |
Path to the Podman Unix socket | unix:///run/user/<uid>/podman/podman.sock when the daemon runs as a non-root user and that socket exists, otherwise unix:///run/podman/podman.sock |
Configuration Examples
Rootless (default):
process_manager:
name: podman
Rootful:
process_manager:
name: podman
config:
socket_path: "unix:///run/podman/podman.sock"
Tmux
Platforms: Linux, macOS.
Tmux is a terminal multiplexer. It is currently a deprecated process manager in GameAP, which is not recommended for use as it does not provide full functionality.
Tmux can be used on older systems, as well as inside containers (LXC, Docker/Podman, etc.), virtual systems, and systems that do not have Systemd and/or cannot use Docker or Podman.
| Feature | |
|---|---|
| Start, stop, restart servers | ✅ |
| Restart after a crash | ✅ GameAP Daemon |
| Statistics | ⚠️ Only whether the server is running |
| Resource limits (CPU / RAM) | ❌ |
| Console reading | ✅ |
| Sending commands to console | ✅ |
| Isolation | ❌ |
Tmux Configuration
Tmux does not require additional configuration.
Configuration Example
process_manager:
name: tmux
Simple
Platforms: Linux, macOS, Windows. In the panel it is listed as Simple (Custom scripts controlled).
simple has no built-in way of talking to a game server: it only runs the commands from the scripts block of the
daemon configuration, substituting the server’s start, stop or restart command for {command}. The status and
console-reading scripts are called without a server command, so with the default {command} template they expand to
nothing and every such call fails with empty command. Without a working status script the server’s state cannot be
determined: it is never reported to the panel and is not restarted after a crash.
On Linux the daemon falls back to simple when neither systemd nor tmux is available.
| Feature | |
|---|---|
| Start, stop, restart servers | ✅ Via the configured scripts |
| Restart after a crash | ✅ GameAP Daemon, requires a status script |
| Statistics | ⚠️ Only whether the server is running |
| Resource limits (CPU / RAM) | ❌ |
| Console reading | ⚠️ Requires a console-reading script |
| Sending commands to console | ⚠️ Requires a command script |
| Isolation | ❌ |
Simple Configuration
process_manager:
name: simple
Windows
Shawl
Platforms: Windows.
Shawl is a lightweight process manager for Windows that provides basic functionality for managing game servers. It is written in Rust and uses the Windows API to run applications as Windows services.
| Feature | |
|---|---|
| Start, stop, restart servers | ✅ |
| Restart after a crash | ✅ Shawl, --restart |
| Statistics | ⚠️ Only whether the server is running |
| Resource limits (CPU / RAM) | ❌ |
| Console reading | ✅ |
| Sending commands to console | ❌ |
| Isolation | ❌ |
Shawl Configuration
Shawl does not require additional configuration.
Operation Details
| Parameter | Value |
|---|---|
| Configuration directory | C:\gameap\services |
| Stop timeout | 10000 ms |
| Log rotation | Daily |
| Log retention | 7 days |
Configuration Example
process_manager:
name: shawl
WinSW
Platforms: Windows.
WinSW (Windows Service Wrapper) is a process manager written in C#. It allows running applications as Windows services. In GameAP, it is a deprecated manager and has been replaced by Shawl.
| Feature | |
|---|---|
| Start, stop, restart servers | ✅ |
| Restart after a crash | ✅ WinSW, onfailure actions |
| Statistics | ⚠️ Only whether the server is running |
| Resource limits (CPU / RAM) | ❌ |
| Console reading | ✅ |
| Sending commands to console | ❌ |
| Isolation | ❌ |
WinSW Configuration
WinSW does not require additional configuration.
Operation Details
| Parameter | Value |
|---|---|
| Configuration directory | C:\gameap\services |
| Configuration format | XML |
Configuration Example
process_manager:
name: winsw
Troubleshooting
Docker
failed to connect to docker daemon — the daemon cannot reach Docker. Check that Docker is running
(systemctl status docker) and that the user the daemon runs as may access /var/run/docker.sock — usually by being
a member of the docker group (sudo usermod -aG docker <user>, then log in again). With a remote Docker daemon check
host and cert_path.
failed to lookup user <name> — the game server’s Su User does not exist on the node. Create the OS user or
change the field.
Podman
Connection errors mentioning the socket path — the Podman API socket is not running or lives elsewhere. Rootless:
systemctl --user enable --now podman.socket
ls -la /run/user/$(id -u)/podman/podman.sock
curl --unix-socket /run/user/$(id -u)/podman/podman.sock http://d/v4.0.0/libpod/info
If the daemon runs as root, the socket is /run/podman/podman.sock (sudo systemctl enable --now podman.socket).
When the socket is at a non-standard path, set socket_path.
Docker and Podman
could not determine the rules for installing the game when installing a server from an imported Pelican or
Pterodactyl egg — the node is running a process manager other than Docker or Podman. Switch the manager in the
daemon configuration and restart the daemon.