Files
obsidian-vault/family/how-to/arr-stack-taiga.md
T

229 lines
17 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Arr stack — TrueNAS Taiga
created: '2026-05-23'
updated: '2026-09-29'
type: tech
namespace: family
tags: [arr, taiga, truenas, media, operations]
related:
- "[[personal/tech/flaresolverr-taiga]]"
- "[[family/how-to/truenas-infrastructure]]"
- "[[family/how-to/arr-stack-kraken]]"
---
# Arr stack — TrueNAS Taiga
Каноническая документация arr-стека на TrueNAS **Taiga**. Kraken сюда не входит.
## Текущее состояние
Проверено 2026-09-29 после полного `force-recreate`:
- `flaresolverr`, `prowlarr`, `radarr`, `sonarr`, `lidarr`, `jellyfin`, `transmission` запущены.
- `docker compose config -q` проходит.
- Lidarr → SkyHook: 10 результатов через VLESS proxy.
- Lidarr → Transmission: штатный test проходит.
- Prowlarr → RuTracker: реальный search возвращает 50 результатов.
- Prowlarr → Kinozal: реальный search возвращает 14 результатов.
- FlareSolverr: health `ok`, session `prowlarr` создаётся с proxy и pre-login.
- 3x-ui egress закреплён: Sweden master → Poland failover → текущий auto-resolve.
- Три последовательных proxy-запроса сохраняют один внешний IP.
- FlareSolverr watcher автоматически восстанавливает session и RuTracker login после потери.
Health-warning у Sonarr/Lidarr может показывать старый quarantine индексаторов. Проверять нужно реальным search и `IndexerStatus`, а не одной строкой health.
## Архитектура
| Компонент | Container | Порт | Назначение |
|---|---|---:|---|
| Prowlarr | `prowlarr` | 9696 | индексаторы и sync |
| Radarr | `radarr` | 7878 | фильмы |
| Sonarr | `sonarr` | 8989 | сериалы |
| Lidarr | `lidarr` | 8686 | музыка и SkyHook |
| FlareSolverr | `flaresolverr` | 8191 | Cloudflare/browser |
| Transmission | `transmission` | 9091 | torrent download client |
| Jellyfin | `jellyfin` | 8096 | media server |
| VLESS proxy | `vless-proxy` | 1080/1081 | SOCKS5/HTTP proxy |
Compose:
```text
/mnt/RED_2TB/docker/arr/docker-compose.yml
```
Конфигурация сервисов: `/mnt/RED_2TB/docker/arr/<service>`. Media mount внутри arr-контейнеров: `/storage`.
## Маршрутизация
1. Lidarr → `api.lidarr.audio` идёт через `http://vless-proxy:1081`.
2. FlareSolverr/Chrome → RuTracker идёт через `socks5://vless-proxy:1080`.
3. Локальный Transmission идёт напрямую по `transmission:9091`.
### Sticky egress для трекеров
Настройки 3x-ui находятся на Taiga в `/mnt/RED_2TB/docker/xray-admin/x-ui.db`. Для пользователя `vless-space` используется цепочка:
```text
space-master → sub1-sweden (prefix; также матчится sub1-sweden-yt)
space-failover → sub1-poland-yt
space-auto → sub1-* / leastLoad
```
Исправление 2026-11-02: подписка больше не содержала `sub1-sweden-yt` (актуальный тег — `sub1-sweden`), поэтому основной selector не находил кандидатов. Резервирование тоже было ошибочным: Xray `fallbackTag` принимает **outbound**, а не другой balancer. В журнале — `non existing outTag: space-failover`; Lidarr показывал `Invalid response received from LidarrAPI`, вложенная причина — TLS `unexpected EOF`.
В постоянном `settings.xrayTemplateConfig` исправлен prefix основного selector и добавлены два outbound типа `loopback`: `space-failover` → inboundTag `space-failover-loopback`, `space-auto` → inboundTag `space-auto-loopback`. Соответствующие routing-правила отправляют их на одноимённые balancer и стоят **перед** правилом `vless-space-via-subscription`, чтобы не возвращаться на основной маршрут. Остальные клиенты, подписка и observatory не изменялись.
Приёмка на живом Lidarr: `/api/v1/search` для «Четыре», «Четыре позиции Бруно», «4 Позиции Бруно» и Radiohead — HTTP 200; `artist/lookup` находит `4 Позиции Бруно` (`c0e9bf2e-9c31-4ff1-8e23-0021652a9015`). Обе резервные ступени проверены временным override `space-master` на соответствующий loopback: поиск HTTP 200; override затем снят, основной выбор `sub1-sweden`. Ошибок `non existing outTag` после рестарта — 0. Бэкап SQLite (через backup API, с WAL) и шаблонов до/после: `/mnt/RED_2TB/docker/xray-admin/lidarr-search-fix-20261102T013142Z/`. Откат — вернуть только значение `xrayTemplateConfig` из `template-before.json` и перезапустить `xray-admin`; весь файл БД поверх живого контейнера не копировать.
Master и первый failover не должны быть заменены общим `leastLoad`: смена egress-IP между challenge и повторным запросом инвалидирует Cloudflare-cookie.
Lidarr должен иметь:
```text
proxyEnabled=true
proxyType=http
proxyHostname=vless-proxy
proxyPort=1081
proxyBypassLocalAddresses=true
proxyBypassFilter=transmission,prowlarr
```
Pitfall: `proxyBypassLocalAddresses=false` помогает SkyHook, но одновременно отправляет локальный Transmission через VLESS и ломает его. Внешний и локальный маршруты разделены намеренно.
## FlareSolverr и RuTracker
Entrypoint:
```text
/mnt/RED_2TB/docker/arr/flaresolverr-entrypoint.sh
```
При старте он ждёт `/health`, создаёт session `prowlarr` с `socks5://vless-proxy:1080`, читает credentials RuTracker из Prowlarr SQLite в режиме `immutable=1`, выполняет pre-login и запускает основной процесс. В compose важны `PROXY_URL`, `BROWSER_TIMEOUT=180000`, `shm_size: 1gb`, `restart: unless-stopped` и read-only mount каталога Prowlarr.
После старта watcher проверяет egress-IP каждую минуту и login-состояние RuTracker каждые пять минут. При смене IP или потере login он пересоздаёт session и выполняет pre-login заново.
RuTracker должен иметь оба Prowlarr-тега:
```text
proxy + flaresolverr = [1,2]
```
Подробности: [[personal/tech/flaresolverr-taiga]].
Повторный сбой 2026-10-26 UTC: реальные отказы RuTracker сопровождались локальной ошибкой Prowlarr `database is locked`; подобные блокировки затрагивали и другие индексаторы, затем Lidarr. Отдельно исправлен watchdog FlareSolverr: признак входа теперь проверяется в HTML после разбора JSON, временная ошибка запроса не сбрасывает рабочую сессию. Проверено: 50 результатов реального поиска, успешный одиночный тест RuTracker в Lidarr, после `CheckHealth` предупреждение о недоступности индексаторов исчезло. Высокое ожидание дискового I/O и блокировки SQLite требуют отдельного разбора; исправление watchdog их не устраняет.
## Перезапуск и приёмка
```bash
ssh truenas_admin@mallexxx.duckdns.org \
'cd /mnt/RED_2TB/docker/arr && docker compose config -q && docker compose up -d --force-recreate flaresolverr prowlarr radarr sonarr lidarr'
ssh truenas_admin@mallexxx.duckdns.org \
'cd /mnt/RED_2TB/docker/arr && docker compose ps'
```
FlareSolverr session:
```bash
curl -fsS -H 'Content-Type: application/json' \
-d '{"cmd":"sessions.list"}' http://127.0.0.1:8191/v1
```
Ожидается `status=ok` и session `prowlarr`.
SkyHook:
```bash
curl -H "X-Api-Key: $LIDARR_KEY" \
'http://127.0.0.1:8686/api/v1/artist/lookup?term=Astrix'
```
Ожидается непустой JSON-массив и запись VLESS о `api.lidarr.audio:443`.
RuTracker проверять реальным search, а не только `indexer/test`:
```bash
curl -H "X-Api-Key: $PROWLARR_KEY" \
'http://127.0.0.1:9696/api/v1/search?query=radiohead&type=search&indexerIds=1'
```
Ожидается непустой массив без `error` у результатов.
## Pitfalls и исправления
### Session не наследует proxy задним числом
`PROXY_URL` применяется при создании Chrome session. После изменения proxy session нужно пересоздать. Entrypoint делает это автоматически при старте FlareSolverr.
### Профиль прокси меняется между запросами
Симптом: FlareSolverr успешно решает challenge, но Prowlarr получает `Auth Failed` или timeout на следующем запросе. Причина — 3x-ui `leastLoad` выбрал другой профиль и внешний IP изменился. Исправление — pinned master/failover chain и watcher relogin; timeout сам по себе проблему не решает.
### Prowlarr API маскирует password
GET индексатора возвращает `********`. Нельзя использовать такой JSON для pre-login. Рабочий pre-login читает SQLite read-only из отдельного контейнера.
### `indexer/test` не является единственной приёмкой
Он может тестировать объект с замаскированным password и вернуть `Auth Failed`, хотя реальный search работает. Приёмка — реальный `/api/v1/search` плюс FS request с cookie `bb_session`.
### Размер HTML не доказывает login
Страница Cloudflare/Chromium может быть большой. Надёжный признак — `bb_session` и успешный запрос через ту же session.
### Quarantine может быть историческим
Перед очисткой сделать SQLite backup. Остановить Prowlarr, удалить только `IndexerStatus`, выполнить `PRAGMA quick_check`, запустить снова и повторить реальный search. Всю БД не удалять.
### `testall` создаёт ложные timeout
Параллельные browser challenges перегружают Chrome. Проверять один индексатор за раз с большим timeout.
## Массовая закачка альбомов
Альбомы скачиваются пачкой, по одному ходить не нужно:
| Сценарий | Действие |
|---|---|
| Новый артист | `Monitor` → **All** + `Start search for missing albums` — очередь на все отсутствующие альбомы |
| Уже добавлен | `Artist → Edit → Monitor: All` + **Search Monitored** |
| Вся библиотека | `Wanted → Missing → Search All` |
| Много артистов сразу | `Library Import` (`Monitor: All` каждому) или `POST /api/v1/artist` в цикле |
Один альбом за раз — только при `Monitor: Single Album` или ручном поиске лупы у альбома.
Приёмка пакетного поиска — реальный `queue`/`History` в Lidarr, а не строка health: при открытом
дефекте download-client очередь формируется, но раздачи не стартуют.
## Troubleshooting
### Monitored без скачиваний: MASTER BOOT RECORD, 2026-11-02
На живом хосте у MASTER BOOT RECORD (`artistId=97`) все 12 альбомов monitored, файлов и истории загрузок нет. Prowlarr оказался остановлен с 2026-10-28 (`ExitCode=137`, `OOMKilled=false`; причину остановки отдельно не установили). До остановки журнал содержал `database is locked`. Все активные индексаторы Lidarr были в карантине. База Prowlarr прошла `PRAGMA quick_check=ok`; контейнер запущен без изменения настроек качества. После штатного перезапуска FlareSolverr подтверждён вход в RuTracker (parsed HTML logged-in=true), затем прошли одиночные тесты RuTracker в Prowlarr и RuTracker/NoNaMe Club/Kinozal в Lidarr. Health Lidarr — `[]`.
Уточнённая диагностика MP3, 2026-11-02: проверка одного FLAC-релиза VIRUS.DOS была недостаточна для объяснения отсутствия загрузок MP3. Нужно выполнять **поиск по артисту** `GET /api/v1/release?artistId=97`, без `albumId`: альбомный поиск добавляет название отдельного альбома и может не находить пак дискографии. Lidarr поддерживает дискографии — утверждать обратное нельзя.
На RuTracker есть MP3-пак `Master Boot Record - Discography (15 Albums) - 2016-2024, MP3, 160-320 kbps`, тема `5969222`, размер 1 998 105 001 байт, 23 сида при проверке. Поиск по артисту в Lidarr находит его и возвращает **два точных отказа**: `1.9 GB is larger than maximum allowed 690.3 MB` и `MP3-160 is not wanted in profile`. Диапазон 160–320 из названия распознан как MP3-160; в профиле `MP3 (default)` MP3-160 выключен, разрешены MP3-VBR-V2/MP3-256/MP3-VBR-V0/MP3-320. Сам факт, что раздача MP3, не означает соответствия этим ограничениям. Лимиты качества/размера и ручной override раздачи не менялись.
Другие MP3 из того же поиска также имеют отдельные причины отказа: Realtime Execution — `Unable to parse albums from release name`; VirtuaVerse — `Unable to parse release`; сингл Secret Track — `Unable to parse albums from release name`. Проверенный FLAC-релиз VIRUS.DOS отклонён с `FLAC is not wanted in profile`, но это не объяснение отказа имеющейся MP3-дискографии.
После refresh только этого артиста и повторного `MissingAlbumSearch` через 3 активных индексатора команда `87994` завершилась: `Completed search for 12 albums. 0 reports downloaded.` Очередь и история MASTER BOOT RECORD остались пустыми. Это не результат «скачивание исправлено»: доступ к индексаторам восстановлен, но подходящие загрузки в текущем профиле не выбраны. Профиль MP3 и мониторинг не менялись; разрешение FLAC не следует из самого вопроса о monitored.
| Симптом | Проверка | Исправление |
|---|---|---|
| SkyHook 403 | host config Lidarr и VLESS log | proxy `vless-proxy:1081`, local bypass оставить включённым |
| Transmission auth error | download-client test | синхронизировать password с текущим Transmission `PASS`; host `transmission:9091` |
| RuTracker Auth Failed | session, cookies, real search | пересоздать session/pre-login; не использовать `********` |
| DNS/Cloudflare timeout | VLESS log, FS cookies, tags | проверить `[1,2]` и `BROWSER_TIMEOUT=180000` |
| Старый health quarantine | `IndexerStatus` и real search | backup + очистка только `IndexerStatus` |
| сервис не пережил restart | compose, mounts, restart policy | проверить bind mounts и `restart: unless-stopped` |
## Backup и безопасность
Перед изменением Prowlarr DB или compose сохранять backup рядом с исходным файлом. Пароли и API keys в Obsidian не записывать.
## Связанные документы
- [[personal/tech/flaresolverr-taiga]] — FlareSolverr, session, pre-login и диагностика.
- [[family/how-to/truenas-infrastructure]] — общий TrueNAS.
- [[family/how-to/arr-stack-kraken]] — отдельный стек Kraken; не смешивать с Taiga.