Install QLSM¶
There are three ways to get QLSM running, from easiest to most hands-on.
Option 1 — Vultr Startup Script (No Terminal Required)¶
The easiest path. Requires a Vultr account.
- Log in to Vultr and go to Manage → Startup Scripts.
- Create a new startup script and paste the Vultr QLSM startup script.
- Deploy a new VM. Under the Configure Software tab, select that startup script from the drop-down menu. Choose Debian 12 as the OS — Ubuntu is supported too, but 99k LAN rate is not compatible with it. For the plan, vc2-1c-1gb ($5/month) works fine.
- Wait approximately 10 minutes after the VM boots.
- QLSM will be running at the VM's IP address on port 80.
You never open a terminal. The startup script handles everything.
Custom domain (optional): If you have a domain pointing to the VM's IP, find this line in the startup script before saving it:
Replace :80 with your domain:
QLSM will obtain a free HTTPS certificate automatically via Let's Encrypt. Your domain's A record must point to the VM's IP before it boots.
Vultr API key (optional): If you want to provision additional Vultr-hosted QLDS game servers from within the UI, create a Vultr API key, then find this line in the startup script and uncomment it before saving it:
Paste your key between the quotes before saving the script.
Option 2 — One-Line Install Script¶
For any Debian 12 machine where you have SSH access:
With a custom domain (enables automatic HTTPS via Caddy):
SITE_ADDRESS=qlsm.example.com bash <(curl -fsSL https://raw.githubusercontent.com/dngrtech/qlsm/main/qlsm-install.sh)
With Vultr provisioning enabled from the start:
VULTR_API_KEY=your_vultr_api_key bash <(curl -fsSL https://raw.githubusercontent.com/dngrtech/qlsm/main/qlsm-install.sh)
With both a custom domain and Vultr provisioning:
SITE_ADDRESS=qlsm.example.com VULTR_API_KEY=your_vultr_api_key bash <(curl -fsSL https://raw.githubusercontent.com/dngrtech/qlsm/main/qlsm-install.sh)
The script:
1. Creates ~/qlsm/ with the required directory structure
2. Downloads docker-compose.yml and Caddyfile
3. Generates a .env file with secure random secrets
4. Pulls the Docker image and starts all services
QLSM will be available at the server's IP (or your domain) when it finishes.
Option 3 — Docker Compose (Full Control)¶
Clone the repo and configure everything yourself:
git clone https://github.com/dngrtech/qlsm.git && cd qlsm
cp .env.example .env
# Edit .env — set SITE_ADDRESS, REDIS_PASSWORD, VULTR_API_KEY if using Vultr
docker compose up -d
First Login¶
Default credentials: admin / admin
You will be prompted to change your password on first login.
Configuration (.env)¶
All options are set via environment variables. When using the install script, a .env file is generated at ~/qlsm/.env. When using Docker Compose directly, copy .env.example to .env and edit it.
After editing .env, restart the stack:
Core¶
| Variable | Description | Default |
|---|---|---|
SITE_ADDRESS |
Domain name or :port. A bare domain enables automatic HTTPS via Let's Encrypt. Use :80 for HTTP-only. |
:80 |
SECRET_KEY |
Signs JWT tokens and session cookies. Auto-generated on first run and persisted to disk. | auto-generated |
DEFAULT_ADMIN_USER |
Username of the bootstrap admin account created on first run. | admin |
FLASK_ENV |
Runtime profile: production or development. |
production |
Redis¶
| Variable | Description | Default |
|---|---|---|
REDIS_PASSWORD |
Password for the Redis task queue. Auto-generated by the installer. | auto-generated |
REDIS_URL |
Full Redis connection URI. Override when pointing at an external Redis instance. | redis://redis:6379/0 |
Database¶
| Variable | Description | Default |
|---|---|---|
DATABASE_URL |
SQLAlchemy connection URI. Override to use an external database. | sqlite:////app/data/qlds_ui.db |
Authentication¶
| Variable | Description | Default |
|---|---|---|
JWT_EXPIRATION_HOURS |
How long a login session lasts before the user must re-authenticate. | 24 |
FORCE_HTTPS |
Set to true to force HTTPS cookies when QLSM sits behind a TLS-terminating reverse proxy but SITE_ADDRESS is set to a port (e.g. :443). |
false |
CORS_ORIGINS |
Comma-separated list of allowed CORS origins. Leave blank when the frontend and API are served from the same origin. | (blank) |
Logging¶
| Variable | Description | Default |
|---|---|---|
LOG_LEVEL |
Logging verbosity: DEBUG, INFO, WARNING, or ERROR. |
INFO |
LOG_FORMAT |
Log output format: text (human-readable) or json (structured, useful for log aggregators). |
text |
LOG_FILE |
Optional file path to write logs to. If unset, logs go to stdout/stderr. | (blank) |
Cloud Provisioning¶
| Variable | Description | Default |
|---|---|---|
VULTR_API_KEY |
Vultr API key. Required only if you want QLSM to provision game server VMs via the Vultr provider. | (blank) |
Self-Host Provider¶
| Variable | Description | Default |
|---|---|---|
QLSM_HOST_USER |
SSH username used when QLSM connects back to the host machine for self-hosted game servers. | root |
QLSM_HOST_IP |
Pre-fills the "Server address" field when adding a self-host entry in the UI. | (blank) |
QLSM_SELF_HOST_SSH_TARGET |
Override the auto-detected SSH management target for the self-host provider. Only needed in non-standard network setups. | auto-detected |
Grafana (optional logging profile)¶
| Variable | Description | Default |
|---|---|---|
GRAFANA_PASSWORD |
Grafana admin password. Only used when starting the stack with --profile logging. |
admin |
Logging Stack (Optional)¶
QLSM ships an optional observability stack — Loki + Promtail + Grafana — for browsing and searching structured application logs. It is disabled by default and opt-in via a Docker Compose profile.
Components¶
| Container | Role |
|---|---|
| Loki | Log aggregation and storage. Receives log streams and indexes them for querying. |
| Promtail | Log collection agent. Reads container stdout/stderr (or systemd journal) and ships them to Loki. |
| Grafana | Web UI for querying and visualising logs. Pre-configured with Loki as a data source. |
Starting the Logging Stack¶
Add --profile logging to any docker compose command:
Set the Grafana admin password before starting (or in .env):
Accessing Grafana¶
Grafana listens on port 3000 of the server. Because this port is typically not exposed to the internet, access it through a secure tunnel (VSCode port forwardingm Tailscale VPN, etc.) rather than opening it in a firewall.