Files
pipu-music/docs/server-management.md
T
mrleo1nid a29a8b18ad
ci / api / api (push) Successful in 52s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 1m9s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m35s
release / release (версия и заметки) (push) Successful in 5s
release / android (APK в релиз) (push) Successful in 4m6s
ci / db / db (push) Successful in 1m15s
ci / docker / docker (образы собираются — их сервер собирает сам при обновлении) (push) Successful in 1m19s
ci / ts / ts (packages + web) (push) Successful in 2m34s
release / desktop (Linux и Windows в релиз) (push) Successful in 14m27s
release / prune (старые файлы и прогоны) (push) Successful in 6s
feat(admin): manage server updates and local configuration
2026-10-22 23:01:36 +03:00

11 KiB
Raw Permalink Blame History

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

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

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

После получения версии с управлением сервером выполните на Linux-хосте:

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

Новая установка через 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.