Первоначальная версия VidConf

This commit is contained in:
2026-07-23 01:04:01 +03:00
commit 896455381a
335 changed files with 61527 additions and 0 deletions

526
docs/deploy/env.md Normal file
View File

@@ -0,0 +1,526 @@
# Переменные окружения (.env)
Полный справочник переменных окружения VidConf. Все секреты хранятся **только** в `.env` и никогда не коммитятся в git.
## Соглашение
Значения читаются из файла `.env` (или переменных окружения) при старте приложения. Dev-шаблон см. в `.env.example`.
---
## База данных
### DATABASE_URL
**Тип:** `str` | **Default:** `postgresql+asyncpg://vidconf:vidconf@localhost:5432/vidconf`
**Описание:** Connection string для асинхронного драйвера SQLAlchemy (asyncpg).
**Пример:**
```bash
DATABASE_URL=postgresql+asyncpg://vidconf:vidconf@localhost:5432/vidconf
```
**Проде:** Используйте отдельного пользователя с минимальными привилегиями (только SELECT/INSERT/UPDATE на нужные таблицы).
### POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB
**Для Docker Compose:** переменные инициализации контейнера PostgreSQL.
```bash
POSTGRES_USER=vidconf
POSTGRES_PASSWORD=change-me-secure
POSTGRES_DB=vidconf
```
---
## Redis (очередь Celery)
### REDIS_URL
**Тип:** `str` | **Default:** `redis://localhost:6379/0`
**Описание:** URL Redis для брокера Celery (очередь задач) и кэша сеансов.
**Пример:**
```bash
REDIS_URL=redis://localhost:6379/0
REDIS_URL=redis://:password@redis.example.com:6379/1 # с паролем, БД 1
```
**Проде:** Используйте Redis с паролем и настройте мониторинг/резервные копии.
---
## Конфигурация приложения
### Бутстрап настроек инстанса (первый старт backend, `BOOTSTRAP_*`)
Три переменные определяют начальное состояние настроек модулей при первом
запуске backend. Используются инсталлятором `install.sh` для синхронизации
пресетов поставки (пресеты 15 → матрица `BOOTSTRAP_*`).
#### BOOTSTRAP_CHAT_ENABLED
**Тип:** `bool` (строка: `true` | `false`) | **Default:** `false`
**Описание:** Включить чат в конференциях при первом старте backend.
```bash
BOOTSTRAP_CHAT_ENABLED=false # пресеты 1, 3
BOOTSTRAP_CHAT_ENABLED=true # пресеты 2, 4, 5
```
**Применение:** однократно при первом старте (lifespan backend), затем игнорируется
(настройка хранится в БД, `instance_settings.chat.enabled`). Изменение переменной
на живой инсталляции не действует — меняйте через админ-API `PUT /api/v1/admin/settings`.
---
#### BOOTSTRAP_TRANSCRIPTION_ENABLED
**Тип:** `bool` | **Default:** `false`
**Описание:** Включить транскрибацию и суммаризацию при первом старте backend.
```bash
BOOTSTRAP_TRANSCRIPTION_ENABLED=false # пресеты 1, 2
BOOTSTRAP_TRANSCRIPTION_ENABLED=true # пресеты 3, 4, 5
```
**Применение:** однократно при первом старте (lifespan backend), затем игнорируется.
Выключение транскрибации = AI-уровень не применяется (см. ниже). На живой
инсталляции меняйте через `PUT /api/v1/admin/settings?transcription_enabled=...`.
**Guard:** если транскрибация включена в настройках (`transcription_enabled=true`),
но ни один Celery-воркер `transcriber` не обслуживает очередь, в админке
отображается предупреждение (поле `transcription_queue_served` в ответе
`GET /api/v1/admin/settings`).
---
#### BOOTSTRAP_AI_LEVEL
**Тип:** `str` | **Default:** `min` | **Допустимые:** `min`, `medium`, `max`
**Описание:** Уровень качества AI-обработки при первом старте backend
(требует `BOOTSTRAP_TRANSCRIPTION_ENABLED=true`).
```bash
BOOTSTRAP_AI_LEVEL=min # пресеты 13
BOOTSTRAP_AI_LEVEL=medium # пресет 4
BOOTSTRAP_AI_LEVEL=max # пресет 5
```
**Матрица инсталлятора (пресет → `BOOTSTRAP_*`):**
| Пресет | `BOOTSTRAP_CHAT_ENABLED` | `BOOTSTRAP_TRANSCRIPTION_ENABLED` | `BOOTSTRAP_AI_LEVEL` |
|--------|:---:|:---:|---|
| 1 (MVP) | `false` | `false` | `min` |
| 2 (+чат) | `true` | `false` | `min` |
| 3 (+AI мин) | `true` | `true` | `min` |
| 4 (+AI средний) | `true` | `true` | `medium` |
| 5 (+AI макс) | `true` | `true` | `max` |
**Применение:** однократно при первом старте, затем игнорируется
(настройка в `instance_settings.ai_level`). На живой инсталляции меняйте
через `PUT /api/v1/admin/settings?ai_level=...` (проверяется доступность уровня,
недоступный уровень → 400).
---
### PLUGINS_CONFIG_PATH
**Тип:** `str` | **Default:** `config/plugins.yaml`
**Описание:** Путь к конфигурационному файлу плагинов (от корня проекта или абсолютный).
```bash
PLUGINS_CONFIG_PATH=config/plugins.yaml
```
Содержит профили AI: transcriber (faster-whisper small/medium/large-v3), summarizer (Qwen3.5 4B/9B/35B-A3B), chat (отключён/включён).
---
## Пользователь seed (начальный администратор)
### SEED_ADMIN_EMAIL
**Тип:** `str` | **Default:** `admin@vidconf.example`
**Описание:** Email администратора, создаваемого при инициализации БД (`uv run python -m scripts.seed`, см. [backend/README.md](../../backend/README.md)).
```bash
SEED_ADMIN_EMAIL=admin@example.com
```
### SEED_ADMIN_PASSWORD
**Тип:** `str` | **Default:** `change-me`
**Описание:** Пароль администратора. **Измените на боевом инстансе сразу после развёртывания!**
```bash
SEED_ADMIN_PASSWORD=SuperSecurePassword123!
```
---
## Аутентификация и сессии (JWT)
### JWT_SECRET
**Тип:** `str` | **Default:** `dev-only-insecure-secret-change-me`
**Описание:** Секретный ключ для подписи JWT токенов (HS256).
**Требование:** Минимум 32 символа случайных данных для проде.
```bash
# Генерировать:
# python -c "import secrets; print(secrets.token_urlsafe(32))"
JWT_SECRET=your-long-random-secret-generated-above
```
### ACCESS_TOKEN_TTL_MINUTES
**Тип:** `int` | **Default:** `15`
**Описание:** Срок действия access-токена в минутах.
```bash
ACCESS_TOKEN_TTL_MINUTES=15
```
### REFRESH_TOKEN_TTL_DAYS
**Тип:** `int` | **Default:** `14`
**Описание:** Срок действия refresh-токена в днях. При истечении пользователь должен перелогиниться.
```bash
REFRESH_TOKEN_TTL_DAYS=14
```
### EMAIL_VERIFICATION_TTL_HOURS
**Тип:** `int` | **Default:** `24`
**Описание:** Срок действия email-верификационного токена в часах (при регистрации).
```bash
EMAIL_VERIFICATION_TTL_HOURS=24
```
### AUTH_COOKIE_SECURE
**Тип:** `bool` | **Default:** `true`
**Описание:** Флаг `Secure` для cookies, содержащих refresh-токены.
- **true** (проде) — cookies отправляются только по HTTPS
- **false** (dev на localhost) — cookies отправляются и по HTTP (необходимо для Safari на localhost без HTTPS)
```bash
AUTH_COOKIE_SECURE=false # только для dev
AUTH_COOKIE_SECURE=true # проде обязательно
```
### FRONTEND_URL
**Тип:** `str` | **Default:** `http://localhost:5173`
**Описание:** URL фронтенда. Используется для формирования ссылок в email'ах подтверждения (обычно не требуется, фронтенд за nginx'ом).
```bash
FRONTEND_URL=http://localhost:5173
FRONTEND_URL=https://vidconf.example.com
```
---
## LiveKit SFU
### LIVEKIT_URL
**Тип:** `str` | **Default:** `ws://localhost:7880`
**Описание:** Внутренний server-to-server URL LiveKit (для Celery задач, вызовы RoomService). Не проксируется через Nginx.
```bash
LIVEKIT_URL=ws://localhost:7880
LIVEKIT_URL=http://livekit:7880 # docker-сеть
```
### LIVEKIT_PUBLIC_URL
**Тип:** `str` | **Default:** `ws://localhost:7880`
**Описание:** Публичный URL LiveKit (браузер клиента). Обычно за nginx'ом с TLS.
```bash
LIVEKIT_PUBLIC_URL=ws://localhost:7880 # dev
LIVEKIT_PUBLIC_URL=wss://livekit.example.com # проде (WSS)
```
### LIVEKIT_API_KEY
**Тип:** `str` | **Default:** `devkey`
**Описание:** API ключ LiveKit (для генерации токенов комнат).
```bash
LIVEKIT_API_KEY=your-api-key
```
### LIVEKIT_API_SECRET
**Тип:** `str` | **Default:** `change-me-livekit-secret`
**Описание:** API секрет LiveKit (для подписи токенов).
```bash
LIVEKIT_API_SECRET=your-secret-key
```
Оба найдите в конфигурации LiveKit сервера (`livekit.conf`).
---
## TURN (Coturn)
### TURN_REALM
**Тип:** `str` | **Default:** `vidconf.local`
**Описание:** Realm для TURN сервера (Coturn). Испльзуется в credentials для WebRTC NAT traversal.
```bash
TURN_REALM=vidconf.example.com
```
### TURN_STATIC_AUTH_SECRET
**Тип:** `str` | **Default:** `change-me-turn-secret`
**Описание:** Секрет для TURN сервера (для временных credentials).
```bash
TURN_STATIC_AUTH_SECRET=your-secret-auth-key
```
---
## Аватары
### MEDIA_ROOT
**Тип:** `str` | **Default:** `/app/media`
**Описание:** Абсолютный путь к каталогу хранения загруженных аватаров пользователей.
```bash
MEDIA_ROOT=/app/media # Docker Compose (по умолчанию)
MEDIA_ROOT=/var/lib/vidconf/media # альтернативный путь на сервере
```
**Структура:**
```
MEDIA_ROOT/
└── avatars/
├── 550e8400-e29b-41d4-a716-446655440000.jpg
├── 6ba7b811-9dad-11d1-80b4-00c04fd430c8.png
└── ...
```
**Docker Compose:** том `media` монтируется в backend и nginx. Nginx раздаёт файлы напрямую по `location /media/` в обход backend'а (для performance).
---
## Транскрибация
### RECORDINGS_DIR
**Тип:** `str` | **Default:** `/recordings`
**Описание:** Абсолютный путь к тому с записями (LiveKit Egress пишет .ogg треки сюда, Celery воркер их читает).
```bash
RECORDINGS_DIR=/recordings
RECORDINGS_DIR=/mnt/recordings # альтернативный путь
```
**Docker Compose:** том `recordings` монтируется в обе сервиса (egress, transcriber). Менять путь внутри контейнера обычно не нужно (он совпадает с точкой монтирования).
---
## Email
Все SMTP-реквизиты — **только в `.env`, никогда не попадают в БД или API**.
### EMAIL_BACKEND
**Тип:** `str` | **Default:** `console`
**Допустимые значения:**
- `console` — dev: письма только логируются в stdout, ссылки берутся из логов
- `smtp` — реальная отправка через aiosmtplib
```bash
EMAIL_BACKEND=console # dev
EMAIL_BACKEND=smtp # проде
```
### SMTP_HOST
**Тип:** `str` | **Default:** `localhost`
**Описание:** Хост SMTP сервера (для `EMAIL_BACKEND=smtp`).
```bash
SMTP_HOST=smtp.gmail.com
SMTP_HOST=mail.example.com
```
### SMTP_PORT
**Тип:** `int` | **Default:** `587`
**Описание:** Порт SMTP (обычно 587 для TLS, 465 для SSL, 25 без шифрования).
```bash
SMTP_PORT=587 # TLS (STARTTLS)
SMTP_PORT=465 # SSL
SMTP_PORT=25 # plain
```
### SMTP_USERNAME
**Тип:** `str | None` | **Default:** `None`
**Описание:** Логин SMTP (если требуется аутентификация).
```bash
SMTP_USERNAME=noreply@vidconf.example.com
SMTP_USERNAME=
```
### SMTP_PASSWORD
**Тип:** `str | None` | **Default:** `None`
**Описание:** Пароль SMTP.
```bash
SMTP_PASSWORD=your-app-password
SMTP_PASSWORD=
```
### SMTP_START_TLS
**Тип:** `bool` | **Default:** `true`
**Описание:** Использовать STARTTLS (команда TLS после SMTP HELLO). Обычно для порта 587.
```bash
SMTP_START_TLS=true # порт 587
SMTP_START_TLS=false # если уже SSL или plain
```
### SMTP_USE_TLS
**Тип:** `bool` | **Default:** `false`
**Описание:** Использовать implicit TLS (сразу шифрованное соединение). Обычно для порта 465.
```bash
SMTP_USE_TLS=false # для STARTTLS (587)
SMTP_USE_TLS=true # для implicit TLS (465)
```
### SMTP_FROM
**Тип:** `str` | **Default:** `VidConf <no-reply@vidconf.example>`
**Описание:** From адрес в письмах (имя + email).
```bash
SMTP_FROM=VidConf <no-reply@vidconf.example>
SMTP_FROM=noreply@example.com
```
### SMTP_TIMEOUT_S
**Тип:** `int` | **Default:** `30`
**Описание:** Таймаут SMTP операций в секундах.
```bash
SMTP_TIMEOUT_S=30
```
---
## Примеры конфигурации
### Dev (console backend)
```bash
# Database & Redis
DATABASE_URL=postgresql+asyncpg://vidconf:vidconf@localhost:5432/vidconf
REDIS_URL=redis://localhost:6379/0
# App
PLUGINS_CONFIG_PATH=config/plugins.yaml
JWT_SECRET=dev-only-secret-change-me
FRONTEND_URL=http://localhost:5173
# LiveKit
LIVEKIT_URL=ws://localhost:7880
LIVEKIT_PUBLIC_URL=ws://localhost:7880
LIVEKIT_API_KEY=devkey
LIVEKIT_API_SECRET=...
# Seed
SEED_ADMIN_EMAIL=admin@vidconf.example
SEED_ADMIN_PASSWORD=change-me
# Email (только логирование)
EMAIL_BACKEND=console
# Media (аватары)
MEDIA_ROOT=/app/media
```
### Проде (SMTP, TLS)
```bash
# Database & Redis
DATABASE_URL=postgresql+asyncpg://vidconf:secure-pass@db.example.com:5432/vidconf
REDIS_URL=redis://:redis-password@redis.example.com:6379/0
# App
PLUGINS_CONFIG_PATH=config/plugins.yaml
JWT_SECRET=<generated-long-random-key>
ACCESS_TOKEN_TTL_MINUTES=15
REFRESH_TOKEN_TTL_DAYS=14
AUTH_COOKIE_SECURE=true
FRONTEND_URL=https://vidconf.example.com
# LiveKit
LIVEKIT_URL=http://livekit:7880
LIVEKIT_PUBLIC_URL=wss://livekit.example.com
LIVEKIT_API_KEY=your-key
LIVEKIT_API_SECRET=your-secret
# Seed
SEED_ADMIN_EMAIL=admin@vidconf.example
SEED_ADMIN_PASSWORD=<strong-password>
# Email
EMAIL_BACKEND=smtp
SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_USERNAME=apikey
SMTP_PASSWORD=SG.xxxxx...
SMTP_START_TLS=true
SMTP_USE_TLS=false
SMTP_FROM=VidConf <noreply@vidconf.example>
SMTP_TIMEOUT_S=30
# Media (аватары)
MEDIA_ROOT=/var/lib/vidconf/media
# Recordings
RECORDINGS_DIR=/mnt/recordings
# Transcription
```
---
## Безопасность
1. **Никогда не коммитьте `.env` в git** — используйте `.gitignore`
2. **Регулярно ротируйте JWT_SECRET** (потребует переlogin'ования пользователей)
3. **Используйте окружение для production credentials** (никогда не hardcod'ьте)
4. **Проверьте SMTP_PASSWORD в логах** — их быть не должно (логирование маскирует пароли)
5. **Для SMTP используйте app passwords** (не основной пароль аккаунта)
---
## Ссылки
- [.env.example](../../.env.example) — шаблон переменных для dev
- [backend/core/config.py](../../backend/core/config.py) — парсинг Settings в коде