--- 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/`. 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-yt space-failover → sub1-poland-yt space-auto → sub1-* / leastLoad ``` 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]]. ## Перезапуск и приёмка ```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 | Симптом | Проверка | Исправление | |---|---|---| | 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.