From a74ce112a6654cb3d6412fbc554a772c408b5b1e Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Mon, 28 Sep 2026 01:58:17 +0600 Subject: [PATCH] [2026-09-28] eagle: family/how-to/navidrome-truenas-android.md family/plans/lidarr-taiga-deploy.md family/projects/media-toolbox-taiga.md personal/tech/skill-arr-media-stack-setup-additions.md --- family/how-to/navidrome-truenas-android.md | 11 + family/plans/lidarr-taiga-deploy.md | 469 +++++------------- family/projects/media-toolbox-taiga.md | 18 +- .../skill-arr-media-stack-setup-additions.md | 42 +- 4 files changed, 184 insertions(+), 356 deletions(-) diff --git a/family/how-to/navidrome-truenas-android.md b/family/how-to/navidrome-truenas-android.md index eae0e9e1..fc920202 100755 --- a/family/how-to/navidrome-truenas-android.md +++ b/family/how-to/navidrome-truenas-android.md @@ -683,6 +683,17 @@ Lidarr матчит по MusicBrainz release groups и пишет полные (действие `Write Metadata Tags`). Связка [`navidrome-lidarr-bridge`](https://github.com/danielbanariba/navidrome-lidarr-bridge) — закачанное Lidarr'ом подхватывается Navidrome автоматически. +> 🆕 **2026-09-28 — план деплоя Lidarr к Navidrome составлен, ждёт «go» Alex.** +> Полный план — [[family/plans/lidarr-taiga-deploy]] §2026-09-28. +> Ключевое для этой связки: +> - **Root folder Lidarr = `/storage/Music`** — та же папка, что читает Navidrome. +> - 🔴 **`Write Metadata Tags` в Lidarr ОБЯЗАТЕЛЕН.** Без него Lidarr не пишет `Album Artist`, +> и новые закачки развалятся на альбомы-одиночки в Navidrome (при отсутствии ALBUMARTIST +> Navidrome подставляет track artist — см. таблицу выше). +> - 🔴 **Существующие 7861 файл в Lidarr НЕ импортировать.** Импорт как «Existing Albums» +> заставит Lidarr перезаписать теги из MusicBrainz — правки 50 сессий ремонта тегов уедут. +> Lidarr отвечает только за новые закачки; старая библиотека остаётся как есть. + ### ⚠️ Что реально стоит починить до запуска: СЕМАНТИКА `artist` Файлы `!Классика` содержат **семантически мусорные** `artist` — формально валидные теги: diff --git a/family/plans/lidarr-taiga-deploy.md b/family/plans/lidarr-taiga-deploy.md index 122d0296..6b83cc10 100755 --- a/family/plans/lidarr-taiga-deploy.md +++ b/family/plans/lidarr-taiga-deploy.md @@ -1,366 +1,129 @@ -# Lidarr на Taiga — деплой + прокси для индексеров +# Lidarr на Taiga — деплой в связке с arr-стеком и Navidrome -**Дата:** 2026-09-26 (обновлено 2026-09-27) -**Статус:** 🟡 Фаза 0 выполнена (прокси, 3/6 индексеров зелёные). -🔴 **2026-09-27 вечер: Music-библиотека ОТКАЧЕНА** — Alex потребовал вернуть Jellyfin к состоянию -до импорта музыки. Библиотека удалена, идёт восстановление БД из найденного бэкапа. -Итоговая причина: теги в **CP1251**, Jellyfin их не читает → навигация по папкам → провал приёмки. -**Lidarr не установлен; начинать его до завершения отката нельзя.** -Актуальный план — [[family/plans/music-jellyfin-lidarr-taiga]] §ОТКАТ. -Открыто: FlareSolverr (RuTracker/Kinozal), Lidarr не установлен. +**Дата:** 2026-09-28 +**Статус:** 🟡 УТВЕРЖДЁН Alex 2026-09-28 («1 A. 2 да, пока не делать. Приступай») — идёт исполнение **Namespace:** family +**Решения Alex:** (1) переименование — **вариант A**: `Rename Tracks=ON`, `Rename Folders=ON`, +раскладка `Music/// - `, `Write Metadata Tags=ON`; +(2) импорт существующих 7861 файлов — **НЕ делать**, Lidarr отвечает только за новые закачки. ## Задача -Поставить Lidarr на TrueNAS/Taiga в дополнение к Prowlarr/Radarr/Sonarr/Transmission/Jellyfin, -настроить на музыку, обеспечить синк с Jellyfin, провести проверку живости всего стека. +Поставить Lidarr на TrueNAS/Taiga в дополнение к Prowlarr/Radarr/Sonarr/Transmission, +настроить на музыку, связать с arr-стеком (Prowlarr/Transmission) и с музыкальным +сервером Navidrome. -## ✅ ОБНОВЛЕНО 2026-09-27: блокер тегов снят, задача переставлена +## 🎯 Ключевые факты, определившие решения (проверено 2026-09-28) -**Сессия 2026-09-27 (новая задача Alex):** «Добавляй библиотеку музыки на TrueNAS в jellyfin -за исключением бэкап-папок. Потом поднимай lidarr в связку к нему и существующему arr stack.» - -> 🎉 **Ремонт тегов СРАБОТАЛ.** Выборка 108 файлов (12 × 9 категорий) через `ffprobe` -> из контейнера jellyfin: **108/108 имеют `artist`+`title`, мойибаке 0, пустых 0.** -> 40 файлов, «убитых» `fix40.py`, восстановлены из `backup_conv40` — целые, с тегами. -> **Поэтому решение «Jellyfin Music — НЕ ТРОГАТЬ» (2026-09-26, пункт 3 таблицы выше) устарело.** - -> 🔴 **КОНФЛИКТ, ВЫНЕСЕН НА ALEX:** его решение 2026-09-26 «Music не трогать» против -> задачи 2026-09-27 «добавляй библиотеку». Задан вопрос, **ответа нет, изменений не внесено**. -> **Актуальный план — [[family/plans/music-jellyfin-lidarr-taiga]]** (этот документ — история Фазы 0). - -Что изменилось против Фазы 3 ниже: - -| Было (2026-09-26) | Стало (2026-09-27) | +| Факт | Значение | |---|---| -| Фаза 3 «НЕ ТРОГАТЬ» | Фаза 3 = основная задача сессии | -| Блокер: 2759 mojibake / 662 lost | Блокер снят: теги чистые (108/108) | -| Бэкап-папка одна — `Music/backup/` | Бэкап-папок **4** (7316 файлов, 48 ГБ) | -| Исключать бэкап не нужно (снести до создания) | Исключать все 4 через пустой `.ignore` | -| Библиотеку не создавать | Создать `collectionType=music` | +| **Музыкальный сервер — NAVIDROME, не Jellyfin** | `https://music.mallexxx.duckdns.org`, v0.64.2, скан 7861 живой трек | +| Navidrome читает **только теги**, папки игнорирует | структура `category/sub/file` ему не мешает | +| Jellyfin для музыки **провален** | баг [#18162](https://github.com/jellyfin/jellyfin/issues/18162) — имя папки перекрывает тег | +| Структура `Music/` на диске | **плоская**, НЕ `Artist/Album/Track` (подтверждено: `!Rock&Folk/Green Apelsin`, `!Рэп/Guf` и т.п.) | +| Lidarr пишет теги при импорте | MusicBrainz release groups, включая `Album Artist` → новые закачки приходят с полным набором | +| Prowlarr appProfile | `Standard` = **id 1** | +| Prowlarr applications | Radarr, Sonarr — оба `fullSync`; **Lidarr отсутствует** | +| Индексеры | все 6 тегированы `[1]` (прокси `vless-socks5`); **живых 3/6** | +| RuTracker caps | отдаёт ветку **3000 Audio** ✅ | +| NoNaMe caps | отдаёт ветку **3000 Audio** ✅ | +| RuTor caps | в ответе не было 3000 — **проверить `?t=caps` при настройке** | +| Transmission | `download-dir=/mnt/storage/Downloads` (**плоский**, без подкаталога категории), `media_net` 172.16.17.5 | +| Диск | 913 ГБ свободно из 929 | +| Стек | prowlarr/radarr/sonarr/jellyfin/transmission Up, uid 950; navidrome Up, `caddy_default` | +| Lidarr | **не установлен**: ни контейнера, ни Caddy-блока, ни Application в Prowlarr | -**Стек без изменений:** lidarr **не установлен**, в Prowlarr его нет, Caddy-блока `lidarr` нет. -Индексеры: 3/6 живые (RuTor/Byrutor/NoNaMe ✅; RuTracker/Kinozal — Cloudflare). -Обход `docker run`-блокировки: `ffprobe` есть внутри контейнера `jellyfin` (`/usr/lib/jellyfin-ffmpeg/ffprobe`). +## Архитектура после деплоя ---- +``` +Prowlarr (9696) ──fullSync──> Lidarr (8686) + Radarr + Sonarr + │ +Transmission (9091) ──download──┐ │ + /mnt/storage/Downloads ↓ ↓ + /storage/Music ← root folder Lidarr + │ + Navidrome (4533) ──> music.mallexxx.duckdns.org + │ + caddy: lidarr.mallexxx.duckdns.org +``` -## Решения Alex (2026-09-26) — ⚠️ пункт 3 УСТАРЕЛ +## План (утверждён) -| # | Вопрос | Решение | +### Фаза 1 — контейнер + +1. **Бэкап** `/mnt/RED_2TB/docker/arr/docker-compose.yml` → `~truenas_admin/` + (⚠️ `/mnt/RED_2TB/backup` root-owned — туда писать нельзя). +2. Добавить сервис `lidarr` в compose (паттерн radarr, **один проект = нет name-conflict**): + образ `lscr.io/linuxserver/lidarr:latest`, `PUID=950 PGID=950 TZ=Asia/Novosibirsk`, + `dns: [8.8.8.8, 8.8.4.4]`, порт `8686:8686`, + volumes `/mnt/RED_2TB/docker/arr/lidarr:/config` + `/mnt/RED_2TB/storage:/storage`, + networks `media_net` + `caddy_default`. +3. Старт: `cd /mnt/RED_2TB/docker/arr && docker compose up -d lidarr` + (⚠️ **НЕ** через временную копию compose в /tmp — name-conflict, чинили долго). +4. Caddy: блок `lidarr.mallexxx.duckdns.org { reverse_proxy lidarr:8686 }`. + Caddyfile root-owned → **только через alpine** (`-v /:/host:rw`), отправлять **весь файл**, + потом `caddy validate` → `caddy reload`. TLS ~10 сек, `exit=35` сразу после reload — норма. + +### Фаза 2 — онбординг Lidarr (через API) + +1. API-ключ: `docker exec lidarr grep ApiKey /config/config.xml`. +2. **Root folder: `/storage/Music`** (решение Alex 2026-09-26). +3. **Download client:** Transmission, host `transmission`, port `9091`, + urlBase `/transmission/`, category `lidarr`, без логина/пароля. +4. **Вариант A (решение Alex):** + - Media Management → `Rename Tracks = ON`, `Rename Folders = ON` + - стандартная маска Lidarr: `Music/<Artist Folder>/<Album Folder>/<track> - <title>` + - `Write Metadata Tags = ON` — обязательно, иначе новые закачки без `Album Artist` + развалятся на альбомы-одиночки в Navidrome + - `Import Extra Files = OFF` +5. **Импорт существующих 7861 файлов — НЕ делать** (решение Alex). + Lidarr отвечает только за новые закачки. Существующая библиотека остаётся как есть. + ⚠️ Поэтому **не** запускать Library Import и не нажимать «Update All» по существующим артистам — + это перезапишет теги, выправленные за 50 сессий (см. [[personal/plans/music-artist-albumartist-repair]]). + +### Фаза 3 — связка с arr-стеком + +1. **Prowlarr:** добавить Application `Lidarr` (`implementation: Lidarr`, + `syncLevel: fullSync`, `baseUrl: http://lidarr:8686`, apiKey из Фазы 2, + `appProfileId: 1`, `syncCategories: [3000,3010,3020,3030,3040,3050,3060]`). + Прокси-тег `[1]` наследуется автоматически — все 6 индексеров уже тегированы. +2. **Проверить фактом, а не предположением:** отдают ли RuTor/Byrutor/NoNaMe + audio-категории 3000-й серии (`?t=caps`). RuTracker и NoNaMe — отдают (проверено 2026-09-28). +3. Remote Path Mapping для Lidarr — тот же паттерн, что у Radarr/Sonarr: + host `transmission`, remotePath `/mnt/storage/Downloads/`, localPath `/storage/Downloads/` + (сносит существующую health-ошибку `RemotePathMappingCheck`). + ⚠️ Transmission кладёт **плоско** в `/mnt/storage/Downloads`, подкаталога категории нет — + маппинг сам по себе может не закрыть ошибку. Разбирать по факту. + +### Фаза 4 — приёмка (Alex, в UI) + +1. `https://lidarr.mallexxx.duckdns.org` открывается. +2. Тестовый поиск артиста → релиз найден → торрент появился в Transmission. +3. Файл доехал в `/storage/Music`, виден в Navidrome. +4. `docker ps` — 6 сервисов arr-стека + lidarr Up, uid 950. + +## Риски / открытые вопросы + +| # | Риск | Что делать | |---|---|---| -| 1 | Куда Lidarr складывает музыку | **`/storage/Music`** — существующая папка как root folder | -| 2 | Как обходить блокировку индексеров | **Через прокси** (`vless-proxy`) | -| 3 | ~~Jellyfin Music-библиотека~~ | ~~**НЕ ТРОГАТЬ**~~ → **УСТАРЕЛО 2026-09-27** (теги починены, задача переставлена) | - -## 🔴 Результат разведки (факты с живой машины, 2026-09-26) - -### Что работает - -| Компонент | Состояние | -|---|---| -| prowlarr, radarr, sonarr, jellyfin, transmission | ✅ Up, все под uid 950, PUID/PGID=950 | -| `media_net` (external) | ✅ существует; в ней prowlarr, radarr, sonarr, transmission | -| `caddy_default` | ✅ prowlarr, radarr, sonarr, jellyfin | -| Caddy subdomains | ✅ radarr/sonarr/prowlarr/jellyfin.mallexxx.duckdns.org | -| Radarr root folder | `/storage/radarr` — accessible ✅ | -| Sonarr root folder | `/storage/sonarr` — accessible ✅ | -| Radarr/Sonarr download client | Transmission (id=1, enable=true) ✅ | -| Prowlarr → Radarr/Sonarr apps | оба `syncLevel=fullSync` ✅ | -| Radarr/Sonarr indexers | 5 шт. у Radarr, baseUrl `http://prowlarr:9696/<id>/` ✅ формат верный | -| Диск | 960 ГБ свободно из 976 (2% used) | -| Music | 7890 аудиофайлов, `Music/backup` НЕ существует | - -### 🔴 Что НЕ работает — корень проблемы - -**Все 6 индексеров Prowlarr отключены: `disabledTill` = 2026-09-27T08:07:26Z** (более 6 часов недоступны). - -**Корневая причина — DNS-блокировка у интернет-провайдера TrueNAS (Ростелеком):** - -``` -nslookup rutracker.org 8.8.8.8 → NXDOMAIN -nslookup rutracker.org 192.168.2.2 → NXDOMAIN (роутер, = провайдерский DNS) -nslookup rutor.info 8.8.8.8 → NXDOMAIN -nslookup kinozal.tv 8.8.8.8 → NXDOMAIN -nslookup nnmclub.to 8.8.8.8 → NXDOMAIN -nslookup byrutgame.org 192.168.2.2 → 185.200.198.230 ✅ (единственный рабочий) -nslookup google.com 192.168.2.2 → ✅ -``` - -**Это НЕ поломка роутера и НЕ поломка стека.** Блокировка на стороне провайдера: провайдерский DNS -отдаёт NXDOMAIN даже для внешнего резолвера, потому что сам DNS-трафик проходит через провайдера. - -**Следствие:** `dns: [8.8.8.8, 8.8.4.4]` в compose **НЕ помогает** — проверено, NXDOMAIN с 8.8.8.8 тоже. -Единственный рабочий путь — прокси, где DNS резолвится на выходной стороне. - -### ⚠️ `vless-proxy` не виден из media_net - -``` -vless-proxy networks: hermes_taiga_net (172.16.15.2) -docker exec prowlarr getent hosts vless-proxy → FAIL -docker exec prowlarr getent hosts xray-admin → 172.16.1.9 ✅ -``` - -Понадобится подключить `vless-proxy` к `media_net` (runtime + персистентно в его compose). - -### ⚠️ Прочие находки (не блокеры) - -- **Radarr/Sonarr health error RemotePathMappingCheck:** Transmission кладёт в `/storage/Downloads/radarr` - и `/storage/Downloads/sonarr`, а внутри контейнеров этих подпапок нет. Проверить remote path mapping. -- **Transmission:** download-dir `/mnt/storage/Downloads`, incomplete `/mnt/storage/Downloads/transmission/incomplete`, - `rpc-whitelist 172.16.*.*`, `script-torrent-done = false` (хука автопостинга нет). -- **Radarr `indexerstatus` вернул 404** — эндпоинт в этой версии иначе; `disabledTill` в `/api/v3/indexer` пустой `{}`. - Реальный статус отключения виден только в Prowlarr `/api/v1/indexerstatus`. -- Лишние файлы в `/mnt/RED_2TB/storage/`: `cmp-remote.sh`, `cmp-remote-v2.sh`, `edu_acl_fix.py`, - `edu_chgrp_fix.py`, `acl-edu-before-20260922-234617.json`, `shares-before-20260914-070242.json` — мусор от прошлых сессий, не трогать без команды. - -## API-ключи (полные, сняты с живой машины) - -| Сервис | Ключ | -|---|---| -| Prowlarr | `35c8b3f497114076a6150ea0d9504845` | -| Radarr | `51e201f2d61b4fe2a0c322d5e99349fe` | -| Sonarr | `b1eb9cdd5c804e6c956dc9c8bd305dc8` | -| Jellyfin | `eaglesetup2026taiga` | - -### ✅ СДЕЛАНО в Фазе 0 (2026-09-26, end-of-session) - -| # | Действие | Факт | -|---|---|---| -| 1 | `vless-proxy` подключён к `media_net` | `172.16.17.6`; проверено `docker exec prowlarr getent hosts vless-proxy` → резолвится | -| 2 | Персистентность в compose | `/mnt/RED_2TB/docker/vless-proxy/docker-compose.yml` — добавлена `media_net` в `networks:` + `external: true`. Бэкап: `~/vless-proxy-compose.bak-20260926-012529` и `.bak-<ts>` рядом с файлом. Контейнер пересоздан `docker compose up -d --force-recreate`. MD5 файла: `4449e2b55a75362904438d4792abed90` | -| 3 | Тег `proxy` создан в Prowlarr | `POST /api/v1/tag {"label":"proxy"}` → `id=1`. До этого таблица `Tags` была **ПУСТА**, а `Indexers.Tags` у RuTracker ссылался на висячий id `[1]` — прокси физически не был привязан | -| 4 | Прокси `vless-socks5` (id=1) привязан к тегу | `PUT /api/v1/indexerproxy/1` c `"tags":[1]`. Socks5, host `vless-proxy`, port `1080` | -| 5 | **Все 6 индексеров** тегированы `[1]` | Подтверждено из БД `prowlarr.db`: `SELECT Id, Name, Tags FROM Indexers` → все `[1]` | -| 6 | `testall` прогнан | **3 из 6 зелёные** (было 0 из 6). NXDOMAIN ушёл ПОЛНОСТЬЮ | - -**Результат `POST /api/v1/indexer/testall` (фактические данные):** - -| id | Индексер | Результат | Сообщение | -|---|---|---|---| -| 1 | RuTracker | ❌ | `[403:Forbidden] [POST] at https://rutracker.org/forum/login.php` | -| 2 | RuTor | ✅ | OK | -| 3 | Byrutor | ✅ | OK | -| 4 | NoNaMe Club | ✅ | OK | -| 5 | Kinozal | ❌ | `Unable to access kinozal.me, blocked by CloudFlare Protection` | -| 6 | Kinozal (M) | ❌ | `Unable to access kinozal.me, blocked by CloudFlare Protection` | - -### 🔬 Точный диагноз по RuTracker (проверено curl'ом через прокси, из контейнера prowlarr) - -``` -GET https://rutracker.org/forum/index.php → HTTP 200 ✅ (сайт доступен через прокси!) -POST https://rutracker.org/forum/login.php → HTTP 403 ❌ "Just a moment..." - (Cloudflare JS-challenge) -``` - -Тело ответа содержит `challenge` ×8, `cloudflare` ×5 — это **страница Cloudflare-челленджа**, а не отказ -сайта. **Логин/пароль проверить невозможно** — челлендж режет запрос до отправки формы. - -**Вывод:** прокси полностью решил DNS-блокировку. Остаточная проблема — **другого класса**: -Cloudflare-защита, для которой нужен headless-браузер. Прокси тут бессилен. - -### 🔴 FlareSolverr НЕ УСТАНОВЛЕН (блокер для оставшихся 3 индексеров) - -``` -docker ps -a | grep -i flare → NOT FOUND -docker images | grep -i flare → NO IMAGE -docker exec prowlarr printenv | grep -i flare → NOT SET -docker exec prowlarr cat /config/config.xml | grep -i flare → NOT IN CONFIG -``` - -**Варианты, предложенные Alex (ждём решения):** - -| # | Вариант | Оценка | -|---|---|---| -| 1 | **Задеплоить FlareSolverr** — `ghcr.io/flaresolverr/flaresolverr:latest` в `media_net`+`caddy_default`, затем `PROWLARR__FLARESOLVERR_URL=http://flaresolverr:8191` в compose Prowlarr | ~10 мин; закроет RuTracker + Kinozal | -| 2 | Пропустить RuTracker/Kinozal — 3 рабочих индексера (RuTor, Byrutor, NoNaMe) уже дают музыку, идти к Lidarr сразу | 0 мин, но теряем Kinozal (помечен как MUSIC-трекер) | -| 3 | Только Kinozal — у него нет логина-формы, FlareSolverr может хватить для одного | компромисс | - -**Рекомендация агента — вариант 1:** Kinozal в описании значится как `MOVIES / TV / MUSIC`, -то есть именно музыкальный трекер; без него смысл задачи (Lidarr на музыку) падает. - -### Что уже сделано в коде/конфиге (для воспроизведения) - -```bash -# 1. Подключение vless-proxy к media_net (persistent, через alpine — каталог root-owned 0:0 755) -cat /tmp/vless-proxy-compose.yml | ssh truenas_admin@mallexxx.duckdns.org \ - "docker run --rm -i -v /:/host:rw alpine:latest sh -c \ - 'cp .../docker-compose.yml .../docker-compose.yml.bak-\$(date +%Y%m%d-%H%M%S) && \ - cat > .../docker-compose.yml && md5sum .../docker-compose.yml'" -ssh truenas_admin@mallexxx.duckdns.org "cd /mnt/RED_2TB/docker/vless-proxy && docker compose up -d --force-recreate" - -# 2. Создание тега proxy -curl -s -X POST -H "X-Api-Key: $PW_KEY" -H "Content-Type: application/json" \ - -d '{"label":"proxy"}' http://localhost:9696/api/v1/tag # → {"label":"proxy","id":1} - -# 3. Привязка прокси к тегу proxy -curl -s -X PUT -H "X-Api-Key: $PW_KEY" -H "Content-Type: application/json" \ - -d '{"id":1,"name":"vless-socks5","implementation":"Socks5","configContract":"Socks5Settings", - "tags":[1],"fields":[{"name":"host","value":"vless-proxy"},{"name":"port","value":1080}, - {"name":"username","value":""},{"name":"password","value":""}]}' \ - http://localhost:9696/api/v1/indexerproxy/1 - -# 4. Тегирование индексеров (Kinozal требует forceSave=true — иначе 400 на Cloudflare-проверке) -# RuTracker уже имел tags=[1]; RuTor/Byrutor/NoNaMe — обычный PUT 202 -# Kinozal (5) и Kinozal (M) (6): PUT /api/v1/indexer/<id>?forceSave=true → 202 -# ⚠️ ПОСЛЕ PUT обязателен docker restart prowlarr — иначе API отдаёт 202, но БД хранит [] - -# 5. Проверка -curl -s -X POST -H "X-Api-Key: $PW_KEY" -H "Content-Type: application/json" -d '{}' \ - --max-time 240 http://localhost:9696/api/v1/indexer/testall -``` - -### 🔴 Пойманные питфоллы Фазы 0 (дорогие, записать обязательно) - -1. **`Indexers.Tags` ссылался на несуществующий тег.** В `prowlarr.db` таблица `Tags` была **пустой**, - а у RuTracker стоял `Tags=[1]`. Прокси существовал (`IndexerProxies` id=1 `vless-socks5`), но - `IndexerProxies.Tags=[]` — привязки не было. Симптом: `Test All` даёт NXDOMAIN, хотя прокси настроен. - **Диагностика: скопировать `prowlarr.db` на Mac (`sqlite3` на хосте TrueNAS НЕТ) и посмотреть - `SELECT Id,Name,Tags FROM Indexers; SELECT Id,Name,Tags FROM IndexerProxies; SELECT * FROM Tags;`** - -2. **`docker exec prowlarr wget` — BusyBox, НЕ умеет PUT и `-e`.** Ошибки - `unrecognized option: method=PUT` и `unrecognized option: e`. **Но в контейнере prowlarr есть - `/usr/bin/curl`** — использовать `curl`, не `wget`. (Linuxserver-образы содержат curl.) - -3. **Kinozal PUT → HTTP 400 `CloudFlare Protection`.** Prowlarr при PUT валидирует доступ к сайту. - Обход: добавить `?forceSave=true` в query string → HTTP 202. - -4. **PUT вернул 202, но БД осталась `Tags=[]`.** Prowlarr держит кеш. **`docker restart prowlarr` - обязателен** — после рестарта все 6 тегов на месте. - -5. **`aws`-подобная правка JSON через `awk`/`sed` ломается, если `tags` — ПОСЛЕДНЕЕ поле объекта.** - Строка `"tags": []` в конце (перед `}`) — awk, режущий блок, съедал закрывающую `}` → - `HTTP 400 Expected start of a property name... LineNumber: 583`. - **Надёжный приём:** `awk '/"tags":/ { exit } { print }' file > body.json` — обрезать ВСЁ от `tags` - до конца, затем дописать хвост вручную: `printf ' "tags": [1],\n "id": %s\n}\n' "$ID" >> body.json`. - -6. **`jq` с `\\(...)` внутри inline SSH-строки через `terminal` ломается** (`unexpected INVALID_CHARACTER`). - **Писать jq-выражение в файл-скрипт** (`/tmp/parse.sh`) и запускать `bash /tmp/parse.sh` — тогда работает. - -7. **`execute_code` требует апрува Alex и был отклонён** (таймаут без ответа). Для разбора JSON — - файл-скрипт + `terminal`, не `execute_code`. Это подтверждает правило из профиля Alex. - -8. **`vless-proxy` содержит ДВА инбаунда:** SOCKS5 на `1080` и HTTP на `1081` (обе `0.0.0.0`). - Оба проверены, оба обходят блокировку. Prowlarr настроен на SOCKS5/1080. - -9. **Мёртвый домен `kinozal.tv` — использовать `kinozal.me`.** `kinozal.tv` не резолвится - даже на выходной стороне прокси (мёртв). `kinozal.me` через прокси → **HTTP 200**. - `kinozal.me/login.php` → 403 (нормальная защита страницы логина от curl, не блокировка). - -10. **`byrutgame.org` — единственный, работавший напрямую** (без прокси). Через прокси даёт 404 - на `/` (норм — у сайта нет корневой страницы). - -### Проверка обхода блокировки — сырые данные (воспроизводимо) - -``` -# БЕЗ прокси (из контейнера radarr) -rutracker.org → NXDOMAIN rutor.info → NXDOMAIN -kinozal.tv → NXDOMAIN nnmclub.to → NXDOMAIN - -# ЧЕРЕЗ прокси (HTTP 1081 и SOCKS5 1080 — одинаково) -https://rutracker.org/forum/index.php → 200 -https://rutor.info/ → 200 -https://nnmclub.to/ → 200 -https://kinozal.me/ → 200 -https://kinozal.tv/ → 000 -``` - -## План - -### Фаза 0 — обход DNS-блокировки через прокси — 🟡 ЧАСТИЧНО ВЫПОЛНЕНА - -✅ **шаги 1–4 сделаны** (см. «СДЕЛАНО» выше). Осталось: **решение Alex по FlareSolverr** и -шаг 5 (приёмка Alex в UI). - -Текст шагов (для истории): - -1. ✅ **Подключить `vless-proxy` к `media_net`** — СДЕЛАНО (runtime + персистентно в compose). -2. ✅ **Проверить прокси из контейнера arr-стека** — СДЕЛАНО: 3/4 сайта дают 200 через прокси. -3. ✅ **Прописать прокси в Prowlarr** — СДЕЛАНО: тег `proxy` создан, прокси привязан, все 6 тегированы. -4. ✅ **Сбросить `indexerstatus`** — СДЕЛАНО через `testall` (`DELETE /indexerstatus` → 405, метод не поддерживается). -5. ⏳ **ПРИЁМКА ALEX:** `https://prowlarr.mallexxx.duckdns.org` → Indexers → Test All → 3 зелёных минимум. -6. ⏳ **РЕШЕНИЕ ALEX по FlareSolverr** — блокирует RuTracker + Kinozal (MUSIC-трекер). - -### Фаза 1 — деплой Lidarr - -1. **Бэкап** `/mnt/RED_2TB/docker/arr/docker-compose.yml` в `~truenas_admin/`. -2. **Добавить сервис `lidarr`** в compose по образцу radarr: - - образ `lscr.io/linuxserver/lidarr:latest` - - PUID=950, PGID=950, TZ=Asia/Novosibirsk, dns 8.8.8.8/8.8.4.4 - - порты `8686:8686` - - volumes: `/mnt/RED_2TB/docker/arr/lidarr:/config`, `/mnt/RED_2TB/storage:/storage` - - networks: `media_net`, `caddy_default` -3. **Поднять** из правильной папки: `cd /mnt/RED_2TB/docker/arr && docker compose up -d lidarr`. -4. **Caddy:** блок `lidarr.mallexxx.duckdns.org { reverse_proxy lidarr:8686 }` - (правка Caddyfile — только через alpine-контейнер, файл root-owned). -5. **ПРИЁМКА ALEX:** `https://lidarr.mallexxx.duckdns.org` открывается. - -### Фаза 2 — Lidarr на музыку - -1. **Root folder `/storage/Music`** (решение Alex). -2. **Download client** — Transmission: host `transmission`, port 9091, urlBase `/transmission/`, - category `lidarr`, без логина/пароля. -3. **Application в Prowlarr** — добавить Lidarr (implementation `Lidarr`), syncCategories 3000-й серии: - `[3000,3010,3020,3030,3040,3050,3060]`. -4. **Прокси-тег** для заблокированных индексеров (наследуется из фазы 0). -5. **Качество/маска переименования** — решить при настройке (Lidarr переименовывает файлы по маске). -6. **ПРИЁМКА ALEX:** тестовый поиск → торрент появился в Transmission. - -### Фаза 3 — синк с Jellyfin — ✅ РАЗБЛОКИРОВАНА 2026-09-27 - -> 🔴 **БЫЛО (2026-09-26): НЕ ТРОГАТЬ** — блокировано до ремонта тегов (2759 mojibake / 662 lost). -> ✅ **СТАЛО (2026-09-27):** теги починены (108/108 подтверждено), Фаза 3 = **основная задача**. -> Полные шаги (создание библиотеки + исключение 4 бэкап-папок через `.ignore`) — -> [[family/plans/music-jellyfin-lidarr-taiga]] §Фаза 1. - -Что нужно знать (проверено): - -- `/storage/Music` **уже смонтирован** в Jellyfin (ro) — доп. монтирование не требуется. -- Создание: `POST /Library/VirtualFolders?name=Music&collectionType=music&paths=/storage/Music` - (**query string**, не body). -- Бэкап-папок **4** (не одна): `backup` 7041, `backup_conv40` 40, `backup_fix` 165, `backup_raw` 70. - Исключать через **пустой `.ignore`** в каждой — механизм подтверждён официальной докой Jellyfin - (https://jellyfin.org/docs/general/server/media/excluding-directory/), работает в 10.11.x. - Создавать **ДО** первого скана. -- Объём к индексации: **7861** файл, ожидание 20–60 мин на Pentium G2020. -- Остаточные дефекты — 29 файлов (16 битых + 13 DRM) — [[personal/tech/music-broken-toload]]. Не блокер. - -### Фаза 4 — приёмка живости стека - -1. `docker ps` — 6 сервисов arr-стека Up. -2. Radarr/Sonarr/Prowlarr health — без ошибок (сейчас есть IndexerLongTermStatusCheck и RemotePathMappingCheck). -3. Разобрать RemotePathMappingCheck. -4. **ПРИЁМКА ALEX:** панели по HTTPS, плейбек в Jellyfin, поиск в Radarr/Sonarr. - -## Питфоллы (Taiga-специфика, проверено) - -- **`dns: [8.8.8.8]` в compose НЕ обходит блокировку** — проверено, NXDOMAIN с 8.8.8.8 тоже. - Провайдерский DNS отдаёт NXDOMAIN и для внешнего резолвера, т.к. DNS-трафик идёт через провайдера. -- **На хосте TrueNAS нет `curl` и `python3`** в PATH (zsh). `wget` есть внутри контейнеров. - BusyBox `wget` **не поддерживает `-e`** и **`--method=PUT`**. - **В контейнерах linuxserver есть `/usr/bin/curl`** — использовать его для API-вызовов. -- **`sqlite3` на хосте НЕ установлен** (вопреки старой доке). Копировать `.db` на Mac через - `ssh ... "cat /path/db" > /tmp/db` и читать локальным `sqlite3`. -- **Caddyfile root-owned** — правка только через `docker run --rm -v /:/host alpine` (см. skill `truenas-caddy-service-deploy`). - Тот же приём работает для любого root-owned каталога (подтверждено на `/mnt/RED_2TB/docker/vless-proxy/` — `0:0 755`; - `cd` туда работает, запись — нет). -- **`docker network connect` теряется при пересоздании** — прописывать сети в compose. -- **Prowlarr API PUT возвращает 202, но кеш не сброшен** — `docker restart prowlarr` обязателен, - иначе `GET` покажет старое значение и БД останется прежней. -- **Prowlarr `?forceSave=true`** — обход валидации доступа к сайту при PUT индексеров - (`400 CloudFlare Protection` → `202`). -- **`DELETE /api/v1/indexerstatus` → HTTP 405.** Сброс статуса делать через `POST /api/v1/indexer/testall` - (он сбрасывает `disabledTill` сам). -- **`jq` с интерполяцией `\(...)` в inline SSH-строке ломается** — писать в файл-скрипт. -- **JSON-правка `awk`/`sed` ломается при `tags` последним полем** — обрезать `awk '/"tags":/ { exit }'` - и дописывать хвост через `printf`. -- `ls -la` на TrueNAS показывает `d---------` — норма для NFSv4 ACL; реальные права через `midclt call filesystem.getacl`. -- Папки медиа: uid 950 `drwxrwx---`, root `/mnt/RED_2TB/storage` — `drwxr-x--x` (traverse работает). - -## Связанные заметки - -- [[family/projects/media-toolbox-taiga]] — *arr стек -- [[family/how-to/jellyfin-config]] — Jellyfin Taiga + план Music-библиотеки -- [[personal/tech/music-tags-repair-truenas]] — ремонт тегов (7890 файлов) -- [[personal/tech/truenas-nfs4-acl-and-arrmultiuser]] — NFS4 ACL и PUID -- [[family/how-to/arr-stack-taiga]] — предыдущий опыт деплоя +| 1 | RuTor может не отдавать audio-категории | проверить `?t=caps`; живых аудио-индексеров 2-3, не 0 | +| 2 | Живых индексеров 3/6 — RuTracker и Kinozal за Cloudflare | FlareSolverr не установлен; Kinozal помечен как MUSIC-трекер, может понадобиться | +| 3 | RemotePathMapping: Transmission качает **плоско** | подкаталога категории нет → маппинг может не сработать; разбирать по факту | +| 4 | Rename Folders=ON меняет структуру папок для НОВЫХ закачек | существующие 7861 не трогаются (Lidarr трогает только свои импорты) | +| 5 | Случайный импорт старой библиотеки перезапишет теги | не запускать Library Import, не «Update All» | + +## Ссылки + +- [[family/projects/media-toolbox-taiga]] — *arr стек на Taiga +- [[family/how-to/navidrome-truenas-android]] — Navidrome (музыкальный сервер) +- [[personal/plans/music-artist-albumartist-repair]] — ремонт тегов (находка: `album` = имя папки-владельца) +- [[personal/tech/truenas-nfs4-acl-and-arrmultiuser]] — NFSv4 ACL и uid 950 + +## История + +- **2026-09-26** — разведка, Фаза 0 (прокси для индексеров) выполнена: `vless-proxy` в `media_net`, + тег `proxy` создан, 3/6 индексеров подняты. Lidarr не установлен. +- **2026-09-27** — Jellyfin Music-библиотека провалена (баг #18162) → полный откат; + музыка ушла в **Navidrome**. Lidarr отложен. +- **2026-09-28** — Alex: «Ставь lidarr на truenas с привязкой к arr стеку и navidrome». + Факты собраны, план составлен, решения приняты (**1 A**, **2 не импортировать**), деплой начат. diff --git a/family/projects/media-toolbox-taiga.md b/family/projects/media-toolbox-taiga.md index f8bfef7d..2fd8ad70 100755 --- a/family/projects/media-toolbox-taiga.md +++ b/family/projects/media-toolbox-taiga.md @@ -18,6 +18,19 @@ status: deployed --- # *arr Stack на Тайге — Setup & Config +> 🆕 **STATE 2026-09-28: ПЛАН ДЕПЛОЯ LIDARR СОСТАВЛЕН, ЖДЁТ «go» ALEX. НИЧЕГО НЕ ИЗМЕНЕНО.** +> Команда Alex: «Ставь lidarr на truenas с привязкой к arr стеку и navidrome». +> **Связка — с NAVIDROME, не с Jellyfin** (Jellyfin для музыки закрыт, баг #18162). +> Root folder — `/storage/Music` (та же папка, что читает Navidrome). +> Compose: сервис `lidarr` (`lscr.io/linuxserver/lidarr:latest`, порт 8686, PUID/PGID 950, +> `media_net` + `caddy_default`, `:rw` на `/mnt/RED_2TB/storage:/storage`). +> Caddy-блок `lidarr.mallexxx.duckdns.org` → `reverse_proxy lidarr:8686`. +> Prowlarr: Application `Lidarr`, `syncLevel=fullSync`, `baseUrl=http://lidarr:8686`, +> `appProfileId=1` (`Standard`), `syncCategories=[3000,3010,3020,3030,3040,3050,3060]`. +> **Полный план, оба открытых вопроса и риски — [[family/plans/lidarr-taiga-deploy]] §2026-09-28.** +> 🔴 **Индексеры для музыки (проверено 2026-09-28):** RuTracker отдаёт `3000 Audio` ✅, +> NoNaMe — `3000 Audio` ✅, RuTor — не подтверждён. Живых индексеров 3/6. + > ✅ **STATE 2026-09-27 (v6, ночь): NAVIDROME РАЗВЁРНУТ — музыкальный сервер для `Music/`.** > Контейнер **`navidrome`** (v0.64.2) на порту **4533**, домен **`https://music.mallexxx.duckdns.org`** > (Caddy, Let's Encrypt). Compose — `/mnt/RED_2TB/docker/navidrome/docker-compose.yml`. @@ -49,7 +62,8 @@ status: deployed Prowlarr (9696) → Radarr (7878) + Sonarr (8989) → Transmission (9091) → Jellyfin (8096) Navidrome (4533) ← `/storage/Music` — ✅ развёрнут 2026-09-27, читает ТЕГИ (не папки) -⏳ Lidarr (8686) — не установлен, план Фаза 2. +⏳ Lidarr (8686) — план составлен 2026-09-28, ждёт «go». Связка с NAVIDROME. + → [[family/plans/lidarr-taiga-deploy]] §2026-09-28 Staging папки (`radarr/`, `sonarr/`) невидимы в Jellyfin. Router скрипт создаёт симлинки из staging → категоризированные библиотеки по NFO (genre + mpaa). @@ -76,7 +90,7 @@ Transmission → /mnt/storage/Downloads | **Navidrome** | **https://music.mallexxx.duckdns.org** — ✅ **развёрнут 2026-09-27** (музыка) | | Transmission | https://transmission.mallexxx.duckdns.org (уже был) | -| Lidarr | https://lidarr.mallexxx.duckdns.org — ⏳ **НЕ установлен** (план, Фаза 1) | +| Lidarr | https://lidarr.mallexxx.duckdns.org — ⏳ **НЕ установлен**; план составлен 2026-09-28, ждёт «go» ([[family/plans/lidarr-taiga-deploy]] §2026-09-28) | Caddy: subdomain-based роутинг, без URL Base. Let's Encrypt автоматически. diff --git a/personal/tech/skill-arr-media-stack-setup-additions.md b/personal/tech/skill-arr-media-stack-setup-additions.md index 701d46bc..ce8c3bac 100755 --- a/personal/tech/skill-arr-media-stack-setup-additions.md +++ b/personal/tech/skill-arr-media-stack-setup-additions.md @@ -1,7 +1,7 @@ --- title: Skill — arr-media-stack-setup (дополнения 2026-09-26) created: '2026-09-26' -updated: '2026-09-26' +updated: '2026-09-28' type: tech namespace: personal tags: @@ -12,15 +12,55 @@ tags: - truenas - blocked - pitfalls + - lidarr + - navidrome related: - '[[personal/plans/lidarr-taiga-and-indexer-unblock]]' + - '[[family/plans/lidarr-taiga-deploy]]' - '[[family/projects/media-toolbox-taiga]]' + - '[[family/how-to/navidrome-truenas-android]]' --- # Skill `arr-media-stack-setup` — дополнения 2026-09-26 > Зеркало патча скилла. Что добавлено после разведки на Тайге (задача «Lidarr + музыка + синк с Jellyfin»). > Полный скилл: `~/.hermes/hermes-whale/skills/devops/arr-media-stack-setup/SKILL.md` +## 1a. Lidarr — музыкальный *arr (патч 2026-09-28) + +**Связка — с NAVIDROME, не с Jellyfin.** Jellyfin для музыки непригоден (баг #18162, имя папки +перекрывает теги). План деплоя на Тайге — [[family/plans/lidarr-taiga-deploy]] §2026-09-28. + +**Сервис = копия radarr:** `lscr.io/linuxserver/lidarr:latest`, порт `8686`, `PUID=950 PGID=950`, +volumes `/mnt/RED_2TB/docker/arr/lidarr:/config` + `/mnt/RED_2TB/storage:/storage` (`:rw`), +сети `media_net` + `caddy_default`. Старт — из папки проекта `/mnt/RED_2TB/docker/arr`. +**Root folder — та же папка, что читает Navidrome** (`/storage/Music`). + +🔴 **`Write Metadata Tags` обязателен** — без него Lidarr не пишет `Album Artist`, и при +отсутствии `ALBUMARTIST` Navidrome подставляет track artist → сборники и фиты разваливаются +на альбомы-одиночки. + +🔴 **Существующую библиотеку в Lidarr НЕ импортировать** — импорт как «Existing Albums» заставит +Lidarr перезаписать теги из MusicBrainz, ручной ремонт тегов уйдёт. Lidarr отвечает только +за новые закачки. + +### Audio-категории — проверять `?t=caps`, не предполагать + +```bash +# внутри контейнера prowlarr (в linuxserver-образах есть /usr/bin/curl) +docker exec prowlarr curl -s -H 'X-Api-Key: <KEY>' \ + 'http://localhost:9696/api/v1/indexer/<ID>' > /tmp/idx.json +jq -r '.capabilities.categories[] | "\(.id) | \(.name)"' /tmp/idx.json | grep -E '^3|Audio' +``` + +**Факт Taiga 2026-09-28:** RuTracker → `3000 Audio` ✅, NoNaMe Club → `3000 Audio` ✅, +**RuTor → категории не отдал**. Живых индексеров 3/6 (RuTracker/Kinozal за Cloudflare). + +### Prowlarr → Lidarr + +`POST /api/v1/applications`: `implementation=Lidarr`, `configContract=LidarrSettings`, +`syncLevel=fullSync`, `baseUrl=http://lidarr:8686`, `appProfileId` из `GET /api/v1/appprofile` +(на Taiga — `1`, `Standard`), `syncCategories=[3000,3010,3020,3030,3040,3050,3060]`. + ## 1. Индексеры недоступны: DNS-фильтр провайдера (НЕ Cloudflare, НЕ Pi-hole) **Новый класс проблемы**, ранее не описанный в скилле. Задокументированы были только