Files
pipu-music/docs/server-management.md
T
mrleo1nid bc55528afd
ci / docker / docker (образы собираются — их сервер собирает сам при обновлении) (push) Successful in 1m21s
fix(deploy): provision management agent during server updates
2026-10-22 23:43:11 +03:00

12 KiB
Raw Blame History

Управление сервером из веб-интерфейса

В меню админки доступны Обновления (/admin/updates) и Конфигурация (/admin/config). Клиентские APK и desktop-сборки по-прежнему раздаются через существующий механизм appupdate; источники обновления сервера от него независимы.

Установка на существующий сервер

Обычное обновление на Linux-хосте автоматически настраивает агент после переключения на выбранную версию и до пересоздания контейнеров:

cd /opt/pipu-music/deploy
./update.sh main   # либо тег версии, содержащей эту возможность

Если прав не хватает, установщик запросит sudo только для настройки системного сервиса. Повторный запуск проверяет установку и запускает остановленный агент; исправный агент с тем же кодом и unit-файлом не перезапускается. Ошибка установки останавливает обновление до пересоздания контейнеров. При обновлении из админки собственный агент остаётся запущенным и заменяет свою копию после успеха.

В версии v1.9.0 вызов установщика из update.sh был пропущен. Если сервер уже обновлён до неё, агент можно включить сразу без новой сборки:

cd /opt/pipu-music/deploy && sudo bash ./install-management.sh

Чтобы получить исправленный updater на checkout ветки main, один раз выполните git pull --ff-only перед ./update.sh main: старая временная копия updater, запущенная до checkout, ещё не содержит нового шага настройки.

Новая установка через sudo ./install.sh также устанавливает агент автоматически. Нужны systemd, Python 3.10+, Git, Bash, flock (util-linux) и Docker Compose 2.24+. Compose должен поддерживать несколько --env-file и тег !reset из существующего TLS-overlay. Агент выполняется от root, чтобы запускать Compose и обращаться к данным развёртывания; API продолжает работать без root и без Docker socket.

Скрипт создаёт pipu-management.service, копирует агент вне Git-checkout в /usr/local/lib/pipu/server-agent.py, создаёт deploy/config.local и общий каталог ${PIPU_DATA}/management с владельцем UID 65532. Последний монтируется только в API. Приватные настройки источников, состояние, аудит и журналы лежат в /var/lib/pipu-management, доступном только root. Нужен доступ этого пользователя к origin; SSH-ключи и known_hosts для приватных репозиториев настройте на хосте. Пароли и токены в URL источников не принимаются.

После успешного обновления агент автоматически заменяет свою установленную копию из нового checkout и перезапускается, сохранив итоговый статус. Для ручной установки нового кода можно повторно запустить install-management.sh. Во время выполняющейся операции не перезапускайте его: systemd остановит дочерние процессы. После прерывания/перезагрузки задача помечается ошибкой, а не успехом.

Права

Администратор всегда может управлять обновлениями. В меню действий пользователя на странице Пользователи он может выдать и забрать право Управление обновлениями (manages_updates). Право действует независимо от роли и проверяется на сервере при каждом запросе. Оно позволяет изменять источники, видеть журнал и запускать обновление. Пользователь с этим правом получает ссылку на обновления, но не получает доступ к пользователям, конфигурации или остальным действиям админа.

Выдавайте это право доверенным операторам: обновление запускает код выбранного совместимого репозитория на хосте. Только администраторы могут просматривать, сохранять и применять конфигурацию. Выдача/отзыв права записываются в audit_log; операции агента с UUID инициатора — в его приватный audit.jsonl без значений секретов.

Обновления

При первом обращении автоматически добавляется текущий git remote origin. Можно создавать, редактировать и удалять источники; хотя бы один должен остаться. Поддерживаются совместимые Git-репозитории Pipu через HTTP(S) и SSH.

  • Последний релиз — значение по умолчанию: максимальный стабильный тег SemVer vMAJOR.MINOR.PATCH (также допускается без v), без -rc.N.
  • Выбрать версию — конкретный релизный тег, включая release candidate.
  • main — текущий commit ветки main.

Обновления устанавливаются только по нажатию кнопки и после подтверждения. Перед запуском агент повторно читает refs и фиксирует SHA; update.sh проверяет, что полученный commit совпадает. Выбранный источник не перезаписывает origin и не смешивает его теги с тегами другого репозитория. Git checkout с локальными изменениями отклоняется. Защита update.sh от downgrade сохраняется: откат выполняется вручную с PIPU_ALLOW_DOWNGRADE=1 после проверки совместимости БД.

Выполнение, ограниченный хвост журнала и итоговый статус доступны на странице. Можно закрыть браузер или переждать перезапуск API: работа продолжается на хосте. Полные логи остаются приватными; для интерфейса известные секреты маскируются. Одновременно агент допускает только одну операцию обновления/применения. Резервная копия и откат схемы БД автоматически не выполняются.

Конфигурация

Реестр поддерживаемых параметров находится в deploy/config.schema.json: API, общие параметры сервисов, рекомендатель и развёртывание. Добавляя параметр в конфигурацию сервиса, обновите реестр; для рекомендателя/агента хранилища также проверьте передачу через Compose. Пути томов, сгенерированный DATABASE_URL и некоторые служебные параметры показаны для просмотра и меняются на хосте. Страница не является произвольным редактором nginx/Caddy/YAML-файлов.

Приоритет при запуске через скрипты:

  1. Явные переменные окружения Compose и значения из deploy/.env.
  2. deploy/config.local.
  3. Встроенные значения по умолчанию.

Для интерполяции Compose скрипты передают --env-file config.local --env-file .env. У API порядок env_file: [config.local, .env]; рекомендатель и storage-agent получают только необходимые им переменные через environment. При ручном запуске Compose сохраняйте эти флаги, иначе параметры интерполяции из config.local не подхватятся. Страница показывает ожидаемое значение после применения, а не утверждает, что работающий процесс уже перечитал сохранённый файл. Окружение shell запуска Compose тоже может перекрывать интерполяцию; для агента используется окружение systemd.

В интерфейсе видны локальное значение, значение из .env и источник приоритета. Если ключ уже есть в .env, изменение его в config.local сохраняется, но не перекрывает .env — интерфейс прямо сообщает об этом. Чтобы управлять таким ключом через страницу, удалите его строку из .env на хосте. Секреты не возвращаются в API открытым текстом: поле без изменений сохраняет прежний секрет, ввод заменяет, Сбросить локальное удаляет только значение из config.local.

Сохранение атомарно, с правами 0600 и проверкой ревизии: устаревшая форма не затрёт правки другого администратора. Перед сохранением проверяются типы и Compose; при ошибке прежний файл восстанавливается. Произвольные ключи, переводы строк и изменение служебных параметров отклоняются. Сохраняемые значения трактуются буквально: подстановки shell не выполняются.

Кнопка Применить и перезапустить отдельно подтверждает пересоздание контейнеров. Агент запускает apply-config.sh, ждёт /readyz и сохраняет результат. Если сервисы не стали готовы, состояние — ошибка; исправьте config.local или восстановите его на хосте. Автоматического отката конфигурации после неудачного применения нет.

Диагностика:

sudo systemctl status pipu-management.service
sudo journalctl -u pipu-management.service -n 100
cd /opt/pipu-music/deploy
docker compose --env-file config.local --env-file .env logs api

Проверки разработки: python3 -m unittest discover -s deploy -p 'test_*.py', go test ./internal/auth ./internal/management из services/api, а также pnpm --filter @pipu/web test:e2e e2e/server-management.spec.ts.