--- title: Skill — arr-media-stack-setup (дополнения 2026-09-26) created: '2026-09-26' updated: '2026-09-28' type: tech namespace: personal tags: - skill - arr - prowlarr - dns - 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: ' \ 'http://localhost:9696/api/v1/indexer/' > /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) **Новый класс проблемы**, ранее не описанный в скилле. Задокументированы были только «Cloudflare 403 на `indexers.prowlarr.com`» и «RuTracker Turnstile». Здесь **DNS не отдаёт IP вообще**. ```bash # InitialFailure показывает НАЧАЛО проблемы, а не «сейчас» GET /api/v1/indexerstatus → initialFailure: "2026-05-20T05:4x:xx" ← день деплоя → disabledTill: +24 ч карантин # Резолв проверять ДВУМЯ резолверами nslookup rutracker.org 192.168.2.2 # роутер nslookup rutracker.org 8.8.8.8 # внешний # NXDOMAIN на ОБОИХ → фильтр на стороне аплинка/провайдера # NXDOMAIN на роутере → Pi-hole/локальный DNS ``` **Быстрый чек всех индексеров** — `wget -S` на каждый домен из контейнера prowlarr: `wget: bad address ''` = DNS-провал, `HTTP/1.1 200 OK` = домен жив. **Фикс:** SOCKS5-прокси, но сперва убедиться, что прокси-контейнер виден целевой сети (`docker network inspect media_net --format '{{range .Containers}}{{.Name}} {{end}}'`). После `docker network connect` — **добавить сеть в compose**, иначе потеряется при пересоздании. Затем `POST /api/v1/indexer/testall` снимает `disabledTill`. ## 2. `disabledTill` НЕ виден в Radarr/Sonarr `GET /api/v3/indexer` отдаёт `"status": {}` — пусто. Карантин смотреть **только** в Prowlarr (`/api/v1/indexerstatus`, `/api/v1/health`). Не делать вывод «индексеры свободны» по Radarr. ## 3. TrueNAS: `python3` ЕСТЬ, `curl` и `sqlite3` — НЕТ **Исправление распространённой ошибки в доке** («нет curl и python3»). Факт 2026-09-26: `python3` на хосте работает (использовался для разбора JSON). Нет **`curl`** и **`sqlite3`**. **Рабочий паттерн API = `wget` в контейнере + хостовый `python3`:** ```bash ssh truenas_admin@HOST \ "docker exec prowlarr sh -c 'wget -qO- --header=\"X-Api-Key: \" http://localhost:9696/api/v1/health'" ``` - busybox-`wget`: только `-qO-` / `-S` / `--header` / `--timeout`. **`-e use_proxy=yes` НЕ поддерживается** (GNU-опция) → прокси-тест изнутри linuxserver-контейнера этим способом невозможен. - Экранирование JSON через ssh ломается на кавычках в `--header` → надёжнее писать вывод в файл (`> /tmp/x.json`) и разбирать отдельным вызовом. - `jq` с дефисами: `.["download-dir"]`, не `.download-dir`. ## 4. `/etc/resolv.conf` контейнеров = `127.0.0.11` Docker embedded DNS. В linuxserver-образах **нет `getent`** → использовать `nslookup`/`wget`. ## 5. RemotePathMapping: health жалуется при «задокументированном» маппинге ``` RemotePathMappingCheck error "download client Transmission places downloads in /storage/Downloads/radarr but this directory does not appear to exist inside the container" ``` Проверять **фактический** download-dir, а не предполагаемый: ```bash docker exec transmission sh -c 'cat /config/settings.json' # → "download-dir": "/mnt/storage/Downloads" ``` Если download-dir **плоский** (без подкаталога категории) — сам маппинг не спасёт: подкаталога нет. Плюс Transmission монтирует `/mnt/storage`, Radarr — `/storage` (один хост-путь под двумя именами). **Всегда проверять наличие записей в API** (`GET /api/v3/remotepathmapping`), а не то, что записано в доке. ## Связанные заметки - [[personal/plans/lidarr-taiga-and-indexer-unblock]] — план, из которого выросли эти находки - [[family/projects/media-toolbox-taiga]] — состояние стека на Тайге