345 lines
32 KiB
Markdown
345 lines
32 KiB
Markdown
Lampac NextGen — локальный Docker-развёртывание
|
||
|
||
> Сервер: Proxmox VM 130 «lampac», Debian 13, 192.168.88.243, логин prodik. Детали — AGENT.md (раздел Размещение на сервере).
|
||
|
||
Локальное развёртывание [Lampac NextGen](https://github.com/lampac-nextgen/lampac) — самохостируемого бекенда для Lampa — в Docker. Официальная документация: [docs.lampac.dev](https://docs.lampac.dev).
|
||
|
||
## Быстрый старт
|
||
|
||
```bash
|
||
docker compose up -d # первый запуск
|
||
docker compose logs -f # логи (строки compilation / configure module / loaded module)
|
||
docker compose restart # после правки config/init.conf или манифестов в mods/
|
||
```
|
||
|
||
- Веб-клиент Lampa: **http://localhost:9118**
|
||
- Админ-панель: **http://localhost:9118/adminpanel** (root-пароль из `config/passwd`)
|
||
- TorrServer-прокси: `http://localhost:9118/ts/*` (порт TorrServer — 9085)
|
||
|
||
По умолчанию сервер слушает порт **9118**; если порт занят — меняй `listen.port` в `config/init.conf` до первого запуска.
|
||
|
||
## Первая установка: SQLite не может создать базу в named volume
|
||
|
||
**Симптом.** Свежий `docker compose up -d` уходит в crash-loop (`Restarting (139)`, healthcheck `unhealthy`), в логах:
|
||
|
||
```
|
||
Unhandled exception. Microsoft.Data.Sqlite.SqliteException (0x80004005):
|
||
SQLite Error 14: 'unable to open database file'.
|
||
at Microsoft.Data.Sqlite.SqliteConnection.Open()
|
||
at Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal.SqliteDatabaseCreator.Create()
|
||
at Microsoft.EntityFrameworkCore.RelationalDatabaseCreator.EnsureCreated()
|
||
at Core.Program.Run(String[] args)
|
||
```
|
||
|
||
**Причина.** Процесс в контейнере работает от uid `1000` (пользователь образа `lampac`), а Docker при первом создании named volume делает его владельцем `root:root`. Смонтированный каталог `/lampac/database` поэтому недоступен на запись для `lampac`, `sqlite3` получает `EACCES` и приложение падает сразу после `EnsureCreated()` — база не создаётся ни разу, поэтому изнутри контейнера это не лечится.
|
||
|
||
Та же первопричина у второй ошибки первого запуска:
|
||
|
||
```
|
||
System.UnauthorizedAccessException: Access to the path '/lampac/passwd' is denied.
|
||
```
|
||
|
||
`config/passwd` монтируется файлом и тоже должен принадлежать uid `1000`.
|
||
|
||
**Лечение** — на хосте, от root:
|
||
|
||
```bash
|
||
# тома (первый запуск или миграция/копия томов)
|
||
chown -R 1000:1000 /var/lib/docker/volumes/lampac_database/_data \
|
||
/var/lib/docker/volumes/lampac_cache/_data
|
||
|
||
# файл пароля (владелец 1000, права 600 — читает только процесс контейнера)
|
||
chown 1000:1000 config/passwd && chmod 600 config/passwd
|
||
|
||
docker compose up -d # или docker compose restart, если контейнер уже создан
|
||
```
|
||
|
||
**Проверка:**
|
||
|
||
```bash
|
||
docker compose ps # Up (healthy)
|
||
docker logs --since 2m lampac | grep -ci unhandled # 0
|
||
ls -ln /var/lib/docker/volumes/lampac_database/_data/Sisi.sql # uid/gid 1000
|
||
```
|
||
|
||
> После лечения в `lampac_database` должны появиться `Sisi.sql`, `Sync.sql`, `TimeCode.sql`, `tgnotify/`, `tracks/`, `storage/` — это и есть признак, что базы созданы.
|
||
|
||
Проверить uid процесса в контейнере: `docker exec lampac id` → `uid=1000(lampac)`.
|
||
|
||
Правило: **любой bind-mount файл/каталог, в который пишет контейнер, должен принадлежать `1000:1000`** (см. `.gitignore` для `config/passwd`, `dlna/`, `lampa-main/`).
|
||
|
||
## Секреты (вынесены из git)
|
||
|
||
Модули `TelegramBot`, `TelegramAuthBot`, `TelegramAuth` читают `bot_token` и `mutations_api_secret` из конфига. В репозитории эти поля **всегда пустые** — реальные значения живут в файле, который не коммитится.
|
||
|
||
| Файл | В git? | Назначение |
|
||
|---|---|---|
|
||
| `config/init.conf` | ❌ .gitignore | Шаблон конфига, живёт только локально (не коммитится, в т.ч. в `Home/lampac`). Именно его редактируете для обычных настроек (`listen`, `SkipModules`, `initPlugins`, модули). |
|
||
| `config/secrets.env` | ❌ .gitignore | Токены ботов и `mutations_api_secret`. `TELEGRAM_NOTIFY_BOT_TOKEN`, `TELEGRAM_AUTH_BOT_TOKEN`, `TELEGRAM_AUTH_MUTATIONS_SECRET`. |
|
||
| `config/init.custom.conf` | ❌ .gitignore | Боевой конфиг, который монтируется в контейнер. Собирается из шаблона + `secrets.env` скриптом. |
|
||
| `scripts/config-secrets.py` | ✅ | Собирает/разбирает боевой конфиг: `apply`, `export`, `check`, `status`. |
|
||
| `scripts/install-git-hooks.sh` | ✅ | Устанавливает хуки: `post-merge`/`post-checkout` → `apply`, `pre-commit` → `check`. |
|
||
| `docker-compose.yaml` | ✅ | Монтирует `./config/init.custom.conf:/lampac/init.conf` (не `init.conf`). |
|
||
|
||
**Рабочий процесс:**
|
||
|
||
```bash
|
||
# первый раз / после git pull:
|
||
python3 scripts/config-secrets.py apply # init.custom.conf = шаблон + secrets.env
|
||
docker compose up -d # рекреация из-за нового mount
|
||
|
||
# правки в init.conf:
|
||
# 1) правите config/init.conf (шаблон)
|
||
# 2) python3 scripts/config-secrets.py apply -> обновляет init.custom.conf
|
||
# 3) docker compose restart lampac
|
||
|
||
# перед коммитом (init.conf не коммитится — он в .gitignore):
|
||
git add -A
|
||
git commit -m "..."
|
||
```
|
||
|
||
**Git-хуки (рекомендуется):** `bash scripts/install-git-hooks.sh` — после `git pull`/смены ветки `apply` запустится сам, а `pre-commit` не даст случайно закоммитить секреты.
|
||
|
||
> `docker-compose.override.yml` (в .gitignore) — серверный override для Proxmox (том DLNA -> `/mnt/torrents`), живёт только на сервере.
|
||
|
||
## Структура проекта
|
||
|
||
| Путь | Назначение |
|
||
|---|---|
|
||
| `docker-compose.yaml` | Основной сервис (образ `ghcr.io/lampac-nextgen/lampac:1.68.1`) |
|
||
| `docker-compose.override.yml` | Серверный override (Proxmox: том DLNA -> `/mnt/torrents`), в .gitignore |
|
||
| `config/init.conf` | Шаблон конфига (JSON, в .gitignore — только локально) |
|
||
| `config/init.custom.conf` | Боевой конфиг (в .gitignore, монтируется в `/lampac/init.conf`) |
|
||
| `config/secrets.env` | Токены ботов и `mutations_api_secret` (в .gitignore) |
|
||
| `config/passwd` | Пароль root для `/adminpanel` и `/weblog` (в .gitignore) |
|
||
| `lampa-main/` | Веб-клиент Lampa (в git, bind-mount в `/lampac/wwwroot/lampa-main`) |
|
||
| volume `lampac_cache` | Кеш (`/lampac/cache`) — Docker named volume |
|
||
| volume `lampac_database` | SQLite-базы Sync, TimeCode, tg-notify, tracks, storage (`/lampac/database`) — Docker named volume |
|
||
| `dlna/` | Локальные медиа для DLNA (`/lampac/data/dlna`) |
|
||
| `plugins/extensions.json` | Каталог плагинов для веб-клиента (раздел «Плагины»), отдаётся через `/extensions` |
|
||
| `mods/<Имя>/` | Пользовательские копии встроенных модулей с `enable: true` |
|
||
|
||
> Веб-клиент `lampa-main` **хранится в git** (каталог `lampa-main/`) и смонтирован bind-mountом в `/lampac/wwwroot/lampa-main` (в `docker-compose.override.yml` на сервере), поэтому переживает пересоздание контейнера. В образе клиента нет, а `LampaCron` автообновление из GitHub не докачивает (на сервере нет доступа к GitHub) — поэтому клиент держим в репозитории. Обновить клиент: скачать архив с https://github.com/yumata/lampa/archive/refs/heads/main.zip, распаковать в `lampa-main/` (топ-каталог `lampa-main-main` переименовать в `lampa-main`), `chown -R 1000:1000 lampa-main`, закоммитить; на сервере `git pull` — перезапуск не нужен (статика). См. также `scripts/restore-lampa-main.sh`.
|
||
|
||
## Включённые модули из `mods/`
|
||
|
||
Встроенные модули с `"enable": false` в `manifest.json` внутри образа **нельзя включать правкой файла в контейнере** — файлы пропадут при обновлении. Механика по официальной документации ([модули Lampac](https://docs.lampac.dev/modules/overview), [пользовательские модули](https://docs.lampac.dev/maintenance/custom-modules)):
|
||
|
||
1. Скопировать модуль из образа в `mods/<Имя>/` на хосте:
|
||
```bash
|
||
docker cp lampac:/lampac/module/<Имя> "mods/<Имя>"
|
||
```
|
||
2. В `mods/<Имя>/manifest.json` поставить `"enable": true`.
|
||
3. Добавить том в `docker-compose.yaml`:
|
||
```yaml
|
||
- ./mods/<Имя>:/lampac/mods/<Имя>
|
||
```
|
||
4. При необходимости добавить секцию модуля в `config/init.conf` (runtime-флаг).
|
||
5. `docker compose up -d` (при добавлении тома) или `restart` (при правке манифеста с `dynamic: true`).
|
||
|
||
### Сейчас подключены
|
||
|
||
| Модуль | Что даёт | Секция в init.conf |
|
||
|---|---|---|
|
||
| `Tracks` | `/tracks.js`, `/ffprobe` — субтитры и дорожки | `"Tracks": { "enable": true }` |
|
||
| `AdminPanel` | `/adminpanel` — редактор init.conf, current.conf, users.json | `"AdminPanel": { "enable": true }` |
|
||
| `Tg-notify.bot` | `/tg-notify.js`, `/api/tg/*` — уведомления о новых сериях в Telegram | секция `"TelegramBot"` |
|
||
| `TelegramAuth` | `/tg/auth/*` — привязка UID устройства к учётке Telegram, HTTP API статуса | секция `"TelegramAuth"` (`enable: false` → без accsdb-гейта) |
|
||
| `TelegramAuthBot` | `@GatusMonBot` — long-polling бот привязки и админ-команды | секция `"TelegramAuthBot"` |
|
||
|
||
Клиентский плагин `tg-notify.js` зарегистрирован в `LampaWeb.customPlugins`; `{localhost}` в URL автоматически подставляется сервером.
|
||
|
||
> **Модуль `Music` удалён из `mods/`** (коммит `remove Music`): в образе у него `manifest.enable: false`, поэтому `/music.js` → 404, секция `"Music"` из `init.conf` убрана, плагин из `customPlugins` убран. Вернуть музыку — той же механикой: скопировать `lampac:/lampac/module/Music` в `mods/Music`, поставить `enable: true`, вернуть секцию и плагин.
|
||
|
||
### Ещё можно включить тем же способом
|
||
|
||
В образе выключены также: `DatabaseEditor`, `ExternalBind`, `LogUserRequest-Lite`, `Transcoding`, `Music`, `WatchTogether`.
|
||
|
||
## Конфигурация
|
||
|
||
- `config/init.conf` — JSON. После правки: `docker compose restart`. Следи за валидностью JSON (лишняя запятая ломает парсинг).
|
||
- `BaseModule.SkipModules` / `BaseModule.LoadModules` — фильтры загрузки модулей (имя, группа, regex). `SkipModules` имеет приоритет над `LoadModules`.
|
||
- `LampaWeb.initPlugins` — флаги встроенных плагинов веб-клиента; `LampaWeb.customPlugins` — дополнительные плагины (`status: 1`).
|
||
- `LampaWeb.autoupdate: true` — Lampa Web-клиент автообновляется из `yumata/lampa` (раз в 90 минут).
|
||
|
||
## Установка плагинов по ссылке через веб (AdminPanel)
|
||
|
||
Список плагинов, который сервер раздаёт всем клиентам через `/lampainit.js` и `/on.js`, собирается по `LampaWeb.initPlugins` + `LampaWeb.customPlugins`. Watcher перечитывает `init.conf` без перезапуска (интервал ~1 с, runtime-параметры применяются на лету).
|
||
|
||
1. Открой **http://localhost:9118/adminpanel**, введи root-пароль (содержимое `config/passwd`) — пароль сохраняется в cookie `accspasswd` (штатный механизм root-авторизации).
|
||
2. В редакторе `init.conf` открой секцию **`LampaWeb`** → **`customPlugins`** и добавь запись:
|
||
```json
|
||
{ "url": "https://example.com/plugin.js", "status": 1, "name": "ИмяПлагина" }
|
||
```
|
||
Поддерживается плейсхолдер `{localhost}` — сервер подставит свой адрес.
|
||
3. Сохрани — перезапуск не нужен. Проверка: `curl -s http://localhost:9118/lampainit.js | grep <имя>`.
|
||
|
||
Нюансы:
|
||
- `status: 1` — активная запись.
|
||
- Family-dedup: `name.js` и `name/js/{token}` считаются одним плагином; если в registry клиента уже есть один вариант, второй из серверного списка не добавляется.
|
||
- Внешние URL должны быть доступны из браузеров клиентов и отдавать CORS-заголовки.
|
||
- Альтернатива без сервера: вставить ссылку напрямую в веб-клиенте Lampa (настройки → «Плагины») — тогда плагин живёт только в localStorage этого браузера и грузится браузером напрямую.
|
||
|
||
API (для скриптов): `GET/POST /adminpanel/api/init`, `POST /adminpanel/api/init/section/{key}` с cookie `accspasswd=<root-пароль>`.
|
||
|
||
## Каталог плагинов (раздел «Плагины» в веб-клиенте)
|
||
|
||
В веб-клиенте Lampa раздел «Плагины» грузит каталог (store) с маршрута **`/extensions`** (включается при `LampaWeb.initPlugins.pirate_store: true`). Содержимое берётся из файла `LampaWeb/plugins/extensions.json` модуля — у нас он переопределён файловым mount из `./plugins/extensions.json` (см. `docker-compose.yaml`). Плейсхолдер `{localhost}` в ссылках сервер заменяет своим адресом.
|
||
|
||
**Все плагины каталога размещены локально** (mirror): `.js`-файлы лежат в `./plugins/`, каталог целиком смонтирован в `/lampac/wwwroot/plugins/` (одна строка в compose) и ссылки в каталоге ведут на `{localhost}/plugins/<имя>.js`. (Целиком в корень `wwwroot` монтировать нельзя — перекроется веб-клиент `lampa-main`.) Сами файлы плагинов всегда локальные; исключение — плагин-лоадеры, подгружающие основной код с внешнего хоста: «Клубничка 18+» (rc.bwa.ad) и Showy (showy.online/online.js — файл локально патчен под абсолютный URL, иначе он бы подгружал `/online.js` с нашего сервера). Остальные скачаны целиком (для pubtorr / torrentmanager / td скачано тело, а не лоадер).
|
||
|
||
- `plugins/sources.json` — карта «локальный файл → исходный URL». Для обновления плагина: скачать файл по исходному URL, перезаписать локальный, перезапуск не нужен.
|
||
- `plugins/modss.js` — локальная patched-копия MODS's (заменён вызов `Lampa.Utils.isPWA()`), раздаётся как `/plugins/modss.js`, но из каталога исключена (upstream мёртв: загрузчик отвечает stub-ошибкой «Используйте: lampa.mx»). Вернуть карточку можно, добавив запись с `link: "{localhost}/plugins/modss.js"`.
|
||
|
||
Удалены из каталога (мёртвы upstream, проверено по факту выдачи):
|
||
- «MODS's» (`lampa.stream/modss`) — загрузчик отвечает stub-ошибкой;
|
||
- «Отзывы и рецензии» (`lampaplugins.github.io/store/o.js`) — файл заменён автором на пустой stub;
|
||
- «Вторая кнопка Торренты», «Поиск локального TorrServer», «Горячие кнопки», «Золотая Тема», «Тип управления», «Старый стиль», «Мультфильмы» — публичных копий нет;
|
||
- «Телевидение by Skaz» / «ТВ by skaz» / «ТВ by skaz 2.0» — файлы заменены placeholder-заглушками;
|
||
- «Импорт/Экспорт закладок, истории» (`skaz.tv/export.js`) — 404.
|
||
|
||
Важный нюанс — **диск-кеш ответа**: маршруты LampaWeb кешируют ответы в `/lampac/cache/static/<bucket>/<id>.json` (named volume `lampac_cache`), кеш переживает рестарт контейнера. После правки `extensions.json` для мгновенного применения удалить закешированную запись:
|
||
|
||
```bash
|
||
docker exec lampac rm -rf /lampac/cache/static/59 # bucket /extensions; либо весь /lampac/cache/static
|
||
```
|
||
|
||
Перезапуск контейнера при этом **не требуется** (маршрут читает файл при каждом запросе, если нет кеш-записи).
|
||
|
||
## Tg-notify.bot: Telegram-бот уведомлений о новых сериях
|
||
|
||
Фоновый Telegram-бот (long polling): пользователь подписывается на сериал прямо из карточки Lampa, бот отслеживает выход новых эпизодов и появление выбранной озвучки и шлёт в Telegram уведомление с обложкой, номером серии и описанием из TMDB.
|
||
|
||
Модуль объединяет три подсистемы:
|
||
1. **Трекер новых серий** — Trakt API (если задан `trakt_client_id`), иначе TMDB.
|
||
2. **Трекер озвучек** — параллельный опрос встроенных балансиров **Mirage**, **Collaps** и **VideoHub** через `lampac_host` (`/lite/mirage`, `/lite/collaps`, `/lite/cdnvideohub`); берётся максимальный эпизод из всех источников.
|
||
3. **Клиентский плагин** `tg-notify.js` — вкладка «TG Подписки», перехват кнопки 🔔 в карточке, меню выбора озвучки.
|
||
|
||
### Как это работает (поток)
|
||
|
||
1. **Привязка аккаунта** — во вкладке «TG Подписки» в Lampa выдаётся deep-link `/start link_{uid}` (для UID вида email — `/start link64_{base64url(uid)}`). После `/start` бот сохраняет связку `chat_id ↔ lampac_uid` в `database/tgnotify/users.json`; подписки становятся общими для всех устройств этого аккаунта.
|
||
2. **Подписка** — в карточке сериала кнопка 🔔 перехватывается плагином, показывается меню озвучек (`GET /api/tg/voices`), выбор уходит на `POST /api/tg/subscribe` и сохраняется в `subscriptions.json`.
|
||
3. **Фоновый цикл `CheckAll`** — раз в `check_interval_minutes` (первый прогон — через 2 минуты после старта, вручную — `/check`): новые серии через Trakt→TMDB; если выбрана конкретная озвучка — параллельно Mirage + Collaps + VideoHub.
|
||
4. **Уведомление** — сообщение вида:
|
||
|
||
```
|
||
🎬 Название
|
||
🎙 Озвучка
|
||
📺 S05E08 — Название эпизода
|
||
|
||
Описание (до 300 символов)
|
||
```
|
||
|
||
с обложкой кадра из TMDB (`still_path`), если есть.
|
||
|
||
### Конфигурация (секция `TelegramBot` в `config/init.conf`)
|
||
|
||
| Поле | Назначение |
|
||
|---|---|
|
||
| `bot_token` | Токен от [@BotFather](https://t.me/BotFather). **Обязателен** — без него long polling не стартует (в логе предупреждение, сервер работает) |
|
||
| `tmdb_api_key` | Ключ TMDB v3: обложки, описания эпизодов, определение актуального сезона |
|
||
| `trakt_client_id` | Client ID Trakt; основной источник новых серий (если пуст — только TMDB) |
|
||
| `lampac_host` | Базовый URL Lampac для запросов к балансерам; в Docker — `http://127.0.0.1:9118` |
|
||
| `lampac_token` | Токен `accsdb`; обязателен, если включена защита (иначе балансеры вернут ошибку входа) |
|
||
| `kp_api_key` | Ключ kinopoiskapiunofficial.tech — резолвинг `tmdb_id → kinopoisk_id` по названию для VideoHub (опционально; без него покрытие ~40% через мост `/externalids`) |
|
||
| `check_interval_minutes` | Период фоновой проверки (дефолт 60) |
|
||
| `tmdb_lang` | Язык метаданных TMDB (дефолт `ru-RU`, фоллбэк `en-US`) |
|
||
| `data_dir` | Каталог `users.json`/`subscriptions.json` (дефолт `database/tgnotify` — у нас это том `./database/`, переживает рестарты) |
|
||
|
||
### Быстрый старт
|
||
|
||
1. [@BotFather](https://t.me/BotFather) → `/newbot` → получить токен.
|
||
2. `config/init.conf` → `TelegramBot.bot_token` = токен.
|
||
3. `docker compose restart lampac` (по желанию — заполнить `tmdb_api_key` и `trakt_client_id`).
|
||
4. В Lampa (http://localhost:9118) вкладка «TG Подписки» → deep-link → `/start` у бота.
|
||
5. В карточке сериала — 🔔, выбрать озвучку (или «без озвучки» — уведомление о самом факте выхода серии).
|
||
|
||
### Команды бота
|
||
|
||
| Команда | Действие |
|
||
|---|---|
|
||
| `/start` | Приветствие; `/start link_{uid}` — привязка аккаунта |
|
||
| `/list` | Список активных подписок |
|
||
| `/check` | Принудительная проверка в фоне |
|
||
| `/help` | Справка |
|
||
| `/unlink` | Отвязать аккаунт |
|
||
|
||
### HTTP API
|
||
|
||
| Метод | Маршрут | Назначение |
|
||
|---|---|---|
|
||
| `GET` | `/tg-notify.js` | Раздача клиентского плагина (AllowAnonymous) |
|
||
| `POST` | `/api/tg/subscribe` | Подписка на сериал/озвучку |
|
||
| `POST` | `/api/tg/unsubscribe` | Отписка |
|
||
| `GET` | `/api/tg/status?tmdb_id=` | Статус подписки текущего пользователя |
|
||
| `GET` | `/api/tg/voices?title=&year=&season=&tmdb_id=` | Доступные озвучки (Mirage + Collaps + VideoHub) |
|
||
| `GET` | `/api/tg/link` | Deep-link для привязки бота |
|
||
| `GET` | `/api/tg/subscriptions` | Все подписки пользователя с метаданными |
|
||
|
||
Все маршруты, кроме `/tg-notify.js` и `/api/tg/voices`, требуют `requestInfo.user_uid` (вход в аккаунт).
|
||
|
||
### Состояние на нашем инстансе
|
||
|
||
- Модуль загружен, `/tg-notify.js` → 200, плагин уже в `LampaWeb.customPlugins`, вкладка «TG Подписки» видна; аккаунт привязан (`database/tgnotify/users.json`).
|
||
- `bot_token` заполняется **только локально**: в git поле пустое (правило 10), токен вставлен в `config/init.conf` на сервере и при работе `@KlinkerZabbixBot` (`[TelegramBot] @KlinkerZabbixBot запущен!`). После любого `git pull`/правки конфига токен нужно вернуть на место — иначе polling не стартует.
|
||
- Трекинг озвучек зависит от балансиров: на текущий момент `GET /lite/mirage` → тело `disable`, `GET /lite/collaps` → `503` — до тех пор, пока они не будут доступны (или не включится `lampac_token` при защите), бот будет уведомлять только о выходе серий (TMDB/Trakt).
|
||
|
||
## TelegramAuth + TelegramAuthBot: вход в Lampa через Telegram
|
||
|
||
Пара модулей из группы **Community** — замена пароля аккаунта подтверждением в Telegram (сценарий: ТВ, где вводить пароль неудобно). Не путать с Tg-notify.bot — тот только уведомляет о сериях.
|
||
|
||
- **`TelegramAuth`** — серверная часть: хранение пользователей/устройств, HTTP API `/tg/auth/*`, синхронизация UID в `accsdb`; **Telegram Auth Gate** — вместо экрана `deny.js` (модалка пароля) показывает fullscreen-оверлей с UID, кнопкой «Открыть Telegram» и QR-кодом на крупных экранах.
|
||
- **`TelegramAuthBot`** — long-polling бот: пользователь открывает бота (`/start link_{uid}` или отправляет UID), бот сам вызывает `POST /tg/auth/bind/complete`; есть админ-команды. HTTP UI нет.
|
||
|
||
Активация гейта — только при трёх условиях сразу: `accsdb.enable: true` + `LampaWeb.telegramAuthGate.enabled: true` + непустой `botUsername`. Иначе тихий откат на `deny.js`.
|
||
|
||
Конфиг (по образцу `init.merge.example.json` модулей):
|
||
|
||
```json
|
||
"TelegramAuth": {
|
||
"enable": true,
|
||
"mutations_api_secret": "SECRET"
|
||
},
|
||
"TelegramAuthBot": {
|
||
"enable": true,
|
||
"bot_token": "ТОКЕН_ОТ_BOTFATHER",
|
||
"mutations_api_secret": "SECRET"
|
||
},
|
||
"LampaWeb": {
|
||
"telegramAuthGate": {
|
||
"enabled": true,
|
||
"botUsername": "имя_бота_без_@",
|
||
"serviceName": "lampa"
|
||
}
|
||
}
|
||
```
|
||
|
||
`mutations_api_secret` должен совпадать в обоих модулях и быть ненулевым — защищает `bind/complete` и бот-админку; вместе с `bot_token` не публиковать. Оба модуля выключены в `base.conf` (`SkipModules`) и в манифестах (`enable: false`).
|
||
|
||
**Состояние у нас:** модули **включены** (копии в `mods/TelegramAuth/` и `mods/TelegramAuthBot/`, манифесты `enable: true`, `SkipModules` пуст), работают в **API-режиме**: `TelegramAuth.enable: false` → `accsdb` не поднимается, гейт неактивен, доступ не режется. Бот `@GatusMonBot` — `Telegram API OK`, long polling идёт; `owner_telegram_ids: [143672]` создаёт владельца ролью `admin` при старте, `auto_provision_users: true` + `auto_provision_activate_immediately: false` — новые привязки висят в pending до одобрения кнопкой у админа. Секрет `mutations_api_secret` (одинаков в обеих секциях) и `bot_token` лежат в `config/init.conf` **только на сервере**.
|
||
|
||
**Порядок включения гейта (когда решим):** поставить `TelegramAuth.enable: true` → в `LampaWeb` секцию `telegramAuthGate` (`enabled: true`, `botUsername: "GatusMonBot"`) → подключить клиентский оверлей (`deny.js` / `telegram_auth_gate.js`) → **сначала связать свои устройства через бота**, иначе текущие UID получат отказ.
|
||
|
||
## Обновление Lampac
|
||
|
||
```bash
|
||
docker compose pull
|
||
docker compose up -d
|
||
```
|
||
|
||
Перед обновлением проверить, что в `docker-compose.yaml` раскомментированы нужные тома. Данные сохраняются в примонтированных томах: `config/`, `cache/`, `database/`, `dlna/`, `mods/`, `lampa-main/`.
|
||
|
||
`wwwroot/lampa-main` смонтирован как bind-mount из `./lampa-main/` (см. раздел «Структура проекта»), поэтому переживает рекреацию контейнера. Если директория на хосте пуста — `bash scripts/restore-lampa-main.sh scripts/lampa-main.zip` (архив берётся с https://github.com/yumata/lampa/archive/refs/heads/main.zip).
|
||
|
||
**Образ закреплён точным digest** (`1.68.0@sha256:752dafd8…`): тег `1.68.0` на ghcr — mutable, его переиздавали, и в новой сборке **копии модулей в `mods/`** (Roslyn компилирует их на каждом старте) перестают собираться — `CS0103` по символам из старого билда и crash-loop сервера. Чтобы обновить образ: взять новый digest, пересобрать копии модулей в `mods/` из нового образа (`docker cp lampac:/lampac/module/<Имя> mods/<Имя>` + вернуть `"enable": true`) и заменить digest в `docker-compose.yaml`. Не делать «просто» `docker compose pull` без фиксации digest.
|
||
|
||
## Безопасность
|
||
|
||
По предупреждению официальной документации:
|
||
|
||
- Не публикуй в интернет без аутентификации, WAF и ограничения сети: `/adminpanel`, `/weblog`, `/database-editor`, `Tracks`, `Transcoding`, `Catalog`, `DLNA`, proxy-модули.
|
||
- Нигде не раскрывай `config/passwd`, cookie `accspasswd`, заголовок `lcrqpasswd`.
|
||
- **Секреты в git не попадают**: `TelegramBot.bot_token`, `TelegramAuthBot.bot_token`, `mutations_api_secret` хранятся в `config/secrets.env` (в .gitignore). В git `config/init.conf` эти поля всегда пустые. Реальный боевой конфиг — `config/init.custom.conf` (тоже gitignored), собирается скриптом `scripts/config-secrets.py apply` из шаблона + секретов. Перед `git add config/init.conf`: `python3 scripts/config-secrets.py check` → должно быть `check: секретов в config/init.conf нет — ок`.
|
||
- Для публикации за reverse proxy: [deployment/reverse-proxy](https://docs.lampac.dev/deployment/reverse-proxy) (HTTPS в ответах, реальный IP клиента, WebSocket, SSE, streaming).
|
||
- `shm_size: 4096mb` — рекомендованный минимум для Playwright/Chromium.
|