Каталог плагинов: полный локальный mirror в ./plugins (один directory-mount в wwwroot/plugins), доки и вычистка неиспользуемых модулей

- plugins/: скачаны все 30 плагинов store локально (sources.json - карта исходных URL);
  патчи: showy.js (абсолютный хост подгрузки), pubtorr/td/torrentmanager - тела вместо лоадеров,
  modss.js - local-patched копия (из каталога исключена, upstream мёртв)
- extensions.json: 32 позиции, все ссылки {localhost}/plugins/<файл>.js, удалены мёртвые
  (Skaz TV x3, export.js, hotkeys/gold_theme/select_weapon/want/mult, MODS's, o.js, др.)
- compose: ./plugins:/lampac/wwwroot/plugins (один маунт вместо 30 file-mount)
- вычистка: удалены неиспользуемые mods (DatabaseEditor, ExternalBind, LogUserRequest-Lite,
  Telemetry, Transcoding, WatchTogether) и дубль каталога modules/
- config/init.conf: секции Tracks/AdminPanel/Music, customPlugins без gst.js
- mods/Tracks: правки Controller.cs/plugin.js
- README.md / AGENT.md: mirror, кеш static, правила mount
This commit is contained in:
2026-10-02 16:37:30 +03:00
parent 7b8e28b3bf
commit 257b42f518
98 changed files with 62636 additions and 21113 deletions
+96 -77
View File
@@ -1,95 +1,114 @@
# AGENT.md — инструкции для AI-агента
# AGENT.md — инструкции для ИИ-агентов
## О проекте
Работа с проектом: локальный Docker-развёртывание [Lampac NextGen](https://github.com/lampac-nextgen/lampac). Человек читает ответы **только на русском**.
Это **deployment-репозиторий** для локального развёртывания Lampac NextGen (активный форк заброшенного Lampac) в Docker на этой машине. Исходники форка сюда не клонируются — используется официальный образ `ghcr.io/lampac-nextgen/lampac`.
## Источники правды (порядок приоритета)
- Форк: https://github.com/lampac-nextgen/lampac (347+ звёзд, ежедневные коммиты, релизы)
- Документация: https://docs.lampac.dev
- Образ: `ghcr.io/lampac-nextgen/lampac:latest` (multi-arch: amd64/arm64)
- Порт: **9118**, рабочая директория в контейнере: `/lampac`
- Последняя задеплоенная версия: `1.61.2` (при установке 01.10.2026)
- Git: `ssh://git@gitea.prodik.ru:222/prodik/lampac.git`, ветка **main** (эта); ветка `synology` — тот же код с абсолютными путями томов Synology NAS; remote настроен как `origin`
- Коммиты: `git add -A && git commit && git push origin main` — секреты/данные отсекает `.gitignore`; в git идут только compose, `init.conf`, `mods/` (включённые модули), `modules/` (резерв, не монтируется), доки, `.gitignore`
1. **Официальная документация** — [docs.lampac.dev](https://docs.lampac.dev) (полный текст страниц: `https://docs.lampac.dev/llms-full.txt`, индекс: `llms.txt`). Не гадать по памяти — проверять в доках.
2. **Живой контейнер** — состояние модулей, манифестов и конфигов брать из контейнера:
```bash
docker exec lampac sh -c 'cat /lampac/module/<Имя>/manifest.json'
docker exec lampac cat /lampac/current.conf # merged-конфиг: base + init
```
3. **Логи контейнера** — `docker logs lampac`.
4. Локальные файлы проекта: `docker-compose.yaml`, `config/init.conf`, `mods/`.
## Продакшн: Proxmox LXC
## Ключевые правила
Постоянное развёртывание — LXC `121` (`lampac`) на Proxmox `root@192.168.88.254`, контейнер `root@192.168.88.23` (DHCP на vmbr0), SSH по ключу `~/.ssh/id_rsa_prodik`. Проект лежит в `/opt/lampac` (rsync с рабочей машины, без `.git`).
### 1. Никогда не правь файлы внутри контейнера/образа
- **Unprivileged** LXC + `features: nesting=1,keyctl=1` (без этого Docker не стартует), `onboot: 1`, 2 core / 4 GB / 32 GB.
- **SMB `\\10.6.0.1\Torrents` для DLNA**: монтируется **на хосте Proxmox** в `/mnt/torrents` (fstab + креды `/root/.smb_cred`, chmod 600) и пробрасывается в контейнер `mp0`. Unprivileged LXC монтировать cifs **не может** (нет `CAP_SYS_ADMIN` в init userns — `mount error: Operation not permitted`, и это не AppArmor). В fstab обязателен `uid=101000,gid=101000`: маппинг LXC `0→100000`, иначе в контейнере файлы видны как root и приложение (uid 1000) не пишет превью (`Access to the path '/lampac/data/dlna/thumbs/' is denied`).
- Том заменён через **`docker-compose.override.yml`** (в контейнере, не в git): `services.lampac.volumes: - /mnt/torrents:/lampac/data/dlna`. Базовый compose хранит `./dlna` — rsync-обновления его не трогают.
- Обновление на сервере: rsync проекта → `cd /opt/lampac && docker compose up -d`.
- Проверки: `docker ps` → `healthy`; эндпоинты `/version?type=hash`, `/online.js`, `/ts/`, `/dlna`, `/extensions` → 200; в логах нет `denied|SqliteException`.
## Файлы
| Файл | Назначение | Правила |
| --- | --- | --- |
| `docker-compose.yaml` | Единственный compose-файл | тома обязательны; фиксированной сети/subnet нет (дефолтная сеть compose). **Том `./mods:/lampac/mods` ОБЯЗАТЕЛЕН** — без него 10 модулей не загружаются (см. п.4) |
| `config/init.conf` | Конфиг сервера (JSON) | hot-reload для большинства ключей (кроме `BaseModule.SkipModules` — нужен рестарт); строго валидный JSON |
| `config/passwd` | Пароль root, **секрет** | не выводить в чат/логи/коммиты, в `.gitignore` |
| `modules/*` | Старые override-копии (`manifest.json` ×4, `extensions.json`) | **не монтируются** (убраны 01.10.2026): docs https://docs.lampac.dev/installation описывают только 6 томов (`passwd`, `init.conf`, `lampainit.js`, `cache`, `database`, `mods/`); одиночные json-тома — нештатный способ |
| `mods/` | Копии 10 модулей с `enable: true` (AdminPanel, DatabaseEditor, ExternalBind, LogUserRequest-Lite, Music, Telemetry, Tg-notify.bot, Tracks, Transcoding, WatchTogether) | монтируется одним томом `./mods:/lampac/mods` — **единственный способ включить модули с `enable: false` в образе**; при обновлении образа копии пересоздавать вручную (см. п.4) |
| `cache/` | Кеш | монтируется в `/lampac/cache` |
| `database/` | SQLite-БД (Sync, TimeCode, SISI) | монтируется в `/lampac/database`, не удалять |
| `dlna/` | Медиа/превью DLNA | монтируется в `/lampac/data/dlna`, не удалять |
| `.gitignore` | Игнорируемые пути | в игноре: `config/passwd` (секрет), `cache/`, `database/`, `dlna/`, `.DS_Store`; остальное (init.conf, modules/, compose, доки) — переносимое |
| `README.md` / `AGENT.md` | Документация | обновлять при любых изменениях развёртывания |
## Основные команды
Файлы в `/lampac/module/` (и любые другие в образе) **сгорают при обновлении** (`docker compose pull && up -d`). Включение встроенного модуля делается только пользовательской копией:
```bash
docker compose up -d # запуск
docker compose pull && docker compose up -d # обновление
docker compose restart lampac # рестарт (нужен только для passwd)
docker compose logs -f --tail 100 lampac # логи
docker compose ps # статус
curl -fsS "http://localhost:9118/version?type=hash" # health-check (ожидается 200 + hash)
curl -fsS -o /dev/null -w '%{http_code}\n' http://localhost:9118/online.js # ожидается 200
docker cp lampac:/lampac/module/<Имя> "mods/<Имя>"
# в mods/<Имя>/manifest.json -> "enable": true
# в docker-compose.yaml -> "- ./mods/<Имя>:/lampac/mods/<Имя>"
# docker compose up -d
```
Проверка работоспособности после любых изменений: health-check выше + контейнер в статусе `healthy`.
См. также официальные шаги: [Включить модуль](https://docs.lampac.dev/modules/overview), [Пользовательские модули](https://docs.lampac.dev/maintenance/custom-modules).
## Правила работы
### 2. Механика загрузки модуля (4 независимых фильтра)
1. **Отвечать по-русски.**
2. После любых изменений в проекте — дополнять `README.md` и `AGENT.md`.
3. Конфиг менять только в `config/init.conf`; валидность проверять: `python3 -m json.tool config/init.conf`.
4. Включение/выключение модулей — через `BaseModule.SkipModules` в `init.conf` (добавить имя = выключить; имя = имя папки в `/lampac/module/`, группы вроде `OnlineAnime` выключаются целиком). `SkipModules` **не hot-reload** — после правки нужен `docker compose restart lampac`. Модули с `manifest.json: enable: false` в образе (`Tracks`, `Music`, `Tg-notify.bot`, `AdminPanel`, `ExternalBind` и др.) включаются только штатно: копия **всего каталога** модуля с `enable: true`, смонтированная в `/lampac/module/<Name>/`, либо каталог в `mods/<Name>/`. Одиночные тома `manifest.json`/`extensions.json` **не использовать** — docs не описывают таких томов (https://docs.lampac.dev/installation, https://docs.lampac.dev/modules/overview). Список модулей: https://docs.lampac.dev/modules/overview
- Текущее состояние (проверка: `docker logs lampac | grep -c "loaded module"` → **117**): `SkipModules` **пуст** — включены ВСЕ модули, включая группы `OnlineAnime`/`OnlineUKR`/`OnlinePaid`/`OnlineGEO` и `Transcoding`. 10 модулей с `enable: false` в образе подняты через копии в `mods/` (таблица «Файлы»). Если после обновления образа какой-то модуль из `mods/` перестал компилироваться — пересоздать копию: `docker cp lampac:/lampac/module/<Name> ./mods/<Name>` и выставить `enable: true` в её manifest.json, затем `docker compose up -d`.
- Плагины Lampa: `/online.js`, `/sisi.js`, `/dlna.js`, `/ts.js` и т.д. Большинство Lampac сам подключает клиенту через `/lampainit.js` (см. ниже про `initPlugins`); при необходимости плагин можно добавить вручную по URL.
- **Два уровня включения модуля:** (1) `SkipModules`/manifest — модуль скомпилирован и работает на сервере; (2) `LampaWeb.initPlugins.<name>` в `init.conf` — плагин попадает в список `{initiale}`, который `/lampainit.js` добавляет клиенту Lampa (`Lampa.Plugins.add`). Без второго флага сервер отвечает, но пункт в Lampa не появится (так было с `dlna` — флаг `initPlugins.dlna` добавлен в init.conf). Сейчас подключены: `dlna: true` (в `init.conf`), из `base.conf`: `online`, `sisi`, `torrserver`, `jacred`, `cubProxy`, `tmdbProxy`, `timecode`, `pirate_store`. Особый случай `jacred`: модуль `/jacred.js` не регистрирует — флаг подставляет `{jachost}` = хост Lampac в шаблон, клиент пишет его в `jackett_url` (проверка: `curl /api/v1.0/conf` → 200).
- **Override `plugins/override/lampainit.js` (том `./plugins/lampainit.js`) модули НЕ подключает**: `{initiale}` сервер собирает из `LampaWeb.initPlugins` и подставляет в шаблон после чтения (`ApiController.cs:695`), т.е. и при override тоже. Override — только для правки шаблона настроек клиента (`window.lampa_settings`); в проекте не используется.
- **Магазин плагинов** в Lampa (Настройки → Плагины) читает `/extensions` → образный `LampaWeb/plugins/extensions.json` (override-монтирование отключено). **Дефект образа:** 15 записей каталога ссылаются на `127.0.0.1:9118/plugins/*.js` (pubtorr, checker, hotkeys, torrents...) — HTTP-роута `/plugins/` в коде нет, все эти ссылки битые, устанавливать из магазина такие записи нельзя. Рабочий путь — прямой внешний URL (ручной установкой в Лампе или через `LampaWeb.customPlugins`; так подключён PubTorr: `https://lampame.github.io/main/pubtorr.js`). Если плагин уже установился с битым URL — удалить его в Лампе (Настройки → Плагины), иначе дедуп не даст добавить правильный (семейство `pubtorr.js`). Ответ кешируется `Staticache` на диске: `cache/static/<bucket>/` — после правки удалить соответствующий файл (`grep -rl secuses cache/static/`) или весь каталог static, затем перезапросить.
- **Плагины модулей для ручной установки в Лампе** (Настройки → Плагины → по URL): `/tracks.js`, `/music.js`, `/tg-notify.js`, `/watchtogether.js` (проверяются `curl -o /dev/null -w '%{http_code}' http://localhost:9118/<name>.js` → 200).
5. Новые пользовательские модули и копии включаемых — класть в `mods/<Name>/` (один том `./mods:/lampac/mods`), переопределения шаблона настроек клиента — `plugins/lampainit.js` → `/lampac/plugins/override/lampainit.js` (модули через это НЕ подключаются — см. п.4).
6. Не раскрывать пароль из `passwd`, не коммитить его, не выводить в логи.
7. Не открывать порт 9118 в интернет без файрвола/reverse proxy; модули `DLNA`, `Tracks`, `Transcoding`, `GStreamer`, `Catalog` не предназначены для публичного доступа.
8. Образ пиннить по тегу при необходимости воспроизводимости (в compose сейчас `:latest`).
Модуль грузится, только если выполнены **все**:
## Структура контейнера (важные пути)
| Фильтр | Где |
|---|---|
| `"enable": true` | `manifest.json` модуля (копия в `mods/` для встроенных) |
| Имя **не** в `BaseModule.SkipModules` | `base.conf` (в образе) + `config/init.conf` |
| Имя попадает в `BaseModule.LoadModules` | если allowlist задан (у нас не задан — грузится всё остальное) |
| Runtime-флаг | секция модуля в `config/init.conf`, например `"gst": { "enable": true }` |
```text
/lampac/
├── init.conf # конфиг (смонтирован с хоста)
├── passwd # пароль root (смонтирован с хоста)
├── cache/ # кеш (смонтирован)
├── database/ # SQLite и бэкапы конфига (смонтирован)
├── mods/ # пользовательские модули (Roslyn компилирует .cs на лету)
├── module/ # встроенные модули образа
├── plugins/override/ # переопределения JS-плагинов
└── wwwroot/ # статика Lampa UI
`SkipModules` имеет приоритет над `LoadModules` — модуль из обоих списков **не** грузится. Паттерны: точное имя, группа (`OnlineUKR`), regex (`LME.*`), `.*`.
### 3. `config/init.conf` — валидный JSON
JSON **без** trailing comma. Перед применением правок проверять:
```bash
python3 -m json.tool config/init.conf > /dev/null && echo OK
```
Горячая перезагрузка: `init.conf` watcher каждую секунду; `mods/*.cs` перекомпилируются при изменении.
После правки конфига: `docker compose restart` (том смонтирован, `up -d` не нужен). После правки `manifest.json` в `mods/` с `dynamic: true` — тоже `restart` (или ждать hot-rebuild). После изменения томов в compose — `docker compose up -d`.
## Troubleshooting
### 4. Клиентские плагины Lampa
- **Контейнер нестабилен / Chromium падает** — проверить `shm_size: 1024mb` в compose (обязательно для Playwright).
- **Не стартует после правки init.conf** — проверить JSON: `python3 -m json.tool config/init.conf`; бэкапы в `/lampac/database/backup/init/`.
- **Модуль не загрузился** — смотреть `docker compose logs lampac | grep -E "skip compilation|loaded module"`; для модулей с `enable: false` в образе — копия в `mods/` с `enable: true` (см. п.4), монтирование одиночных manifest не используется.
- **Tg-notify молчит** — нужен `bot_token` в секции `TelegramBot` init.conf (без него long polling не стартует, в логе предупреждение).
- **Занят порт 9118** — `lsof -i :9118` или сменить порт в `init.conf` (`listen.port`) и в `ports` compose-файла одновременно.
- **Сеть** — в compose нет фиксированной сети/subnet; используется дефолтная сеть проекта (`lampac_default`).
- **Обновление сломало конфиг** — свериться с https://github.com/lampac-nextgen/lampac/blob/main/config/example.init.conf (новые ключи добавляются в стартовый конфиг).
- Встроенные плагины: флаги `LampaWeb.initPlugins` (`tracks`, `dlna`, `catalog`, `sync`, `backup`, ...).
- Дополнительные: `LampaWeb.customPlugins` — записи со `status: 1` добавляются как есть; поддерживается плейсхолдер `{localhost}` (подставляется реальный адрес сервера).
- Если плагин «не виден» в веб-клиенте — сначала проверить HTTP-статус его URL на сервере (`curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:9118/<плагин>.js`), а не лезть в клиент.
### 4.1 Каталог плагинов (store) `/extensions`
- Раздел «Плагины» веб-клиента грузит каталог с `/extensions` (при `LampaWeb.initPlugins.pirate_store: true`).
- Источник: `/lampac/module/LampaWeb/plugins/extensions.json` — переопределён mount из `./plugins/extensions.json`. Править хост-файл, в контейнер не залезать.
- `{localhost}` в ссылках store сервер заменяет своим адресом при выдаче.
- Статика: `/lampac/plugins/` **не раздаётся** (проверено: файл → 404), корень `wwwroot` — раздаётся. Все плагины каталога — **локальный mirror** в `./plugins/`, смонтирован **одним directory-mount** в `/lampac/wwwroot/plugins/` → ссылки store `{localhost}/plugins/<имя>.js`. Не монтировать каталог целиком в корень `wwwroot` — скроется веб-клиент `lampa-main`.
- Обновление плагина: исходный URL — в `plugins/sources.json`; скачать, перезаписать файл, перезапуск не нужен (статика).
- При проверке скачанного плагина отличать: (а) реальный код, (б) лоадер `putScriptAsync` (абсолютные URL — безопасен локально; host от currentScript — **требуется патч**, см. showy.js), (в) пустой stub/placeholder (мёртвый плагин, из каталога удалять).
- **Кеш-ловушка**: ответ `/extensions` (и других LampaWeb-маршрутов) кешируется на диск в `cache/static/<bucket>/<id>.json`; кеш переживает `docker compose restart`. После правки store: `rm -rf cache/static/59` (bucket `/extensions`), перезапуск не нужен. Заголовок `X-StatiCache-Status: HIT/MISS` показывает состояние.
### 5. AdminPanel API из скриптов (root-авторизация)
- Root-пароль = содержимое `config/passwd`. Механизм: cookie `accspasswd=<пароль>` (таков штатный сценарий: страница входа `auth.html` сама кладёт пароль в эту cookie). Заголовок `lcrqpasswd` — для внутренних вызовов, на `/adminpanel/api/*` с ним уходит 302 на `/adminpanel/auth`.
- Не передавать root-пароль в query string (предупреждение доков).
- Сервер может отвечать 404 вместо 401/403, чтобы не раскрывать админский endpoint.
- Основные маршруты: `GET /adminpanel/api/init` (чтение), `POST /adminpanel/api/init` (полная запись), `POST /adminpanel/api/init/section/{key}` (секция), `GET /adminpanel/api/current` (merged-конфиг), `GET /adminpanel/api/users-json`.
- Правка секций через API пишется в `init.conf` — watcher подхватит без рестарта (runtime-параметры). `customPlugins` — runtime-параметр: плагин появляется в `/lampainit.js` через ~1 с.
### 6. Диагностика «модуль не найден»
Чек-лист (в этом порядке):
1. `curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:9118/<маршрут>` — 404 подтверждает, что модуль не загружен.
2. `docker logs lampac | grep -E "compilation|loaded module" | grep <Имя>` — скомпилирован ли и загружен ли.
3. Манифест: `enable: true`? (в `mods/` для встроенных)
4. Фильтры `SkipModules`/`LoadModules` в `config/init.conf`.
5. Runtime-секция модуля в `config/init.conf`.
6. В логе после старта ожидаются строки `compilation <Имя>`, `configure module: <Имя>` (если есть конфиг-секция), `loaded module: <Имя>`.
### 7. Команды эксплуатации
```bash
docker compose up -d # запуск / пересоздание (при изменении compose)
docker compose restart # после правки init.conf / mods
docker compose logs -f # логи
docker compose pull && docker compose up -d # обновление (сначала поменять тег в compose)
docker exec lampac sh -c '...' # осмотр состояния в контейнере
```
`container_name: lampac` — контейнер один; одновременный запуск нескольких compose-файлов с одним именем невозможен. `docker-compose.override.yml` (gitignore) живёт только на сервере Proxmox и не коммитится.
### 8. Чего не трогать
- `config/passwd`, `cache/`, `database/`, `dlna/` — в .gitignore, не коммитить и не «чинить» содержимое.
Исключение: `cache/static/` — одноразовый диск-кеш ответов LampaWeb; очистка (`rm -rf cache/static/<bucket>`) — штатное действие после правки store/статических маршрутов (см. 4.1).
- Тег образа в `docker-compose.yaml` закреплён — при обновлении менять осознанно и проверить доки по новой версии.
- `LampaWeb.autoupdate` — веб-клиент Lampa сам обновляется из git (`yumata/lampa`), `wwwroot/lampa-main` в контейнере перезаписывается — туда не править.
### 9. После изменений в проекте
Обновлять `README.md` и `AGENT.md` в той же ревизии: структура, включённые модули, секции конфига, новые правила.
### 10. Безопасность (не публиковать)
`config/passwd`, cookie `accspasswd`, заголовок `lcrqpasswd`, `bot_token` в `TelegramBot`. Маршруты `/adminpanel`, `/weblog`, `Tracks`, `Catalog`, `DLNA`, proxy-модули — только для доверенной сети без WAF не открывать.