Reviewing the upload queue is now a per-user flag (reviews_uploads), not part of the admin role: several people can hold it, a moderator can have it, and an admin may not. Only admins grant or revoke it; existing admins keep it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
133 lines
15 KiB
Markdown
133 lines
15 KiB
Markdown
# Руководство администратора
|
||
|
||
Повседневная работа с сервером после установки ([install-guide.md](install-guide.md)): пользователи, музыка,
|
||
очередь на добавление, «Моя волна», обновления и диагностика. Все команды — из каталога
|
||
`/opt/pipu-music/deploy`. Справочник по сервисам и переменным — [deployment.md](deployment.md).
|
||
|
||
## 1. Первый вход
|
||
|
||
1. Логин `admin`. Пароль — `BOOTSTRAP_ADMIN_PASSWORD` из `.env`, а если он не задан — сгенерированный, его
|
||
печатает лог один раз: `docker compose logs api | grep -i bootstrap`.
|
||
2. Сервер сразу попросит сменить логин и пароль администратора (пароль ≥ 12 символов). До этого остальные
|
||
разделы недоступны.
|
||
3. Подключите хранилище с музыкой (раздел 3) — после первого скана появятся библиотека, поиск и «Моя волна».
|
||
|
||
## 2. Пользователи и роли
|
||
|
||
«Администрирование → Пользователи».
|
||
|
||
| Роль | Что может |
|
||
|---|---|
|
||
| Пользователь | Слушать, искать, собирать коллекцию, «Моя волна» |
|
||
| Модератор | Плюс: заводить пользователей и сбрасывать им пароли, смотреть статус библиотеки, предлагать треки |
|
||
| Администратор | Всё: хранилища, сканы, настройки сервера, роли, аудит |
|
||
|
||
**Аудит загрузок** — отдельное право, не роль: рассматривать очередь на добавление (одобрять, отклонять, править
|
||
метаданные). Выдаёт и забирает только администратор — при создании пользователя или в меню строки
|
||
(«Дать / Забрать аудит загрузок»), в том числе себе. Право может быть у нескольких людей сразу и у любой роли;
|
||
у администратора его может не быть. Первый (bootstrap) администратор и админы, существовавшие до появления права,
|
||
получают его автоматически.
|
||
|
||
Полная матрица прав — [auth-and-roles.md](auth-and-roles.md#матрица-прав).
|
||
|
||
- **Новый пользователь:** «Создать» → логин, имя, роль. Сервер выдаёт **временный пароль** — он показывается один
|
||
раз, передайте его человеку. При первом входе пароль придётся сменить.
|
||
- **Забыл пароль:** «Сбросить пароль» — новый временный пароль, все сессии пользователя завершаются.
|
||
- **Волна «застряла» во вкусе:** «Сбросить рекомендации» — профиль вкуса, статистика прослушиваний и показы волны
|
||
стираются, онбординг покажется снова. Лайки, дизлайки и история остаются (и по-прежнему влияют на подбор).
|
||
- **Заблокировать** — вход запрещён, история и лайки сохраняются; **удалить** — безвозвратно вместе с историей.
|
||
- Последнего администратора нельзя понизить, заблокировать или удалить.
|
||
- **Аудит** («Администрирование → Аудит»): кто, когда и что сделал — создание пользователей, смена ролей, сбросы
|
||
паролей, изменения хранилищ и настроек, решения по очереди.
|
||
|
||
## 3. Хранилища и библиотека
|
||
|
||
«Администрирование → Хранилища».
|
||
|
||
- **Папка на сервере** — каталог хоста из `LIBRARY_HOST` в `.env` (например, смонтированный диск `/mnt/music`);
|
||
в форме указывается путь внутри него. **NFS** — сервер и экспорт; монтирует `storage-agent`.
|
||
- «Проверить» — доступ к хранилищу, число найденных аудиофайлов.
|
||
- **Шаблоны путей** («Шаблоны»): как из пути файла получить исполнителя, альбом, год и номер трека, если в тегах
|
||
пусто. «Предпросмотр» показывает разбор реальных путей до сохранения. Что важнее — теги или путь, задаётся
|
||
в карточке хранилища (по умолчанию теги).
|
||
- **Скан:** обычный — только новые и изменённые файлы (по расписанию — интервал в карточке хранилища — и после
|
||
изменения настроек), «Полный» — перечитать всё. Удалённые с диска файлы помечаются отсутствующими, а не стираются из истории.
|
||
- «Администрирование → Библиотека» — счётчики, прогресс скана и аудиоанализа, файлы с ошибками чтения
|
||
(битые файлы, неизвестные форматы) и «Переиндексировать поиск» — если поиск выдаёт устаревшее (обычно не нужно:
|
||
индекс обновляется сам и пересобирается при старте api).
|
||
- **Аудиоанализ** (темп, энергия, настроение — для «Моей волны») идёт в фоне: на 10 тыс. треков — несколько часов
|
||
при 4 ядрах (`analyzer` в `compose.yaml`, `--workers`). Волна работает и до его окончания, но точнее — после.
|
||
Не удалось проанализировать часть треков (например, пока диск не был смонтирован) — «Повторить» под счётчиком
|
||
ошибок возвращает их в очередь; рядом показана самая частая ошибка. Пропавшие файлы анализатор не считает
|
||
попыткой и ждёт, пока диск вернётся.
|
||
|
||
## 4. Очередь на добавление
|
||
|
||
Модераторы и администраторы предлагают треки («Предложить треки»), что попадёт в библиотеку, решают люди
|
||
с правом **аудита загрузок**. Подробно — [uploads.md](uploads.md).
|
||
|
||
- **Куда пишутся файлы:** у хранилища включите «Принимать загрузки» и задайте **шаблон раскладки** — «Подобрать»
|
||
предложит шаблон по уже лежащим файлам, «Проверить» убедится, что из пути, построенного шаблоном, сканер
|
||
получит те же исполнителя, альбом и номер трека. Хранилище по умолчанию — в «Настройках сервера».
|
||
- **Рассмотрение** («Очередь на добавление»): прослушать, поправить метаданные (в том числе сразу для всего
|
||
альбома), одобрить или отклонить с причиной — автор её увидит. Итоговый путь пересчитывается при правке.
|
||
Отметка «возможный дубль» — со ссылкой на похожий трек библиотеки; точные копии отсекаются ещё до загрузки.
|
||
- **Импорт:** одобренный файл записывается в хранилище только под окончательным именем, с проверкой контрольной
|
||
суммы; кроме самих аудиофайлов (и папок для них) на диск ничего не пишется.
|
||
- **Квота** («Настройки сервера»): общий лимит очереди (10 ГБ по умолчанию), лимит на одного модератора
|
||
(выключен) и максимальный размер файла (2 ГБ). Отклонённые файлы и дубли место не занимают; снижение лимита ниже
|
||
занятого не удаляет загрузки, просто новые не принимаются.
|
||
|
||
## 5. «Моя волна»
|
||
|
||
- «Администрирование → Библиотека → Моя волна за 7 дней»: сколько треков выдано, доля дослушанных до конца,
|
||
ранних скипов и лайков на 100 треков. Ориентир — ранних скипов меньше 30%.
|
||
- Таблица по **версиям модели**: `heuristic-v1` — эвристика, `heuristic-v1+cf` — она же с коллаборативной
|
||
фильтрацией (ALS), `lgbm-…` — обученный ранжировщик. По ней видно, стало ли лучше после смены модели.
|
||
- Обучение — каждую ночь в 3:00 UTC: ALS по прослушиваниям, бандит по источникам
|
||
кандидатов, ранжировщик по показам волны. Новая модель включается, только если по проверке на последней неделе
|
||
не хуже текущей. Ранжировщику нужно ~20 тыс. показов с известным исходом — до этого работает эвристика.
|
||
- Новые пользователи с почти пустой историей проходят **онбординг вкуса**: выбирают исполнителей и жанры
|
||
библиотеки. Пропуск тоже запоминается.
|
||
|
||
## 6. Обновление
|
||
|
||
```bash
|
||
./update.sh
|
||
```
|
||
|
||
Скрипт переключается на последний релиз, собирает образы, перезапускает сервисы и ждёт
|
||
готовности; миграции применяются при старте api. Конкретная версия — `./update.sh v1.0.0`; откат на старую версию
|
||
требует `PIPU_ALLOW_DOWNGRADE=1` (миграции не откатываются — сначала проверьте совместимость). Перед обновлением
|
||
прочитайте заметки к релизу на странице релизов Gitea.
|
||
|
||
Android-приложение обновляется само: при запуске оно сверяется с сервером и предлагает новый APK.
|
||
Раздать приложение — ссылка `https://<ваш-домен>/android` (без входа): кнопка «Скачать APK» последнего релиза,
|
||
адрес сервера для копирования и короткая инструкция; та же страница — внизу экрана входа и в меню профиля.
|
||
|
||
## 7. Наблюдение
|
||
|
||
| Что | Как |
|
||
|---|---|
|
||
| Сервер жив и готов | `curl -s https://music.example.com/readyz` → все зависимости `ok` |
|
||
| Состояние сервисов | `docker compose ps` |
|
||
| Логи | `docker compose logs -f --tail=100 api` (или `recommender`, `analyzer`, `storage-agent`) |
|
||
| Место на диске | `df -h /srv/pipu`; больше всего занимает `cache/transcode` (чистится сам) |
|
||
| Версия | `grep PIPU_VERSION .env`, `GET /api/v1/server-info`; Android — внизу вкладки «Профиль» |
|
||
| Нагрузка | `tests/load/smoke.js` — см. [testing.md](testing.md#нагрузочный-smoke) |
|
||
|
||
## 8. Частые ситуации
|
||
|
||
| Ситуация | Что делать |
|
||
|---|---|
|
||
| Ни один трек не играет («Не удалось воспроизвести трек»), в логе api `no such file or directory` | Диск с музыкой не смонтирован: `findmnt <LIBRARY_HOST>`, `sudo mount -a`. Контейнеры увидят диск сами; скан на пустой папке прерывается с ошибкой «is the disk mounted?» и ничего не помечает пропавшим |
|
||
| Трек не находится поиском | Есть ли он в «Библиотеке» (скан завершён, файл не в «ошибках»); затем «Переиндексировать поиск» |
|
||
| Неверный исполнитель или альбом | Поправьте теги файла или шаблон путей и запустите скан |
|
||
| Хранилище в статусе «Ошибка» | Текст ошибки на карточке; диск смонтирован (`findmnt`), NFS доступен с сервера; «Проверить» |
|
||
| Волна однообразная | Идёт ли аудиоанализ («Библиотека → Аудиоанализ»); чем больше прослушиваний, тем точнее волна |
|
||
| Загрузка застряла в «Обработке» | `docker compose logs api | grep upload`; повторный импорт — «Одобрить» ещё раз |
|
||
| Пользователь не может войти | Не заблокирован ли; «Сбросить пароль» |
|
||
| Сервис перезапускается по кругу | `docker compose logs <сервис>`; часто — закончилось место на диске |
|
||
|
||
Остальное — [install-guide.md](install-guide.md#12-если-что-то-не-работает).
|