Переименование: DUB-AI → grabber-ai (образ, сервис, документация, примеры)
docker / build (push) Successful in 21s

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
DenozordecandClaude Sonnet 5.5 committed 2026-10-28 18:57:41 +07:00
1 parent a64ced71d2
commit 71d9700f55
26 files changed
+48 -48

No files matched your search

+1 -1
View File
@@ -1,4 +1,4 @@
# Документация DUB-AI
# Документация grabber-ai
| Документ | Содержание |
|---|---|
+13 -13
View File
@@ -1,11 +1,11 @@
# Docker: запуск DUB-AI на VPS и сборка в Gitea CI/CD
# Docker: запуск grabber-ai на VPS и сборка в Gitea CI/CD
Контейнер запускает HTTP-сервис (`python -m src.service`): по ссылке на раздачу или по HTML определяет
дорожки озвучки (тип, студия, 18+, язык, роль, параметры аудио). Для трекеров за Cloudflare сервис
обращается к вашему **FlareSolverr**, адрес которого задаётся переменной окружения.
```
клиент ──HTTP──▶ dub-ai (:8000) ──▶ трекер (rutracker / nnmclub / kinozal)
клиент ──HTTP──▶ grabber-ai (:8000) ──▶ трекер (rutracker / nnmclub / kinozal)
(grabber) │ ▲ при 403/503 или странице-заглушке
└─▶ FlareSolverr ──┘ (DUB_FLARESOLVERR_URL)
```
@@ -72,7 +72,7 @@ curl -X POST http://localhost:8000/predict \
| `DUB_SEGMENTER_DIR` | `/app/models/segmenter` | каталог сегментатора страниц; нет каталога — работают правила |
| `DUB_HOST`, `DUB_PORT` | `0.0.0.0`, `8000` | адрес/порт внутри контейнера (наружу — `DUB_PUBLISH_PORT` в compose) |
| `DUB_DEVICE` | авто | `cpu` или `cuda` (в образе только CPU-сборка torch) |
| `DUB_IMAGE` | `dub-ai:local` | (compose) какой образ запускать, напр. из реестра Gitea |
| `DUB_IMAGE` | `grabber-ai:local` | (compose) какой образ запускать, напр. из реестра Gitea |
| `DUB_PUBLISH_PORT` | `8000` | (compose) порт на хосте |
В образе жёстко заданы `HF_HUB_OFFLINE=1` и `TRANSFORMERS_OFFLINE=1`: сервис ничего не скачивает с
@@ -88,19 +88,19 @@ Hugging Face. Все файлы моделей, включая архитект
Три способа подключить:
1. **Вместе с compose (по умолчанию).** Сервис `flaresolverr` поднимается рядом, порт наружу не
публикуется, `dub-ai` ходит к нему по `http://flaresolverr:8191`.
публикуется, `grabber-ai` ходит к нему по `http://flaresolverr:8191`.
2. **Свой FlareSolverr на другом хосте.** В `.env`: `DUB_FLARESOLVERR_URL=http://192.168.0.24:8191`, и
запускайте только `docker compose up -d dub-ai` (контейнер FlareSolverr не нужен). Адрес должен быть
запускайте только `docker compose up -d grabber-ai` (контейнер FlareSolverr не нужен). Адрес должен быть
достижим из контейнера: с VPS до домашней сети — через VPN/туннель, не открывайте FlareSolverr в интернет.
3. **`docker run`:**
```bash
docker run -d --name dub-ai -p 8000:8000 \
docker run -d --name grabber-ai -p 8000:8000 \
-e DUB_FLARESOLVERR_URL=http://flaresolverr:8191 -e DUB_API_TOKEN=... \
--network <сеть_с_flaresolverr> dub-ai:local
--network <сеть_с_flaresolverr> grabber-ai:local
```
Проверить, что адрес подхватился: `GET /health` → `"flaresolverr": true`. Проверка связи:
`docker compose exec dub-ai python -c "import urllib.request as u; print(u.urlopen('http://flaresolverr:8191/').read()[:80])"`.
`docker compose exec grabber-ai python -c "import urllib.request as u; print(u.urlopen('http://flaresolverr:8191/').read()[:80])"`.
Замечания:
* FlareSolverr нестабилен: бывают `Timeout after 15.0 seconds` и ответ ~40 с. Это ошибка 400/502 для
@@ -172,11 +172,11 @@ python tools/pack_models.py # -> models-bundle.tar.gz (≈ 75
# выкладка в реестр пакетов Gitea (версия — любая строка, например дата или хэш модели)
curl --fail -H "Authorization: token <GITEA_TOKEN>" \
--upload-file models-bundle.tar.gz \
https://<gitea>/api/packages/<owner>/generic/dub-ai-models/2026-10-28/models-bundle.tar.gz
https://<gitea>/api/packages/<owner>/generic/grabber-ai-models/2026-10-28/models-bundle.tar.gz
```
Ссылка для скачивания (она же `MODELS_URL`):
`https://<gitea>/api/packages/<owner>/generic/dub-ai-models/2026-10-28/models-bundle.tar.gz`.
`https://<gitea>/api/packages/<owner>/generic/grabber-ai-models/2026-10-28/models-bundle.tar.gz`.
Если у вашей Gitea ограничен размер пакета (`[packages] LIMIT_SIZE_GENERIC`, по умолчанию без лимита, но
nginx перед ней часто режет загрузки ~1 МБ), поднимите лимиты или используйте способ Б.
@@ -186,7 +186,7 @@ nginx перед ней часто режет загрузки ~1 МБ), под
## CI/CD в Gitea
Workflow `.gitea/workflows/docker.yml` собирает образ и публикует его в **реестр контейнеров Gitea**
(`<gitea-host>/<owner>/<repo>/dub-ai`).
(`<gitea-host>/<owner>/<repo>/grabber-ai`).
### Что настроить один раз
@@ -230,7 +230,7 @@ Workflow `.gitea/workflows/docker.yml` собирает образ и публи
```
2. Положить на VPS `docker-compose.yml` и `.env` (из `.env.example`):
```
DUB_IMAGE=<gitea-host>/<owner>/<repo>/dub-ai:latest
DUB_IMAGE=<gitea-host>/<owner>/<repo>/grabber-ai:latest
DUB_API_TOKEN=<openssl rand -hex 24>
DUB_FLARESOLVERR_URL=http://flaresolverr:8191
```
@@ -261,7 +261,7 @@ Workflow `.gitea/workflows/docker.yml` собирает образ и публи
| `/predict` → 400 «страница недоступна: Cloudflare challenge … (задайте FlareSolverr)» | не задан `DUB_FLARESOLVERR_URL` или контейнер его не видит (`/health` → `flaresolverr`), проверьте сеть/имя сервиса |
| 400 `FlareSolverr: … Timeout` | FlareSolverr не успел решить challenge; повторите запрос, увеличьте `DUB_FETCH_TIMEOUT`, перезапустите FlareSolverr |
| 401 | не передан токен или он отличается от `DUB_API_TOKEN` |
| Контейнер `unhealthy` в первые минуты | модель ещё грузится; `docker logs dub-ai`. Если не проходит — не хватает памяти (`docker stats`) |
| Контейнер `unhealthy` в первые минуты | модель ещё грузится; `docker logs grabber-ai`. Если не проходит — не хватает памяти (`docker stats`) |
| CI: `Cannot connect to the Docker daemon` | у раннера нет доступа к Docker (см. «Что настроить один раз») |
| CI: `server gave HTTP response to HTTPS client` | workflow взял внутренний адрес Gitea; должен быть `REGISTRY_HOST` = `git.shx.one` (уже так в workflow) |
| CI: `unauthorized` при push | у `ACTION_PAT` нет `write:package` или токен принадлежит не владельцу/участник пространства имён репозитория |
+2 -2
View File
@@ -145,7 +145,7 @@ kinozal требует авторизации, поэтому grabber скачи
(`KinozalClient`) и отправляет сервису готовый HTML вместе с заголовком раздачи:
```php
$ch = curl_init('http://dub-ai:8000/predict');
$ch = curl_init('http://grabber-ai:8000/predict');
curl_setopt_array($ch, [
CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
@@ -192,7 +192,7 @@ python -m src.export_onnx # -> models/best-onnx/ + reports/onnx_parit
```bash
cd examples/rust/onnx_local && cargo build
ORT_DYLIB_PATH="$(find ../../.venv -name onnxruntime.dll | head -1)" \
./target/debug/dub-ai-onnx-local.exe ../../models/best-onnx \
./target/debug/grabber-ai-onnx-local.exe ../../models/best-onnx \
"Перевод: Дублированный | MovieDalen"
```
+1 -1
View File
@@ -10,7 +10,7 @@ torch 2.11.0+cu128).
## Установка (один раз)
```bat
cd C:\Users\shats\Dev\DUB-AI
cd C:\Users\shats\Dev\grabber-ai
python -m venv .venv
.venv\Scripts\python -m pip install --upgrade pip