[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

This commit is contained in:
Alexey Martemyanov committed 2026-09-28 01:58:17 +06:00
1 parent 6bcc02ec19
commit a74ce112a6
4 files changed
+184 -356

No files matched your search

@@ -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` — формально валидные теги:
+116 -353
View File
@@ -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/<Artist>/<Album>/<track> - <title>`, `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 не импортировать**), деплой начат.
+16 -2
View File
@@ -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 автоматически.
@@ -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)
**Новый класс проблемы**, ранее не описанный в скилле. Задокументированы были только