13 KiB
Executable File
title, created, updated, type, namespace, tags, related
| title | created | updated | type | namespace | tags | related | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| FlareSolverr на TrueNAS Taiga | 2026-09-20 | 2026-09-29 | tech | personal |
|
|
FlareSolverr на TrueNAS Taiga
Рабочая документация FlareSolverr для arr-стека Taiga. Общая эксплуатация стека находится в family/how-to/arr-stack-taiga. Kraken здесь не описывается.
Рабочая схема
Prowlarr
└─ tags [proxy, flaresolverr]
└─ FlareSolverr :8191
└─ Chrome session prowlarr
└─ socks5://vless-proxy:1080
└─ RuTracker
Внешний egress для arr закреплён на маршруте 3x-ui:
vless-space
└─ space-master: sub1-sweden
└─ space-failover: sub1-poland-yt
└─ space-auto: текущий leastLoad по подписке
Это важно для Cloudflare: FlareSolverr и последующий запрос Prowlarr должны выходить через один IP. Общий leastLoad по всем профилям без pinned master ломает cookie handoff.
Файлы на TrueNAS:
/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 при каждом старте:
- ждёт FlareSolverr
/health; - удаляет старую session
prowlarr, если она есть; - создаёт
prowlarrсsocks5://vless-proxy:1080; - читает credentials RuTracker из
prowlarr.dbчерез SQLite URImode=ro&immutable=1; - делает pre-login через FlareSolverr;
- оставляет основной процесс FlareSolverr работать;
- проверяет egress-IP раз в минуту и login-состояние RuTracker раз в пять минут;
- при смене IP или потере login-состояния пересоздаёт session
prowlarrи выполняет login заново.
SQLite монтируется read-only. Обычный sqlite3.connect('/prowlarr.db') на read-only mount может упасть с unable to open database file; нужен именно immutable=1.
Compose-настройки
Минимально необходимые параметры:
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:
proxy tag = [1]
flaresolverr tag = [2]
RuTracker tags = [1,2]
FlareSolverr requestTimeout = 180 seconds
3x-ui: master и failover
Шаблон находится в базе 3x-ui:
/mnt/RED_2TB/docker/xray-admin/x-ui.db
Текущая цепочка:
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:
curl -fsS -H 'Content-Type: application/json' \
-d '{"cmd":"sessions.list"}' http://127.0.0.1:8191/v1
Должны быть status=ok и prowlarr.
Проверка login должна смотреть cookies, а не размер HTML:
solution.cookies содержит bb_session
Большая HTML-страница может быть страницей ошибки Chromium и не означает login.
Функциональная приёмка — реальный search Prowlarr:
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.
Диагностика
docker compose ps— контейнеры живы.curl /health— FlareSolverr отвечает.sessions.list— session существует.- Проверить
bb_sessionвsolution.cookies. - Проверить логи
vless-proxyнаrutracker.org:443. - Выполнить одиночный реальный search, не
testall.
Параллельный testall перегружает один Chrome и создаёт ложные timeout. Challenge может занимать больше минуты, поэтому timeout 60 секунд недостаточен.
Перезапуск
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; различать два независимых дефекта.
- Фактические отказы поиска: Prowlarr писал
SQLiteException Busy (5): database is locked. У RuTracker ошибки зафиксированы в 16:08:13 UTC и 17:20:59 UTC, в том числе вGetCookies → ProviderStatusRepository.FindByProviderId, до обращения к трекеру. Аналогичные ошибки были у Kinozal, NoNaMeClub и RuTor. Позже такие же блокировки продолжались в Lidarr. Это не доказательство потери авторизации RuTracker. - Ошибка 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.