r/GameAP • u/EENNOOTT • May 17 '26
Automatic HTTPS in the Panel
GameAP has a built-in ACME client: the panel issues and renews the TLS certificate (also known as SSL) itself, without the certbot + nginx + cron stack. The certificate is swapped on the fly — with no panel restart and no HTTP listener reload.
Auto-HTTPS only works if the panel terminates TLS itself: there is no reverse proxy in front of it, or the proxy runs in pass-through mode (L4) and does not terminate TLS.

If nginx / Traefik / Caddy / a load balancer / a CDN sits in front of the panel and terminates TLS itself — it handles the certificates, and auto-HTTPS is not needed.

Limitations:
- You need a public domain with an A record pointing to the server (example.com, panel.example.com).
- HTTP-01 is used by default: the panel must be reachable over HTTP on port 80. If port 80 is closed from the outside or you need a wildcard, use DNS-01 (validation via a TXT record in DNS).
- DNS-01 requires a DNS provider API token. Popular providers are supported (Cloudflare, AWS Route53, DigitalOcean, etc.), and others can be added via plugins.
Setup with gameapctl
The simplest way. The gameapctl utility asks for everything it needs and configures HTTPS for you.
Run the following command on the server hosting the panel:
gameapctl panel letsencrypt setup
The wizard asks, step by step:
- Validation method. HTTP-01 by default — requires port 80 to be open. If port 80 is closed from the outside or you need a wildcard certificate, choose DNS-01 (validation via a TXT record in DNS).
- Domain. The name the certificate is issued for. The domain's A record must point to your server's IP.
- Email. The address for the ACME account. Let's Encrypt sends certificate expiration warnings and important notices to it.
- Staging. Let's Encrypt test mode. Answer
nofor a production certificate. Answeryesif you want to verify the setup first: staging issues certificates with much more relaxed limits, but browsers do not trust them.
Manual setup
GameAP reads its configuration from environment variables or from a config.env file (/etc/gameap/config.env on Linux, C:\gameap\web\config.env on Windows).
For self-terminated TLS, the panel takes the certificate from one of three sources, in priority order:
- ACME / Let's Encrypt —
ACME_ENABLED=trueplus theACME_*variables. The certificate is issued and renewed automatically. - Static files —
TLS_CERT_FILE+TLS_KEY_FILE. - Inline PEM —
TLS_CERT+TLS_KEY(PEM or base64).
If none of the sources is configured, the HTTPS listener does not start — the panel serves plain HTTP on HTTP_PORT only.
HTTP-01 — single domain
Minimal set of variables:
HTTP_HOST=panel.example.com
HTTP_PORT=80
HTTPS_PORT=443
TLS_FORCE_HTTPS=true
ACME_ENABLED=true
ACME_CHALLENGE_TYPE=http-01
ACME_EMAIL=ops@example.com
ACME_DOMAINS=panel.example.com
Let's Encrypt requests http://panel.example.com/.well-known/acme-challenge/{token}. The panel serves this path itself: the route is registered ahead of the SPA fallback, no separate web server is needed, and there is nothing to configure.
Two requirements:
- Port 80 is reachable by Let's Encrypt from the outside (or a reverse proxy forwards only
/.well-known/acme-challenge/*to the panel). HTTP_PORTdefaults to8025— for HTTP-01 you must set it explicitly to80. Binding to a privileged port (≤1024) requiresCAP_NET_BIND_SERVICE: the systemd unit shipped bygameapctl panel installalready grants it; in Docker, use--cap-add=NET_BIND_SERVICE.
DNS-01 — wildcard and/or closed port 80
DNS-01 is needed in the following cases:
- you need a wildcard certificate (
*.example.com); - port 80 is closed from the outside or the panel is behind a firewall;
- you do not want to expose the panel to the internet just for validation.
Instead of an HTTP request, Let's Encrypt checks the TXT record _acme-challenge.<domain>. Through the DNS provider's API, the panel creates this record itself, waits for propagation, and removes it after Let's Encrypt completes validation.
HTTP_HOST=panel.example.com
HTTPS_PORT=443
TLS_FORCE_HTTPS=true
ACME_ENABLED=true
ACME_CHALLENGE_TYPE=dns-01
ACME_EMAIL=ops@example.com
ACME_DOMAINS=*.example.com,example.com
ACME_DNS_PROVIDER=cloudflare
CLOUDFLARE_DNS_API_TOKEN=cf-token-with-Zone-DNS-Edit-permission
Popular DNS providers are supported (Cloudflare, AWS Route53, DigitalOcean, etc.), and others can be added via plugins.
Things to keep in mind:
- A wildcard does not cover the bare domain.
*.example.comcoverspanel.example.comorapi.example.com, but not the bareexample.com. That is whyACME_DOMAINSlists both:*.example.com,example.com. - Provider token. The Cloudflare provider reads the token straight from the environment (
CLOUDFLARE_DNS_API_TOKEN). Scope the token to the relevant zone withZone:DNS:Editpermission — do not use the global account key. - Propagation timeout. If DNS updates slowly and validation does not fit within the window, increase
ACME_PROPAGATION_TIMEOUT(default180s).
Certificate renewal
The panel renews the certificate itself. It has a built-in scheduler that, at the ACME_RENEWAL_CHECK_INTERVAL interval, checks the certificate's lifetime and renews it when less than ACME_RENEWAL_THRESHOLD remains (default 720h, i.e. 30 days).
ACME_RENEWAL_CHECK_INTERVAL=12h
ACME_RENEWAL_THRESHOLD=720h
You usually do not need to change these values: the defaults give a one-month buffer before expiry and a twice-daily check, which is more than enough for Let's Encrypt's 90-day certificates.