Files
obsidian-vault/personal/tech/flaresolverr-taiga.md
T

199 lines
13 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: 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]].