Files
obsidian-vault/family/plans/lidarr-taiga-deploy.md
T

23 KiB
Executable File
Raw Blame History

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/<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 на музыку) падает.

Что уже сделано в коде/конфиге (для воспроизведения)

# 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

🔴 По решению 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 работает).

Связанные заметки