QMServer
Бэкенд на Go (Gin) и MySQL (GORM). Единая точка для QMLauncher, QMAdmin и QMWeb: аутентификация, профили серверов, моды, новости, скины, настройки лаунчера и облачных пользователей.
Платформа: официально только Linux x86_64 (GOOS=linux, GOARCH=amd64). Docker-образы и цель make build-release рассчитаны на amd64; ARM / AArch64 не поддерживаются.
Документация API
На развёрнутом сервере:
- Swagger UI:
/swagger/index.html(редирект с/docs) - ReDoc:
/redoc - OpenAPI:
/swagger/doc.json
В репозитории QMServer: каталог docs/ (swagger.yaml, swagger.json). Генерация: make swagger или swag init -g docs.go -o docs.
Модули и клиентские интеграции
Часть API управляется флагами в таблице settings. При первом запуске QMServer создаёт записи со значением 0 (выключено); пустое значение для этих ключей нормализуется в «выкл». Управление из QMAdmin: разделы «Модули» и «Интеграции».
Состав модулей и интеграций зависит от варианта сборки (публичная без Go-тега cloud и Cloud с -tags cloud — один и тот же Git-репозиторий, см. BUILD.md в QMServer).
Модули
| Метод | Путь | Описание |
|---|---|---|
| GET | /admin/modules | Список модулей и флагов |
| PATCH | /admin/modules/:id | JSON {"enabled": true} или {"enabled": false} |
QMServer Cloud
id (PATCH) | Ключ в БД | Описание |
|---|---|---|
qmbilling | module_qmbilling | Биллинг и подписки (/api/v1/modules/qmbilling/…). Нельзя включить без включённой интеграции Removed auth stack; при выключении интеграции Removed auth stack модуль QMBilling выключается автоматически. |
dedicated | module_dedicated | Выделенные хосты и агент QMClient |
minecraft | module_game_minecraft | Профили Minecraft и связанные API |
counter_strike_16 | module_game_counter_strike_16 | Профили CS 1.6 / HLDS |
В Cloud нет модуля legacy-auth: встроенный стек Removed auth stack (OAuth, JWT для входа «через Removed auth stack») управляется интеграцией legacy-auth (см. ниже).
QMServer Free
id (PATCH) | Ключ в БД | Описание |
|---|---|---|
dedicated | module_dedicated | Выделенные хосты и агент QMClient |
minecraft | module_game_minecraft | Профили Minecraft и связанные API |
counter_strike_16 | module_game_counter_strike_16 | Профили CS 1.6 / HLDS |
В Free нет встроенного Removed auth stack и нет модуля QMBilling (соответствующие маршруты отсутствуют). Доверие к JWT внешнего IdP при необходимости настраивается через окружение (LEGACY_ENV_ и связанные параметры) — без встроенного OAuth Removed auth stack на стороне QMServer.
При выключенном модуле соответствующие маршруты отвечают 404 с полем detail (например, отключён модуль Minecraft или Dedicated).
Интеграции (QMLauncher, QMWeb; в Cloud — ещё Removed auth stack)
| Метод | Путь | Описание |
|---|---|---|
| GET | /admin/integrations | Список интеграций |
| PATCH | /admin/integrations/:id | JSON {"enabled": true} или {"enabled": false} |
Общие для Cloud и Free: qmlauncher → integration_qmlauncher, qmweb → integration_qmweb.
Только QMServer Cloud: legacy-auth → integration_cloud_auth — встроенный OAuth/JWKS Removed auth stack на стороне QMServer (маршруты вида /api/v1/modules/legacy-auth/… для входа и выдачи токенов). В Free этой интеграции нет.
Поведение:
GET /news: доступен, если включена хотя бы одна интеграция (QMLauncher или QMWeb). Иначе 404.GET /serversбез прав администратора: если обе интеграции выключены — ответ с пустымserver_profiles. Администраторы получают полный список для управления.- Интеграция QMWeb: при выключении недоступны публичные
GET /settings/referralиGET /settings/inventory-sync(404), а также приём инвентаря с игрового сервераPOST /inventory(QXSync): для него дополнительно должен быть включён модуль Minecraft (иначе 404 по отключённому модулю раньше в цепочке). - Интеграция QMLauncher: при выключении недоступны, в частности: игровые аккаунты, скины и прокси, публичный
GET /settings/skin-providers,GET /settings/qmlauncher-msa-client-id,GET /servers/:id/mod-config, маршруты/launcher/*, а в сборке Cloud —POST /check/server,GET /check/data/...,GET /download/...(404 сdetail).
Админские PATCH настроек (скины, CurseForge, MSA, inventory-sync и т.д.) не блокируются отключёнными интеграциями: можно настроить сервис до включения клиентов.
Клиенты QMLauncher и QMWeb при 404 и тексте detail про отключённую интеграцию показывают сообщение, что выбранный QMServer не обслуживает соответствующую интеграцию.
Removed auth stack OAuth2 PKCE (только QMServer Cloud)
Встроенный модуль Removed auth stack поддерживает OAuth2 Authorization Code с PKCE для веб-клиентов (QMAdmin, QMWeb, QMDocs): обмен email/пароля Removed auth stack на одноразовый code и редирект на redirect_uri клиента, затем обмен code + code_verifier на JWT (access_token тот же, что у POST /modules/legacy-auth/auth/login).
На стороне QMServer должны быть заданы:
LEGACY_ENV_— через запятую список точных URLredirect_uri(напримерhttps://web.qx-dev.ru/loginдля QMWeb,https://admin.qx-dev.ru/для QMAdmin,https://qm.qx-dev.ru/login/callbackдля QMDocs — как в сборке фронтов).LEGACY_ENV_— опционально; по умолчанию допускаются идентификаторы вродеqmadmin,qmweb,qmdocs.
| Метод | Путь (под /api/v1) | Описание |
|---|---|---|
| POST | /modules/legacy-auth/oauth/pkce/authorize | Тело JSON: email, password, client_id, redirect_uri, state, code_challenge, code_challenge_method: "S256" → redirect_url с параметрами code и state |
| POST | /modules/legacy-auth/oauth/token | grant_type=authorization_code, code, redirect_uri, client_id, code_verifier → access_token |
Без LEGACY_ENV_ эндпоинты отвечают 404 с пояснением в detail.
Подробнее о входе в UI: QMAdmin, QMWeb.
Базовый путь
Все перечисленные ниже маршруты (кроме /health и /swagger) находятся под префиксом /api/v1.
Система
| Метод | Путь | Описание |
|---|---|---|
| GET | /health | Health check |
| GET | /api/v1/status | Краткий статус API |
Аутентификация (JWT)
Используется QMAdmin и QMWeb. Заголовок: Authorization: Bearer <token>.
| Метод | Путь | Описание |
|---|---|---|
| POST | /auth/login | Вход |
| POST | /auth/register | Регистрация |
| GET | /auth/me | Текущий пользователь |
| PATCH | /auth/profile | Профиль |
| GET | /auth/ely/oauth-url | Старт привязки Ely.by |
| GET | /auth/ely/callback | OAuth callback (без JWT) |
| DELETE | /auth/ely/link | Отвязать Ely.by |
Администрирование: пользователи облака
Требуются JWT и флаг администратора.
| Метод | Путь | Описание |
|---|---|---|
| GET | /admin/users | Список пользователей |
| PATCH | /admin/users/:id | Изменение пользователя (в т.ч. премиум) |
Выделенные хосты и агент QMClient
Реестр машин (VPS / железо) для учёта и сканирования каталогов агентом QMClient. Требуются JWT, админ и включённый модуль Dedicated (см. Модули и клиентские интеграции).
| Метод | Путь | Описание |
|---|---|---|
| GET | /admin/dedicated-servers | Список |
| POST | /admin/dedicated-servers | Создание; в ответе — dedicated_server и одноразовый agent_enrollment_envelope (Base64, RSA-OAEP по публичному ключу из сборки QMClient); открытый токен в JSON не отдаётся |
| PATCH | /admin/dedicated-servers/:id | Обновление полей (IP, имя, ОС, work_dir, локация, провайдер); токен агента не меняется |
| DELETE | /admin/dedicated-servers/:id | Удаление; у связанных игровых профилей сбрасываются dedicated_server_id и data_subdir |
| GET | /admin/dedicated-servers/:id/discovery | Последний отчёт скана (папки, тип, порт, сопоставление с профилями) |
| POST | /admin/dedicated-servers/:id/agent-token | Новый токен агента (старый перестаёт действовать); в ответе — новый agent_enrollment_envelope |
Публичный ключ для конверта вшит в QMServer (routes/embedded/qmclient_enrollment_public.pem) или задаётся переменной QMCLIENT_ENROLLMENT_PUBLIC_KEY_PEM; он должен соответствовать приватному ключу в сборке QMClient (enrollment/keys/enrollment_private.pem).
Агент вызывает API не с JWT админа, а с заголовком Authorization: Bearer и проверяемым токеном (после установки — расшифрованным на стороне агента из конверта; в API по-прежнему формат qm_...):
| Метод | Путь | Описание |
|---|---|---|
| GET | /agent/dedicated-servers/:id | Проверка токена; ответ: work_dir, имя хоста |
| POST | /agent/dedicated-servers/:id/scan | Тело JSON { "entries": [ { "subdir", "game_type", "port", "version_hint" } ] } — сохранение и слияние с профилями по IP/порту |
| GET | /agent/dedicated-servers/:id/supervisor | Очередь задач для агента: объекты с id, server_id, action (start / stop / restart / install_cs16 / provision_mc / remove_instance), data_subdir, port, при необходимости remove_steamcmd (для remove_instance). Плюс список console_pull для выгрузки хвоста лога Minecraft (пока админ опрашивает консоль). Задачи при выдаче переводятся в статус processing |
| POST | /agent/dedicated-servers/:id/supervisor/tasks/:task_id/result | Тело { "ok": bool, "message": string } — завершение задачи (done / failed) |
| POST | /agent/dedicated-servers/:id/supervisor/console | Тело { "server_id", "content" } — фрагмент лога в буфер для GET …/minecraft/console |
Задачи хранятся в таблице agent_supervisor_tasks (связь с профилем сервера и dedicated_server_id; для remove_instance путь инстанса дублируется в instance_subdir, т.к. строка профиля может быть уже удалена). Буфер консоли для опроса из админки — в памяти процесса QMServer.
Админ (JWT): управление процессом Minecraft только для профилей с game_kind: minecraft, привязанных к выделенному хосту и с заполненным data_subdir:
| Метод | Путь | Описание |
|---|---|---|
| POST | /admin/servers/:id/minecraft/process | Тело { "action": "start" | "stop" | "restart" } — постановка задачи в очередь для агента этого хоста |
| GET | /admin/servers/:id/minecraft/console | Последний сохранённый текст лога; продлевает «интерес» к выгрузке лога агентом |
Игровые аккаунты (Minecraft)
Требуются модуль Minecraft и интеграция QMLauncher (и JWT там, где указано ниже).
| Метод | Путь | Описание |
|---|---|---|
| GET | /game-accounts | Список |
| POST | /game-accounts | Создание |
| POST | /game-accounts/sync | Синхронизация |
| GET | /game-accounts/:id | Карточка |
| PATCH | /game-accounts/:id | Обновление |
| DELETE | /game-accounts/:id | Удаление |
| PATCH | /game-accounts/:id/link | Привязка Mojang/Microsoft |
| GET | /game-accounts/:id/inventory | Инвентарь в облаке |
Инвентарь с сервера (мод)
Отдельная авторизация API-ключом — см. раздел Синхронизация инвентаря. В Free и в Cloud работает только при включённом модуле Minecraft и интеграции QMWeb.
| Метод | Путь | Описание |
|---|---|---|
| POST | /inventory | Приём данных от игрового сервера (QXSync); требуются модуль Minecraft, QMWeb, ключ API — иначе 404/ошибки авторизации |
Скины и косметика
| Метод | Путь | Описание |
|---|---|---|
| GET | /skins/proxy | Прокси URL скина (обход CORS) |
| GET | /skins | Список |
| GET | /skins/:username | Выдача PNG |
| POST | /skins/:username | Загрузка (JWT) |
| POST | /capes/:username | Загрузка плаща |
| POST | /elytras/:username | Загрузка элитры |
Настройки (публичные GET / админские PATCH)
| Путь | Назначение |
|---|---|
/settings/skin-providers | Провайдеры скинов |
/settings/referral | Реферальная программа |
/settings/inventory-sync | Вкл/выкл и параметры sync инвентаря |
/settings/curseforge-api-key | Ключ CurseForge для каталога модов |
/settings/inventory-sync/generate-key | POST — новый API-ключ для модов |
/settings/qmlauncher-msa-client-id | Client ID Microsoft для QMLauncher |
QMLauncher (вспомогательные API)
| Метод | Путь | Описание |
|---|---|---|
| GET | /launcher/create-instance/minecraft-versions | Список версий MC |
| GET | /launcher/create-instance/loader-versions | Версии Forge/Fabric/… |
| GET | /launcher/curseforge-api-key | Ключ CurseForge для премиум/админа (JWT) |
Новости
| Метод | Путь | Описание |
|---|---|---|
| GET | /news | Публичная лента |
| POST / PATCH / DELETE | /news, /news/:id | Управление (админ) |
Профили Minecraft-серверов
| Метод | Путь | Описание |
|---|---|---|
| GET | /servers | Список профилей + players / max_players (Server List Ping); админ видит отключённые; при наличии выделенного хоста и data_subdir — поля agent_setup_status / agent_setup_detail (состояние последней задачи установки агентом). Публичный список (не админ): пустой server_profiles, если выключены обе интеграции QMLauncher и QMWeb |
| PATCH | /servers/:id | Включение/выключение профиля |
| DELETE | /servers/:id | Удаление профиля. Тело JSON (опционально): remove_from_host — снять данные на машине; для профиля на dedicated ставится задача remove_instance (агент удаляет каталог инстанса). Для не-dedicated при true удаляется каталог профиля под корнем данных (QMSERVER_DATA_PATH, в Docker по умолчанию /app); при false — только запись в БД. Для профилей не Minecraft дополнительно remove_steamcmd — удалить общий SteamCMD на хосте (через агент) или под тем же корнем данных на стороне QMServer. |
| POST | /admin/servers | Создание профиля на выделенном хосте: dedicated_server_id, data_subdir, имя, порт, version, опционально game_kind: minecraft (по умолчанию) или counter_strike_16; загрузчик модов только для Minecraft |
| GET | /servers/:id/mod-config | JSON для лаунчера до синхронизации |
У профиля могут быть поля dedicated_server_id и data_subdir (папка относительно work_dir на хосте). Такие профили не требуют полного набора локальных data-каталогов на стороне QMServer — игровые файлы живут на выделенной машине. UUID профиля и этот каталог данных всегда соответствуют одному игровому экземпляру (одна запись в БД — одна директория под work_dir выделенного хоста).
Управление файлами на стороне облака (админ, JWT):
/servers/:id/mods,mod-presets,resourcepacks,shaderpacks— списки, метаданные, загрузка/удаление, парсинг зависимостей.
Только QMServer Cloud / Premium
Если APP_NAME содержит cloud или premium:
| Метод | Путь | Описание |
|---|---|---|
| POST | /check/server | Проверка регистрации сервера |
| GET | /check/data/:server_id | Манифест файлов data.json |
| GET | /download/:server_id/*file_path | Отдача файлов модпака и скинов |
Запуск
Поставляется один исполняемый файл qmserver: интерактивный режим по умолчанию, для продакшена — qmserver --server (HTTP + Gin).
| Способ | Детали |
|---|---|
| Docker | Готовые образы GitHub Container Registry — пакет ghcr.io/<владелец>/qmserver: ...:free-latest (публичная сборка) и ...:latest (Cloud), linux/amd64; в контейнере WORKDIR=/app, по умолчанию корень данных задаётся через QMSERVER_DATA_PATH; для продакшена API — ./qmserver --server. В корне монорепозитория docker-compose.yaml и docker-compose.cloud.yaml тянут образы по GHCR_OWNER (и опционально IMAGE_TAG) — см. .env.example; CI: образы собираются из репозитория QMServer (пакет GHCR qmserver; workflows build-qmserver-image, build-qmserver-public-image). У сервиса qmserver задано platform: linux/amd64. При приватном пакете на хосте нужен docker login ghcr.io. |
| systemd | Юнит qmserver: исполняемый файл /opt/qmserver/qmserver, конфиг /opt/qmserver/qmserver.conf, данные /opt/qmserver/data, логи /var/log/qmserver.log (StandardOutput/StandardError → append), симлинк /usr/local/bin/qmserver; make install-systemd в каталоге репозитория QMServer. |
| Вручную | make build-release → один статический исполняемый файл под x86_64; на сервере QMSERVER_DATA_PATH (например /opt/qmserver/data). |
Скрипт install.sh (образ Cloud)
Для отдельного сервера под Linux x86_64 без сборки из исходников в репозитории mindevis/QMServer есть install.sh, ориентированный на Cloud-бинарник и образ ghcr.io/.../qmserver (см. сырой URL):
| Режим | Что делает |
|---|---|
--native (от root) | Берёт архив qmserver-*-linux-amd64*.tar.gz из GitHub Releases, ставит бинарник в /opt/qmserver, подтягивает qmserver.service и пример qmserver.conf, включает systemd. |
--docker | Проверяет curl, Docker, Compose (docker compose или docker-compose), тянет ghcr.io/mindevis/qmserver:latest, создаёт каталог с .env и docker-compose.yml (по умолчанию ~/qmserver-cloud, см. DOCKER_INSTALL_DIR). |
curl -fsSL https://raw.githubusercontent.com/mindevis/QMServer/main/install.sh | sudo bash -s -- --native
curl -fsSL https://raw.githubusercontent.com/mindevis/QMServer/main/install.sh | bash -s -- --docker
Опционально: QMSERVER_RELEASE_TAG (конкретный тег релиза), GITHUB_TOKEN / GH_TOKEN если репозиторий или пакеты приватные, QMSERVER_GHCR_IMAGE — другой образ для Docker. Справка: install.sh --help.
Публичная сборка (free-latest)
Публичная сборка публикуется как ghcr.io/<owner>/qmserver:free-latest (тот же пакет GHCR, что и Cloud; сборка без -tags cloud, см. BUILD.md). Поднять можно через docker-compose.yaml в корне qm-project (make run-qmserver) или вручную. Отдельного install.sh под старый репозиторий QMServerFree больше нет: для нативной установки публичной сборки соберите make build-release в QMServer или используйте только Docker/GHCR.
Каталог данных на диске: QMSERVER_DATA_PATH (в Docker по умолчанию /app, в unit systemd по умолчанию /opt/qmserver/data). Скины по умолчанию: <корень>/skins, либо SKINS_STORAGE_DIR.
# Монорепозиторий: облачный стек (образ qmserver)
make run-qmserver-cloud
# Монорепозиторий: публичная сборка (тег free-latest)
make run-qmserver
# Локальная отладка в каталоге субмодуля QMServer
cd QMServer && go run -tags cloud . --server # Cloud
cd QMServer && go run . --server # публичная сборка
Переменные окружения (основные)
| Переменная | Описание |
|---|---|
PORT | Порт HTTP (по умолчанию 8080) |
DB_DSN | Строка подключения MySQL |
QMSERVER_DATA_PATH | Корень для .servers/, манифестов и каталога скинов по умолчанию (Docker — /app, native systemd — /opt/qmserver/data) |
APP_NAME | Имя приложения; для premium-эндпоинтов — должно содержать cloud или premium |
LEGACY_ENV_ | (В основном QMServer Free) URL JWKS внешнего IdP Removed auth stack для проверки Bearer JWT; если пусто, отдельный путь авторизации по таким токенам не активируется. В Cloud встроенный Removed auth stack задаётся интеграцией, не этой переменной. |
LEGACY_ENV_ | (Cloud, PKCE) Список разрешённых redirect_uri для OAuth2 (см. Removed auth stack OAuth2 PKCE). |
LEGACY_ENV_ | (Cloud, опционально) Разрешённые client_id для PKCE; по умолчанию включает клиентов вроде qmadmin / qmweb / qmdocs. |
ELY_CLIENT_ID, ELY_CLIENT_SECRET, ELY_REDIRECT_URI, ELY_FRONTEND_REDIRECT | Ely.by OAuth |
Подробнее: разделы выше; шаблон переменных — deploy/systemd/qmserver.conf.example в репозитории QMServer (systemd: /opt/qmserver/qmserver.conf; локально можно скопировать в .env).
Репозиторий и сборки
Один репозиторий mindevis/QMServer:
- Публичная сборка (без Go-тега
cloud): API без маршрутовcheck/download, без облачного манифеста данных, без встроенных модулей Removed auth stack и QMBilling (см. модули и интеграции). - Cloud-сборка (
go build -tags cloud, образqmserver): полная облачная / premium конфигурация (APP_NAMEсcloudилиpremium), Removed auth stack как интеграция, QMBilling как модуль.
Репозиторий может быть публичным или приватным на GitHub — от этого зависит только доступ к git clone и к приватным пакетам GHCR. Подробности по флагам сборки — BUILD.md и README.md в QMServer.