# Lidarr на Taiga — деплой + прокси для индексеров **Дата:** 2026-09-26 **Статус:** 🟡 Фаза 0 частично выполнена (3/6 индексеров зелёные), ждём решение Alex по FlareSolverr **Namespace:** family ## Задача Поставить Lidarr на TrueNAS/Taiga в дополнение к Prowlarr/Radarr/Sonarr/Transmission/Jellyfin, настроить на музыку, обеспечить синк с Jellyfin, провести проверку живости всего стека. ## Решения Alex (2026-09-26) | # | Вопрос | Решение | |---|---|---| | 1 | Куда Lidarr складывает музыку | **`/storage/Music`** — существующая папка как root folder | | 2 | Как обходить блокировку индексеров | **Через прокси** (`vless-proxy`) | | 3 | Jellyfin Music-библиотека | **НЕ ТРОГАТЬ** — отдельная задача, заблокирована до ремонта тегов | ## 🔴 Результат разведки (факты с живой машины, 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//` ✅ формат верный | | Диск | 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-` рядом с файлом. Контейнер пересоздан `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/?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 🔴 **По решению Alex (2026-09-26) НЕ ТРОГАТЬ.** Музыкальная библиотека Jellyfin остаётся как есть: её нет, и она не создаётся в рамках этой задачи. Причина — 7890 файлов с массово битыми тегами (см. `[[personal/tech/music-tags-repair-truenas]]`), ремонт на апруве Alex. Что нужно знать для будущей работы (не действие сейчас): - `/storage/Music` **уже смонтирован** в Jellyfin (ro) — доп. монтирование не требуется. - Создание библиотеки возможно одной командой, но **до ремонта тегов бессмысленно**. - Порядок из прошлого плана: ремонт тегов → валидация Alex → удаление `Music/backup/` → библиотека. ### Фаза 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]] — предыдущий опыт деплоя