# Переменные окружения (.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_PASSWORD **Тип:** `str` | **Обязателен** (нет дефолта — `${REDIS_PASSWORD:?}` в `deploy/docker-compose.yml`) **Описание:** Пароль Redis (`--requirepass`). Без него `docker compose up` не стартует — намеренно: инцидент безопасности на этом проекте начался именно с redis без пароля, опубликованного наружу (см. `.forcc/deploy/SESSION2-FINDINGS.md` во внутренних заметках сессии деплоя). `install.sh` генерирует случайное значение при первой установке. Используется backend/worker/livekit/egress — все читают его через `REDIS_URL`/секцию `redis:` своих конфигов, генерируемых из `.env` (см. `deploy/render-templates.sh`). **Пример:** ```bash REDIS_PASSWORD=a1b2c3... ``` ### REDIS_URL **Тип:** `str` | **Default:** `redis://localhost:6379/0` **Описание:** URL Redis для брокера Celery (очередь задач) и кэша сеансов. Значим только при запуске backend/worker НА ХОСТЕ вне docker-сети — внутри контейнеров `docker-compose.yml` всегда подставляет `redis://:${REDIS_PASSWORD}@redis:6379/0` сам, это значение игнорируя. **Пример:** ```bash REDIS_URL=redis://:password@localhost:6379/0 REDIS_URL=redis://:password@redis.example.com:6379/1 # с паролем, БД 1 ``` **Проде:** Redis публикуется только на `127.0.0.1` (loopback) — снаружи недоступен даже с паролем; удалённый доступ — через ssh-туннель. --- ## Конфигурация приложения ### Бутстрап настроек инстанса (первый старт backend, `BOOTSTRAP_*`) Три переменные определяют начальное состояние настроек модулей при первом запуске backend. Используются инсталлятором `install.sh` для синхронизации пресетов поставки (пресеты 1–5 → матрица `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 # пресеты 1–3 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 ` **Описание:** From адрес в письмах (имя + email). ```bash SMTP_FROM=VidConf 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_PASSWORD=change-me-redis-secret REDIS_URL=redis://:change-me-redis-secret@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_PASSWORD=redis-password REDIS_URL=redis://:redis-password@redis.example.com:6379/0 # App PLUGINS_CONFIG_PATH=config/plugins.yaml JWT_SECRET= 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= # 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 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 в коде