Обслуживание
Проверка до того, как сломается
laminara-server doctor --config /etc/laminara/config.jsonКоманда идёт по разделам настроек и проверяет каждый в деле, а не по описи: база аккаунтов отвечает и в ней есть нужные колонки, в хранилище правда заливается и скачивается пробный файл, ключ подписи ставит подпись, которая потом проходит проверку, redis принимает запись, источники доступа и новостей отзываются, адреса из настроек лаунчера открываются снаружи.
Пробы записываются под служебными именами вроде doctor/probe-<uuid> и удаляются сразу после
проверки — настоящих данных команда не трогает.
Строки помечены ok, важно, плохо и — (проверка пропущена). У каждой находки написано, чем
она обернётся для игроков, и, где это возможно, готовая команда для копирования. Хотя бы одно
«плохо» — ненулевой код возврата, так что команду удобно ставить в проверку перед запуском.
Весь путь игрока целиком
С флагом --as команда становится лаунчером и проходит вход от начала до конца:
laminara-server doctor --config /etc/laminara/config.json --as IvanПароль спрашивается скрытым вводом и никуда не сохраняется. Проверяются: вход, продление токена,
отказ при попытке использовать старый токен продления второй раз, список сборок глазами игрока,
манифест и его подпись, скачивание настоящего файла по выданной ссылке и вход в игре —
authenticate, join, hasJoined. Это ловит то, что не видно изнутри: не проксирующий nginx,
временную ссылку S3 с внутренним адресом, кольцо ключей, которое разошлось с опубликованными
сборками.
Что чинится само
laminara-server doctor --config /etc/laminara/config.json --fix--fix приводит в порядок только то, что обратимо и однозначно: права 600 на ключи, соль и
конфиг, недостающие каталоги, права на чтение объектов для nginx, флаг запуска у файла модуля.
Настройки он не переписывает — вместо этого печатает точную команду, которую вы применяете сами.
Остальные ключи
| Ключ | Что делает |
|---|---|
doctor auth storage | проверить только эти разделы (можно и --only auth,storage) |
--deep | сверять все файлы опубликованных сборок, а не выборку из дюжины |
--json | машинный вывод для мониторинга |
--endpoint <url> | обращаться к серверу по этому адресу, а не по тому, что в настройках |
Разделы: config auth storage build api yggdrasil hwid access news console launcher modules rateLimit update log crashReports branding flow consistency. Последние два — путь игрока и
взаимная согласованность настроек: именно там ловятся противоречия, которых не видно внутри
одного раздела (выключенный yggdrasil, из-за которого не войдёт никто; пустой
api.trustedProxies за nginx, из-за которого защита от перебора блокирует сразу всех; домен
скинов, не внесённый в yggdrasil.skinDomains; баны по железу, живущие в памяти при включённом
режиме «не пускать»).
Та же команда работает и внутри сервера — из консоли или скриптом:
laminara-server exec "doctor"laminara-server exec "doctor auth storage"Сохранение и восстановление
laminara-server backup --config /etc/laminara/config.json --out /srv/backups/laminara.tar.gzВ архив попадает то, что нельзя пересоздать: настройки, ключ подписи и все отставные ключи, ключ входа в игре, соль отпечатков, ключ пропусков и база компьютеров с банами. Команда печатает список взятого и отдельно — список того, чего в архиве нет: подготовленные сборки, файлы в хранилище и собранные лаунчеры. Это гигабайты, и они восстанавливаются пересборкой.
laminara-server restore --archive /srv/backups/laminara.tar.gzФайлы кладутся по тем же путям, откуда были взяты. Существующие файлы восстановление не трогает
и говорит, какие пропустило: чтобы заменить их, нужен --force. Разложить архив в отдельную папку
и посмотреть, что внутри, можно через --into /tmp/проверка.
Журнал
Логи всегда идут в консоль, а её подхватывает systemd или docker — там же и ротация. Файл нужен, когда сервер запускают иначе:
{ "log": { "file": "/var/log/laminara/server.log", "maxSizeMB": 20, "keep": 5, "maxAge": "720h" }}Файл режется по размеру, старый получает имя со временем (server-20260825-131500.log), лишние
удаляются по количеству и возрасту. Пустой file — файла нет, только консоль. Если файл открыть
не удалось, сервер запустится и скажет об этом в консоль: журнал не повод не работать.
Наблюдение
Публичный слушатель отвечает на два адреса без авторизации:
| Адрес | Что значит |
|---|---|
/healthz | Процесс жив и отвечает. Всегда 200, пока сервер работает. |
/readyz | Сервер готов обслуживать игроков: хранилище отвечает, каталог сборок читается. 200 или 503 со списком того, что не отвечает. |
curl -s http://127.0.0.1:8099/readyz{"status":"degraded","checks":{"storage":"…"},"failed":["storage"]}Ответ /readyz считается заново не чаще раза в пять секунд, поэтому мониторинг можно опрашивать
хоть каждую секунду. Проверка каждой зависимости ограничена двумя секундами: зависшее хранилище
не подвесит ответ.
Для docker-compose и systemd этого достаточно, чтобы отличить поднявшийся сервер от повисшего:
healthcheck: test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8099/readyz"] interval: 30s timeout: 5s retries: 3