Utility for managing GameAP, GameAP Daemon and other parts of this.
You can use gameapctl to install, upgrade, inspect and manage GameAP, and view logs.
gameapctl is available for Linux, macOS and Windows.
The panel listens on port 80 (8025 with --scope=user). When that port is already taken, the
installer takes the first free one of 8025, 8026 and so on, probing up to ten of them, and says
which it took:
Port 80 is already in use, port 8025 will be used instead.
Ten occupied ports in a row point at the network configuration rather than at a busy port, so the search stops there and the installation continues with the usual warning.
A port chosen by hand — --port=8080 or --host=example.com:8080 — is never replaced: the
installer warns and names a free port instead, so a scripted install gets either the port it asked
for or an error. The installation form of the web UI (gameapctl ui) is pre-filled with the
detected port.
The panel terminates TLS itself, so there is no web server to configure. One command issues a self-signed certificate, points the panel at it and restarts it:
gameapctl panel https enable
gameapctl panel https status
gameapctl panel https disableThe certificate covers the configured HTTP_HOST, the machine's host name, every address of its
network interfaces and loopback, and is valid for 825 days. Narrow that down with --domain and
--ip, both repeatable, and reissue early with --force. A rerun keeps a certificate that still
covers every requested name and is not about to expire, so the browser exception you have already
accepted survives.
Being self-signed, the certificate is not trusted by anything until you add it to the trust store
of each machine that opens the panel; copy it from the path status prints. A certificate you
already have is used instead with --cert and --key, which are left where they are — point them
at the live files of an external ACME client and the panel picks up every renewal on restart.
HTTP keeps answering on its own port. --force-https redirects it to HTTPS; leave it off until you
are sure the HTTPS port is reachable, or you lose access to the panel from anywhere the redirect
target is blocked.
Both listeners are served by one process, and the panel exits when it cannot load the certificate
it is configured with. enable therefore verifies that the panel comes back up serving exactly the
certificate it just wrote, and restores the previous config.env when it does not.
That check goes to the address the panel binds, not to loopback. The panel listens on
HTTP_BIND_IP when that is set, otherwise on HTTP_HOST when it holds an address of this machine,
and otherwise on every interface: HTTP_HOST empty, 0.0.0.0, or a name that does not resolve to
one of the machine's own addresses. enable, disable and status all check it there and fall
back to loopback, so an installation configured with its public address is verified where it
actually answers. status prints the address it worked out.
| system scope | user scope | |
|---|---|---|
| Certificate | /etc/gameap/certs/panel.crt |
~/.config/gameap/certs/panel.crt |
| Private key | /etc/gameap/certs/panel.key |
~/.config/gameap/certs/panel.key |
| Default port | 443 | 8443 |
On Windows both files live in C:\gameap\web\certs.
Let's Encrypt lives under the same command, gameapctl panel https letsencrypt, and is described in
gameapctl panel https letsencrypt --help. ACME takes priority over a certificate on disk, so
enable refuses to run while it is configured, and disable switches both off.
On Linux both the panel and the daemon can be installed without root, into the current user's home directory, managed by systemd user units:
gameapctl panel install --scope=user --host=<host> --database=sqlite
gameapctl daemon install --scope=user --connect=grpc://<host>:31718/<setup-key>The scope is recorded at install time, so the other commands (start, stop, restart,
status, upgrade, uninstall, change-password, https) pick it up automatically.
Pass --scope=user explicitly if the state file in ~/.gameapctl was lost.
- Linux with systemd.
- A real login session, so that
systemctl --usercan reach the user bus: connect withssh user@hostormachinectl shell user@, not withsuorsudo -u. - Lingering, so that the services survive logout and start at boot. The installer only
attempts to enable it and warns when that is denied (common over SSH, where polkit may
refuse it). Check with
loginctl show-user $USER --property=Linger; if it printsLinger=no, runsudo loginctl enable-linger $USER.
| system scope | user scope | |
|---|---|---|
| Panel config | /etc/gameap/config.env |
~/.config/gameap/config.env |
| Panel data | /var/lib/gameap |
~/.local/share/gameap |
| Panel binary | /usr/bin/gameap |
~/.local/bin/gameap |
| Panel unit | /etc/systemd/system/gameap.service |
~/.config/systemd/user/gameap.service |
| Daemon config | /etc/gameap-daemon/gameap-daemon.yaml |
~/.config/gameap-daemon/gameap-daemon.yaml |
| Daemon work dir | /srv/gameap |
~/gameap |
| Daemon binary | /usr/bin/gameap-daemon |
~/.local/bin/gameap-daemon |
| Daemon unit | /etc/systemd/system/gameap-daemon.service |
~/.config/systemd/user/gameap-daemon.service |
The daemon work dir can be changed at install time with gameapctl daemon install --work-path=<dir>
(an absolute path; defaults to /srv/gameap in system scope, ~/gameap in user scope,
C:\gameap on Windows).
Note that ~/.local/bin is frequently missing from PATH in non-login shells. The services
are unaffected because the units use absolute paths, but to run gameap by name add it:
export PATH="$HOME/.local/bin:$PATH".
| Limitation | Reason |
|---|---|
| Ports below 1024 (80, 443) are normally unavailable; the panel defaults to 8025, HTTPS to 8443 | A systemd user unit cannot be granted CAP_NET_BIND_SERVICE. The installer probes the port rather than rejecting anything below 1024, so low ports still work where an administrator lowered net.ipv4.ip_unprivileged_port_start |
| No database server is installed; SQLite is the default | apt/dnf and system services require root. --database=mysql|postgres is only accepted for an existing server, described by --database-host, --database-name, --database-username and --database-password (plus --database-port for a non-default port) |
| System packages are not installed for the panel | It needs none of them: downloads, archive extraction, SQLite and password hashing are all in-process. Building with --github still needs git, go and npm preinstalled |
| The daemon has prerequisites of its own | curl and gpg must be preinstalled (plus tmux or docker if the process manager is overridden to one of them). SteamCMD additionally needs the 32-bit libraries lib32gcc, lib32stdc++6 and lib32z1 on a 64-bit system; the installer only warns about all of these |
Let's Encrypt http-01 is unavailable with --scope=user; use --challenge=dns-01 |
The challenge requires port 80; a system-scope install can use http-01 when port 80 is publicly reachable |
The gameap system user and group are not created |
Everything runs as the current user |
Autotests were performed on the following operating systems. Other operating systems may work as well, if they can run the required dependencies.
| Version | Supported | Notes |
|---|---|---|
| Server 2025 | ✔ | Latest manual test (v0.20.4): 26.11.2024 |
| Server 2022 | ✔ | Latest manual test (v0.9.1): 02.03.2024 |
| Server 2019 | ✔ | Latest manual test (v0.9.3): 02.03.2024 |
| Server 2016 | ✔ | Latest manual test (v0.9.3): 10.03.2024 |
| 11 | ✔ | Latest manual test (v0.20.4): 26.11.2025 |
| 10 | ✔ | Latest manual test (v0.10.0): 26.05.2024 |
| Version | Supported | Notes |
|---|---|---|
| 13 (trixie) | ✔ | |
| 12 (bookworm) | ✔ | Latest manual test (v0.4.1): 12.11.2023 |
| 11 (bullseye) | ✔ | Latest manual test (v0.4.3): 13.11.2023 |
| 10 (buster) | ✔ | Latest manual test (v0.10.0): 25.05.2024 |
| 9 (stretch) | ✔ |
| Version | Supported | Notes |
|---|---|---|
| 24.04 | ✔ | Latest manual test (v0.10.0): 15.05.2024 |
| 22.04 | ✔ | Latest manual test (v0.4.1): 12.11.2023 |
| 20.04 | ✔ | Latest manual test (v0.5.1): 16.11.2023 |
| 18.04 | ✔ | Latest manual test (v0.5.0): 16.11.2023, used chrooted php package |
| 16.04 | ✔ | Latest manual test (v0.5.6): 16.11.2023, used chrooted php package |
| Version | Supported | Notes |
|---|---|---|
| Stream 10 | ✔ | Latest manual test (v0.10.4): 06.11.2025 |
| Stream 9 | ✔ | Latest manual test (v0.6.1): 17.11.2023 |
| Stream 8 | ✔ | Latest manual test (v0.6.2): 17.11.2023 |
| 7 | ✔ | Latest manual test (v0.6.2): 17.11.2023 |
| Version | Supported | Notes Z |
|---|---|---|
| 9 | ✔ | Latest manual test (v0.6.10): 12.02.2024 |
| Version | Supported | Notes |
|---|---|---|
| 2023 | Latest manual test (v0.7.1): 12.02.2024 Web part tested with SQLite Database Amazon Linux 2023 no longer ships any i686 user space |
| Version | Supported | Notes |
|---|---|---|
| 9.3 | Latest manual test (v0.10.0): 15.05.2024 Web part tested with MySQL Database Rocky Linux 9.3 no longer ships any i686 user space |
| Version | Supported | Notes |
|---|---|---|
| 43 | ✔ | Latest manual test (v0.20.6): 26.11.2024 |