--- title: FlareSolverr на TrueNAS Taiga created: '2026-09-20' updated: '2026-09-29' type: tech namespace: personal tags: [flaresolverr, prowlarr, rutracker, taiga, truenas] related: - "[[family/how-to/arr-stack-taiga]]" --- # FlareSolverr на TrueNAS Taiga Рабочая документация FlareSolverr для arr-стека Taiga. Общая эксплуатация стека находится в [[family/how-to/arr-stack-taiga]]. Kraken здесь не описывается. ## Рабочая схема ```text Prowlarr └─ tags [proxy, flaresolverr] └─ FlareSolverr :8191 └─ Chrome session prowlarr └─ socks5://vless-proxy:1080 └─ RuTracker ``` Внешний egress для arr закреплён на маршруте 3x-ui: ```text vless-space └─ space-master: sub1-sweden └─ space-failover: sub1-poland-yt └─ space-auto: текущий leastLoad по подписке ``` Это важно для Cloudflare: FlareSolverr и последующий запрос Prowlarr должны выходить через один IP. Общий `leastLoad` по всем профилям без pinned master ломает cookie handoff. Файлы на TrueNAS: ```text /mnt/RED_2TB/docker/arr/docker-compose.yml /mnt/RED_2TB/docker/arr/flaresolverr-entrypoint.sh /mnt/RED_2TB/docker/arr/prowlarr/ ``` ## Почему нужен entrypoint Одного `PROXY_URL` недостаточно. FlareSolverr применяет proxy при создании browser session. Если session создана до настройки proxy, последующие `request.get` с той же session продолжают работать без proxy. Entrypoint при каждом старте: 1. ждёт FlareSolverr `/health`; 2. удаляет старую session `prowlarr`, если она есть; 3. создаёт `prowlarr` с `socks5://vless-proxy:1080`; 4. читает credentials RuTracker из `prowlarr.db` через SQLite URI `mode=ro&immutable=1`; 5. делает pre-login через FlareSolverr; 6. оставляет основной процесс FlareSolverr работать; 7. проверяет egress-IP раз в минуту и login-состояние RuTracker раз в пять минут; 8. при смене IP или потере login-состояния пересоздаёт session `prowlarr` и выполняет login заново. SQLite монтируется read-only. Обычный `sqlite3.connect('/prowlarr.db')` на read-only mount может упасть с `unable to open database file`; нужен именно `immutable=1`. ## Compose-настройки Минимально необходимые параметры: ```yaml environment: - LOG_LEVEL=warning - BROWSER_TIMEOUT=180000 - PROXY_URL=socks5://vless-proxy:1080 - TZ=Asia/Novosibirsk shm_size: 1gb restart: unless-stopped ``` Entrypoint и Prowlarr config directory подключаются read-only. Не хранить credentials или API keys в compose и Obsidian. В Prowlarr для RuTracker: ```text proxy tag = [1] flaresolverr tag = [2] RuTracker tags = [1,2] FlareSolverr requestTimeout = 180 seconds ``` ## 3x-ui: master и failover Шаблон находится в базе 3x-ui: ```text /mnt/RED_2TB/docker/xray-admin/x-ui.db ``` Текущая цепочка: ```text space-master selector=[sub1-sweden] fallback=space-failover space-failover selector=[sub1-poland-yt] fallback=space-auto space-auto selector=[sub1-] strategy=leastLoad ``` Актуально после исправления 2026-11-02: `sub1-sweden` — prefix selector; `fallbackTag` ссылаются на одноимённые **outbound типа loopback**, которые через отдельные inboundTag/routing-правила передают трафик следующему balancer. Ссылка `fallbackTag` прямо на balancer не работает. Подробности и проверка обеих резервных ступеней — [[family/how-to/arr-stack-taiga]]. Не использовать общий `leastLoad` как первый уровень для RuTracker/Kinozal: он может менять egress между соединениями. `maxRTT` и `tolerance` фильтруют кандидатов, но не делают выбор sticky. Перед изменением базы сохранять backup. После изменения проверить сгенерированный `/app/bin/config.json` и выполнить `xray -test`; не редактировать сгенерированный файл напрямую. Один tag `[2]` не решает DNS-блок Taiga. Один tag `[1]` не решает browser challenge. ## Правильная проверка Проверка session: ```bash curl -fsS -H 'Content-Type: application/json' \ -d '{"cmd":"sessions.list"}' http://127.0.0.1:8191/v1 ``` Должны быть `status=ok` и `prowlarr`. Проверка login должна смотреть cookies, а не размер HTML: ```text solution.cookies содержит bb_session ``` Большая HTML-страница может быть страницей ошибки Chromium и не означает login. Функциональная приёмка — реальный search Prowlarr: ```bash curl -H "X-Api-Key: $PROWLARR_KEY" \ 'http://127.0.0.1:9696/api/v1/search?query=radiohead&type=search&indexerIds=1' ``` `POST /api/v1/indexer/test` не использовать как единственное доказательство: при передаче объекта из API password может быть `********`, что даёт ложный `Auth Failed`. ## Диагностика 1. `docker compose ps` — контейнеры живы. 2. `curl /health` — FlareSolverr отвечает. 3. `sessions.list` — session существует. 4. Проверить `bb_session` в `solution.cookies`. 5. Проверить логи `vless-proxy` на `rutracker.org:443`. 6. Выполнить одиночный реальный search, не `testall`. Параллельный `testall` перегружает один Chrome и создаёт ложные timeout. Challenge может занимать больше минуты, поэтому timeout 60 секунд недостаточен. ## Перезапуск ```bash ssh truenas_admin@mallexxx.duckdns.org \ 'cd /mnt/RED_2TB/docker/arr && docker compose config -q && docker compose up -d --force-recreate flaresolverr' ``` После restart session должна восстановиться автоматически. Если она не появилась, смотреть `docker logs flaresolverr`; credentials не выводить в лог. Автовосстановление можно проверить безопасно: удалить только session `prowlarr` через `sessions.destroy`, дождаться watcher и проверить `request.get` страницы RuTracker с признаком `id="logged-in-username"`. ## Восстановление quarantine При старом предупреждении сначала подтвердить реальный search, выполнить одиночный штатный тест соответствующего индексатора и обновить health. Для Lidarr этот путь проверен 2026-10-26: RuTracker test + `CheckHealth` сняли предупреждение без редактирования БД. При API-тестировании использовать действующие секреты, а не маскированные значения из GET. Ручная очистка `IndexerStatus` — резервный способ только при неработающем штатном восстановлении: backup SQLite, остановка только затронутого сервиса, изменение только нужного статуса, `PRAGMA quick_check`, запуск и реальный search. Не удалять всю БД и не считать health единственным тестом. ## Повторный сбой 2026-10-26 UTC / 2026-10-27 Бишкек Проверено на Taiga; различать два независимых дефекта. 1. **Фактические отказы поиска:** Prowlarr писал `SQLiteException Busy (5): database is locked`. У RuTracker ошибки зафиксированы в 16:08:13 UTC и 17:20:59 UTC, в том числе в `GetCookies → ProviderStatusRepository.FindByProviderId`, до обращения к трекеру. Аналогичные ошибки были у Kinozal, NoNaMeClub и RuTor. Позже такие же блокировки продолжались в Lidarr. Это не доказательство потери авторизации RuTracker. 2. **Ошибка watchdog:** старый скрипт искал `id="logged-in-username"` через grep в сыром JSON FlareSolverr. Кавычки HTML в JSON экранированы, поэтому рабочая авторизация ошибочно считалась потерянной и session пересоздавалась каждые пять минут. На одной живой сессии подтверждено: parsed HTML logged-in=true, старый grep=false. Исправлен `/mnt/RED_2TB/docker/arr/flaresolverr-entrypoint.sh`: сначала разбирается JSON, затем проверяется HTML. Повторный login выполняется при явно обнаруженной форме входа; ошибки транспорта, challenge и некорректный ответ считаются неопределённым состоянием и не уничтожают действующую сессию. Таймаут проверки согласован с `BROWSER_TIMEOUT=180000`: 180 секунд внутри FlareSolverr и 240 секунд у curl. Смена egress-IP по-прежнему вызывает восстановление. Backup исходного скрипта: `/mnt/RED_2TB/docker/arr/flaresolverr-entrypoint.sh.before-json-auth-fix-20261026T175021Z`. Перезапущен только FlareSolverr; SQLite вручную не редактировалась. Приёмка: - синтаксис shell и пять проверок классификатора ответа прошли; - после перезапуска и очередного пятиминутного цикла вход сохранился, HTTP 200, ложных refresh в логах нет; - реальный поиск Prowlarr по RuTracker: HTTP 200, 50 результатов за 17 секунд; - одиночный штатный тест RuTracker в Lidarr прошёл; - после `CheckHealth` предупреждение о недоступных индексаторах исчезло; осталось только уведомление об обновлении Lidarr; - поисковые проверки не запускали новые скачивания. Ограничение: причина локальных блокировок SQLite не устранена этим изменением. На NAS измерено `/proc/pressure/io`: some около 66–70%, full около 50–54%; ZFS pool ONLINE без ошибок, первый mirror заполнен почти полностью (1.79 TiB занято, 27 GiB свободно), новый mirror почти пуст. Это подтверждает высокое ожидание I/O и неравномерное размещение данных, но не доказывает единственную причину блокировки. Настройки ZFS, маршрутизация и мониторинг музыкальной библиотеки не менялись. ## Итоговый рабочий результат На 2026-09-29 после полного рестарта Taiga: - FlareSolverr session `prowlarr` создаётся с proxy и pre-login. - Прямой запрос через session получает `bb_session`. - После полного restart: RuTracker — 50 результатов без ошибок; Kinozal — 14 результатов без ошибок. - Три последовательных proxy-запроса получают один egress-IP. - Искусственно удалённая FlareSolverr session автоматически восстановлена и снова logged-in. - Ошибки Lidarr/SkyHook не относятся к FlareSolverr; их routing описан в [[family/how-to/arr-stack-taiga]].