Перейти к содержимому

Обслуживание

Проверка до того, как сломается

Окно терминала
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