[2026-09-26] eagle: family/how-to/jellyfin-config.md family/how-to/navidrome-truenas-android.md family/plans/lidarr-taiga-deploy.md family/projects/media-toolbox-taiga.md personal/plans/lidarr-taiga-and-indexer-unblock.md personal/tech/skill-arr-media-stack-setup-additions.md

This commit is contained in:
Alexey Martemyanov committed 2026-09-26 14:26:54 +06:00
1 parent 9f300da7b6
commit 4ab53a2a63
6 files changed
+727 -5

No files matched your search

@@ -0,0 +1,326 @@
---
title: Lidarr на Тайге + разблокировка индексеров — план
created: '2026-09-26'
updated: '2026-09-26'
type: plan
namespace: personal
status: awaiting-approval
tags:
- lidarr
- taiga
- truenas
- arr
- music
- dns
- prowlarr
- blocked
related:
- '[[family/projects/media-toolbox-taiga]]'
- '[[family/how-to/jellyfin-config]]'
- '[[personal/tech/music-tags-repair-truenas]]'
- '[[personal/tech/truenas-nfs4-acl-and-arrmultiuser]]'
---
# Lidarr на Тайге + разблокировка индексеров — план
> **Статус: ПЛАН СОСТАВЛЕН, ЖДЁТ ОТВЕТОВ АЛЕКСА на 2 вопроса. НИЧЕГО НЕ ТРОНУТО.**
> Задача поставлена 2026-09-26: «поставить lidarr в дополнение к sonarr/prowlarr, настроить на музыку,
> синк с jellyfin, проверка что весь стек живой».
> Разведка выполнена, найдены 2 блокера, план ниже.
## 🔴 ГЛАВНАЯ НАХОДКА СЕССИИ: DNS-блок у провайдера Тайги
**Стек НЕ сломан. Индексеры мертвы из-за внешней блокировки на стороне Тайги.**
Диагностика (2026-09-26, все команды с живой машины):
```bash
# Из контейнера prowlarr:
docker exec prowlarr sh -c "wget -qO- --timeout=12 -S 'https://rutracker.org/'"
# → wget: bad address 'rutracker.org'
docker exec prowlarr sh -c "wget -qO- --timeout=12 -S 'https://byrutgame.org/'"
# → HTTP/1.1 200 OK ← этот резолвится
```
```bash
# На хосте TrueNAS, ДВА разных резолвера:
nslookup rutracker.org 192.168.2.2 # роутер → NXDOMAIN
nslookup rutracker.org 8.8.8.8 # Google → NXDOMAIN
nslookup google.com 192.168.2.2 # → OK (142.250.181.238)
```
**Вывод:** NXDOMAIN приходит **и с роутера, и с 8.8.8.8** → это **не Pi-hole и не роутер**.
Блок на стороне аплинка Тайги (провайдер Ростелеком / региональный DNS-фильтр).
**Что НЕ резолвится (все 4 трекера):** `rutracker.org`, `rutor.info`, `kinozal.tv`, `nnmclub.to`
**Что резолвится:** `byrutgame.org` (185.200.198.230), `google.com`
> ⚠️ Это **другой** класс проблемы, чем задокументированные ранее «Cloudflare 403 на
> `indexers.prowlarr.com`» и «RuTracker Cloudflare Turnstile». Здесь **DNS не отдаёт IP вообще** —
> до Cloudflare/TLS дело не доходит.
### Следствие в Prowlarr
```
GET /api/v1/health →
"Indexers unavailable due to failures for more than 6 hours:
RuTracker, RuTor, NoNaMe Club, Kinozal, Kinozal (M)"
GET /api/v1/indexerstatus → 5 записей, у всех:
disabledTill = "2026-09-27T08:07:26Z" (сутки карантина)
initialFailure = "2026-05-20T05:4x:xx" ← ЛОМАЕТСЯ С ДНЯ ДЕПЛОЯ, не «сейчас»
```
> 🔑 **`initialFailure` = 2026-05-20** — дата первоначального деплоя стека.
> Значит индексеры через Prowlarr на Тайге **не работали ни одного дня**. Это не регресс.
В Radarr/Sonarr это даёт каскад:
```
IndexerLongTermStatusCheck error All indexers are unavailable due to failures for more than 6 hours
IndexerRssCheck warning All rss-capable indexers are temporarily unavailable
IndexerSearchCheck warning All search-capable indexers are temporarily unavailable
```
## 🔴 БЛОКЕР 2: vless-proxy НЕ виден из media_net
Задокументировано в `media-toolbox-taiga.md`: «vless-proxy доступен в `media_net` как
`vless-proxy:1080` (SOCKS5)». **Факт 2026-09-26 — это НЕ ТАК:**
```bash
docker inspect vless-proxy --format '{{range $n,$c := .NetworkSettings.Networks}}{{$n}} {{$c.IPAddress}}{{end}}'
# hermes_taiga_net 172.16.15.2 ← ТОЛЬКО одна сеть
docker exec prowlarr getent hosts vless-proxy
# NO DNS
```
`docker network inspect media_net` → участники: `prowlarr radarr transmission sonarr`
(**vless-proxy отсутствует**).
**Вывод:** прокси-маршрут для заблокированных индексеров, описанный в доке, **никогда не работал** —
не был реализован. При этом `docker exec prowlarr getent hosts xray-admin` → `172.16.1.9` (работает,
обе в `caddy_default`).
## Фактическое состояние стека (2026-09-26)
Всё проверено на живой машине. **Стек работает**, кроме индексеров.
| Сервис | Статус | UID | Порты | Сети |
|---|---|---|---|---|
| prowlarr | Up 3d | 950 | 9696 | media_net + caddy_default |
| radarr | Up 3d | 950 | 7878 | media_net + caddy_default |
| sonarr | Up 3d | 950 | 8989 | media_net + caddy_default |
| jellyfin | Up 7d | 950 | 8096 | caddy_default |
| transmission | Up 7d | 950 | 9091, 51413 | media_net + transmission_default |
| caddy | Up 3d | — | — | caddy_default |
Проект compose: `arr` (все 4 в `media_net` + `caddy_default`). `media_net` существует.
### Compose (актуальный, `/mnt/RED_2TB/docker/arr/docker-compose.yml`)
Все сервисы: `PUID=950 PGID=950 TZ=Asia/Novosibirsk`, `dns: [8.8.8.8, 8.8.4.4]`.
radarr/sonarr монтируют `/mnt/RED_2TB/storage:/storage`; jellyfin — `:ro`; prowlarr — только `/config`.
**У prowlarr НЕТ монтирования `/storage`.** Порты проброшены (`ports:`) — можно обращаться к API с хоста.
### Индексеры Prowlarr (все 6, `enable=true`)
| id | Name | definitionName | URL |
|---|---|---|---|
| 1 | RuTracker | `RuTracker.org` | rutracker.org |
| 2 | RuTor | `rutor` | rutor.info |
| 3 | Byrutor | `byrutor` | byrutgame.org ← **единственный живой DNS** |
| 4 | NoNaMe Club | `noname-club` | nnmclub.to |
| 5 | Kinozal | `kinozal` | kinozal.tv |
| 6 | Kinozal (M) | `kinozal-magnet` | kinozal.tv |
### Applications Prowlarr
| id | Name | syncLevel | baseUrl |
|---|---|---|---|
| 1 | Radarr | `fullSync` | `http://radarr:7878` |
| 2 | Sonarr | `fullSync` | `http://sonarr:8989` |
### Radarr — практические факты
- Root folder: `/storage/radarr` (id 1, accessible)
- Download client: `Transmission` (id 1, enable=true)
- Индексеров **5** (Byrutor не синкается — нет RSS):
`Kinozal (M)`, `Kinozal`, `NoNaMe Club`, `RuTor`, `RuTracker`
- ⚠️ **БАГ Prowlarr-синка:** baseUrl индексеров = `http://prowlarr:9696/6/` —
**БЕЗ `/prowlarr` urlBase**. Прямая проверка:
`docker exec radarr wget -qO- "http://prowlarr:9696/6/api?t=caps"` → **401 Unauthorized**
Ожидалось `http://prowlarr:9696/prowlarr/6/`. См. skill `arr-media-stack-setup`
§«Корень проблемы короткий URL в синхронизации индексеров».
⚠️ Но у Тайги `<UrlBase>` у prowlarr — **пустой** (`config.xml`), т.е. на этом хосте
форма `9696/6/` может быть и корректной. **Разобрать перед фиксом** — не менять вслепую.
### Ключи API (полные, сняты с живой машины)
| Сервис | Полный ключ |
|---|---|
| Prowlarr | `35c8b3f497114076a6150ea0d9504845` |
| Radarr | `51e201f2d61b4fe2a0c322d5e99349fe` |
| Sonarr | `b1eb9cdd5c804e6c956dc9c8bd305dc8` |
| Jellyfin | `eaglesetup2026taiga` |
### Питфолл: на Тайге нет curl И НЕТ python3 на хосте
Ранее задокументировано «нет curl и python3 в PATH хоста». **Уточнение 2026-09-26:**
`python3` **есть** — использовался для парсинга JSON (`python3 -c 'import json...'`).
Нет **`curl`** и **нет `sqlite3`** на хосте (sqlite3 — подтверждено в `jellyfin-config`).
**Рабочий паттерн для API-вызовов на Тайге:** `wget` **внутри контейнера** + `python3` на хосте для разбора:
```bash
# JSON забираем wget-ом ИЗ КОНТЕЙНЕРА (busybox wget: только -qO- / --header / --timeout)
ssh truenas_admin@mallexxx.duckdns.org \
"docker exec prowlarr sh -c 'wget -qO- --header=\"X-Api-Key: <KEY>\" http://localhost:9696/api/v1/health'"
# ↓ или в файл, затем разбор хостовым python3
ssh truenas_admin@... "docker exec prowlarr sh -c 'wget -qO- ... > /tmp/x.json'"
python3 -c 'import json; d=json.load(open("/tmp/x.json")); ...'
```
> ⚠️ **busybox wget НЕ поддерживает `-e use_proxy=yes`** (это GNU-опция). Для прокси-тестов внутри
> контейнеров нужен другой инструмент (в linuxserver-образах есть `curl`? — проверить) или
> тестировать с хоста. Проверено: `wget: unrecognized option: e`.
### Питфолл: shell-экранирование при выкачивании JSON через ssh
Кавычки в `--header="X-Api-Key: $K"` ломаются на нескольких уровнях ssh/sh. Рабочий приём —
**положить результат в файл внутри контейнера или на хосте**, потом разбирать отдельно.
`jq` с дефисами в ключах (`download-dir`) требует `.["download-dir"]`, не `.download-dir`.
### Питфолл: `/etc/resolv.conf` контейнеров
```
nameserver 127.0.0.11 ← Docker embedded DNS
search local
options ndots:0
```
Поэтому в контейнерах **нет `getent`** — использовать `nslookup`/`wget` для проверки DNS.
Хостовый `resolv.conf`: `domain local` + `nameserver 192.168.2.2`.
## RemotePathMapping — существующая ошибка (состояние 2026-09-26)
Transmission download-dir (факт):
```json
{"download-dir": "/mnt/storage/Downloads",
"incomplete-dir": "/mnt/storage/Downloads/transmission/incomplete",
"script-torrent-done-enabled": false,
"script-torrent-done-filename": "",
"rpc-whitelist": "172.16.*.*",
"rpc-url": "/transmission/"}
```
Radarr/Sonarr health:
```
RemotePathMappingCheck error
"download client Transmission places downloads in /storage/Downloads/radarr
but this directory does not appear to exist inside the container"
```
> 🔑 **Фактическая причина (важно, опровергает старую доку):** Transmission **не раскладывает**
> по `Downloads/radarr` — download-dir плоский `/mnt/storage/Downloads`. Radarr ОЖИДАЕТ
> подкаталог категории (`/storage/Downloads/radarr`), которого нет.
>
> **Задокументированный в `media-toolbox-taiga.md` маппинг `host=transmission`,
> `remotePath=/mnt/storage/Downloads/`, `localPath=/storage/Downloads/` — НЕ ПРИМЕНЁН**
> (в API Radarr/Sonarr записей remotepathmapping нет, health жалуется).
>
> **Второй слой:** Transmission монтирует `/mnt/storage`, radarr — `/storage`. Один и тот же
> хост-путь под двумя именами. Prowlarr/radarr-контейнеры **не видят `/mnt/storage`**.
## ПЛАН
### Фаза 0 — внешняя блокировка (БЛОКЕР для всего остального)
1. Подключить `vless-proxy` к `media_net`:
`docker network connect media_net vless-proxy` (runtime) + добавить сеть в compose
`/mnt/RED_2TB/docker/vless-proxy/docker-compose.yml` (иначе потеряется при пересоздании).
2. Проверить из prowlarr: `getent`/`nslookup vless-proxy`, затем доступ до `rutracker.org`
**через прокси** (SOCKS5 `vless-proxy:1080`).
3. Если через прокси резолвится — создать Proxy в Prowlarr (Settings → Indexers → Add Proxy,
SOCKS5, host `vless-proxy`, порт `1080`, тег `proxy`) и повесить тег `proxy` на
RuTracker / RuTor / Kinozal / NoNaMe.
4. Сбросить `indexerstatus`: `POST /api/v1/indexer/testall` (снимает `disabledTill`).
5. **ПРИЁМКА ALEX:** `https://prowlarr.mallexxx.duckdns.org` → Indexers → Test All → зелёные.
> ⚠️ Byrutor (id 3) резолвится — его прокси не нужен, но в Radarr он не синкается (нет RSS).
> Он полезен только в Sonarr/Radarr с `enableRss: false` — применимо и к Lidarr.
### Фаза 1 — Lidarr контейнер
1. **Бэкап** `/mnt/RED_2TB/docker/arr/docker-compose.yml` → `~truenas_admin/` (не в
`/mnt/RED_2TB/backup` — он root-owned, truenas_admin туда не пишет).
2. Добавить сервис `lidarr` по образцу `radarr`:
- image `lscr.io/linuxserver/lidarr:latest`
- `PUID=950 PGID=950 TZ=Asia/Novosibirsk`, `dns: [8.8.8.8, 8.8.4.4]`
- port `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 — name-conflict).
4. Caddy: добавить блок `lidarr.mallexxx.duckdns.org { reverse_proxy lidarr:8686 }`.
Caddyfile root-owned → **только через alpine-контейнер** (`docker run --rm -i -v /:/host:rw alpine ...`,
см. skill `truenas-caddy-service-deploy`). Отправлять **весь файл**, не патч.
5. **ПРИЁМКА ALEX:** `https://lidarr.mallexxx.duckdns.org` открывается.
### Фаза 2 — Lidarr на музыку
1. Root folder — **РЕШЕНИЕ АЛЕКСА НУЖНО** (см. вопросы ниже).
2. Download client — Transmission: host `transmission`, port `9091`, urlBase `/transmission/`,
category `lidarr`.
3. Индексеры: добавить Application `Lidarr` в Prowlarr (`syncLevel: fullSync`,
`baseUrl: http://lidarr:8686`) — либо вставить Torznab вручную, если синк не пройдёт.
> ⚠️ Lidarr требует **audio-категории (3000-я серия)** в профиле индексера. Посмотреть,
> отдают ли их наши трекеры — RuTracker/Kinozal обычно да; RuTor — нет (см. skill: RuTor
> не даёт movie-категорий; для audio проверить отдельно).
4. `preferMagnetUrl: true` — применить (нет дневного лимита на .torrent).
5. Прокси-тег для заблокированных (из Фазы 0).
6. **ПРИЁМКА ALEX:** тестовый поиск артиста → релиз найден → торрент ушёл в Transmission.
### Фаза 3 — синк с Jellyfin
> 🔴 **ЗАБЛОКИРОВАНО.** Создавать `collectionType=music` на текущих тегах нельзя:
> 7906 файлов → `mojibake` 2759, `lost` 662 (данные уничтожены), `empty` 1026, `partial` 2920.
> Jellyfin раскладывает музыку **по тегам**, не по папкам → получится свалка `Unknown Artist`.
> Полный контекст: [[personal/tech/music-tags-repair-truenas]] — этапы 1–2 готовы (CSV v2),
> ждёт апрув Alex, правки файлов не начаты.
1. Решить порядок (см. вопрос 2 ниже).
2. `/storage/Music` **уже смонтирован** в jellyfin (ro) — доп. монтирование НЕ нужно.
3. Создание: `POST /Library/VirtualFolders?name=Music&collectionType=music&paths=/storage/Music`
(**name/paths в query string**, не в body — Jellyfin 10.11).
4. Возможный митигирующий вариант: `EnableFolderView` — навигация по папкам, теги вторичны.
5. **ПРИЁМКА ALEX:** вкладка Music → треки видны.
### Фаза 4 — приёмка всего стека
1. `docker ps` — все 6 (+ lidarr) Up, uid 950.
2. Radarr/Sonarr/Lidarr health — без ошибок Indexer* и RemotePathMapping.
3. Разобрать RemotePathMapping (см. раздел выше) — нужен подкаталог категории в Transmission
**или** корректный маппинг.
4. **ПРИЁМКА ALEX:** панели открываются, плейбек идёт, поиск работает.
## ❓ ВОПРОСЫ, ЖДУЩИЕ ОТВЕТА АЛЕКСА
1. **Куда Lidarr складывает музыку?**
- (A) отдельный staging `/storage/Music-lidarr` + router-симлинки в `Music/`
— безопасно, не трогает 7890 существующих файлов. **Рекомендую.**
- (B) прямо в `/storage/Music` с отключённым переименованием — риск конфликтов с существующей
категорийной структурой (`!Rock&Folk` и т.д.).
2. **Музыка в Jellyfin — до или после ремонта тегов?**
- Док от 2026-09-26: «сначала теги». Lidarr принесёт часть файлов с чистыми тегами,
но 7890 старых останутся битыми.
## Открытые техвопросы (разобрать по ходу)
- Баг «короткого URL» Prowlarr→Radarr: `http://prowlarr:9696/6/` vs `/prowlarr/6/`.
Нужно решить, корректен ли он при **пустом** `<UrlBase>` у prowlarr. 401 на `?t=caps` — сигнал,
что что-то не так, но не однозначно.
- Битый `image.imageHeight`/пост-обработка не в scope.
- RuTor не даёт movie-категорий; для audio проверить отдельно.
- Есть ли `curl` внутри linuxserver-образов (для прокси-тестов) — проверить.
## История
- **2026-09-26** — разведка, найдены 2 блокера (DNS-фильтр провайдера + vless-proxy не в media_net),
план составлен, ожидает 2 ответов Alex. Ничего не изменено.