Files
obsidian-vault/personal/tech/skill-arr-media-stack-setup-additions.md
T

11 KiB
Executable File
Raw Blame History

title, created, updated, type, namespace, tags, related
title created updated type namespace tags related
Skill — arr-media-stack-setup (дополнения 2026-09-26) 2026-09-26 2026-09-28 tech personal
skill
arr
prowlarr
dns
truenas
blocked
pitfalls
lidarr
navidrome
family/how-to/arr-stack-taiga
family/how-to/arr-stack-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, имя папки перекрывает теги). Актуальный Taiga runbook — family/how-to/arr-stack-taiga.

Сервис = копия 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, не предполагать

# внутри контейнера 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)

Новый класс проблемы, ранее не описанный в скилле. Задокументированы были только «Cloudflare 403 на indexers.prowlarr.com» и «RuTracker Turnstile». Здесь DNS не отдаёт IP вообще.

# 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 '<domain>' = 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:

ssh truenas_admin@HOST \
  "docker exec prowlarr sh -c 'wget -qO- --header=\"X-Api-Key: <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, а не предполагаемый:

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), а не то, что записано в доке.

6. 🔴 Прокси в Lidarr: «записан» ≠ «применяется» (2026-09-28, поздний вечер)

Конфиг-ридбэк ИДЕАЛЬНЫЙ — proxyEnabled:true, proxyType:"http", proxyHostname:"vless-proxy", proxyPort:1081, proxyBypassFilter расширен на все docker-имена стека — а Lidarr всё равно ходит напрямую:

docker logs lidarr | grep -i proxy
  [Error] ProxyCheck: Proxy Health Check failed

artist/lookup → 403 Cloudflare, и сама страница ошибки CF выдаёт egress-IP: Your IP: 90.189.160.148 — домашний аплинк, не VPS. docker restart lidarr не помог.

Диагностическая триада: «прокси настроен неверно» vs «прокси не применяется»

# 1. конфиг верный?            GET /api/v1/config/host  → proxyEnabled / proxyType / proxyPort
# 2. прокси САМ работает?      (из того же контейнера)
docker exec lidarr sh -c 'curl -s -m 15 -x http://vless-proxy:1081 https://api.ipify.org'  # VPS IP
docker exec lidarr sh -c 'curl -s -m 15 https://api.ipify.org'                             # домашний IP
# 3. Lidarr ЕГО ИСПОЛЬЗУЕТ?    ЛОГ — единственный надёжный сигнал
docker logs lidarr 2>&1 | grep -i proxy     # ProxyCheck failed ⇒ НЕ использует

Если (1) ✅ и (2) ✅, а (3) даёт ProxyCheck failed — конфиг инертен.

  • Подозреваемый №1: proxyBypassLocalAddresses: true. api.lidarr.audio резолвится в Cloudflare-IP; эвристика «локальный адрес» может его проглотить. Проверить с false.
  • Подозреваемый №2: IPv6-цель против IPv4-only прокси. В контейнере api.lidarr.audio даёт 2606:4700:... (AAAA), а vless-proxy:1081 — только IPv4. CONNECT к v6-цели падает, и .NET-клиент молча откатывается на прямое соединение. Проверка: curl -x http://vless-proxy:1081 -6 https://api.lidarr.audio/...
  • Подозреваемый №3: proxyType:"socks5" + порт 1080 — обойти специфику HTTP-CONNECT.

🔴 GET /api/v1/health → [] НЕ значит «сервис здоров». Lidarr пишет провал ProxyCheck только в лог — в health-API он не попадает. health: [] сосуществовал с жёстким 403 на каждом вызове метаданных. Проверять живым artist/lookup + docker logs | grep, не health.

🔴 Обобщённое правило для этого хоста: любой сервис, который ходит в интернет сам (Lidarr → SkyHook, FlareSolverr → Chrome), по умолчанию выходит через домашний аплинк (90.189.160.148). curl api.ipify.org на хосте Тайги возвращает домашний IP — VPS-выход существует только за vless-proxy. ⇒ «прокси настроен» бессмысленно; доказательство одно: отличается ли egress-IP этого сервиса от 90.189.160.148.

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