PrimeMeet

LiveKit, TURN, TLS и интеграции

Настройка LiveKit, TURN, reverse proxy и TLS, Android/Firebase, Web Push, email/SMS, PrimeResume worker, DeepSeek, LibreOffice и MediaMTX.

После развёртывания backend нужно настроить подсистемы: LiveKit и TURN для медиа, reverse proxy с TLS, push-уведомления, email и SMS, локальный ASR-worker PrimeResume, DeepSeek, LibreOffice и MediaMTX.

Настройка LiveKit

LiveKit отвечает за WebRTC rooms, аудио, видео, screen share, participant state, RoomService и server webhook.

Переменные

LIVEKIT_API_KEY=<key>
LIVEKIT_API_SECRET=<secret>
LIVEKIT_PUBLIC_URL=/livekit
LIVEKIT_API_URL=http://127.0.0.1:7880

Public URL

Frontend должен получать доступный ему WebSocket URL. Reverse proxy должен корректно поддерживать upgrade.

Webhook

Настройте в LiveKit:

POST https://<domain>/internal/livekit/webhook

Backend проверяет подпись через LiveKit WebhookReceiver. Webhook нужен для participant_left, room_finished и синхронизации активных участников.

Проверка

curl -fsS -H "Authorization: Bearer <session>" \
  https://<domain>/api/livekit/status

Проверяйте звонок между двумя разными устройствами и сетями.

Настройка TURN

TURN нужен, когда прямой UDP/WebRTC путь невозможен: корпоративный firewall, мобильный оператор, symmetric NAT, VPN, заблокированный UDP.

Переменные

TURN_HOST=turn.example.com
TURN_TLS_HOST=turn.example.com
TURN_SHARED_SECRET=<secret>
TURN_CREDENTIAL_TTL=21600

Требования

  • публичный IP;
  • корректный external IP;
  • UDP и TCP;
  • TLS certificate;
  • relay port range;
  • firewall;
  • синхронизированное время.

Проверка

Проверьте пары сетей:

  1. Wi-Fi ↔ Wi-Fi.
  2. Wi-Fi ↔ LTE.
  3. LTE ↔ LTE.
  4. VPN ↔ обычная сеть.
  5. UDP blocked → TURN/TLS.

Симптомы отсутствия TURN

  • звонок приходит, но после принятия черный экран;
  • Client initiated disconnect;
  • один участник не слышит другого;
  • работает в одной сети, не работает в другой;
  • ICE остается checking/failed.

Настройка reverse proxy и TLS

Маршруты

Типовая схема:

/          → Node :3000
/ws        → Node WebSocket
/livekit   → LiveKit
/mtx       → MediaMTX

Требования

  • HTTPS;
  • WebSocket upgrade;
  • достаточный body size;
  • длинные timeout для upload;
  • range requests для медиа;
  • корректный client IP;
  • HSTS после проверки.

Лимит загрузки

Proxy body limit должен быть не меньше:

CHAT_FILE_MAX_BYTES=209715200

Учитывайте multipart overhead.

TLS

Проверьте:

curl -Iv https://<domain>
openssl s_client -connect <domain>:443 -servername <domain> </dev/null

Важно. WebRTC permissions в браузере требуют secure context.

Настройка Android и Firebase

Требования

  • JDK 17;
  • Android SDK;
  • Node/npm;
  • Firebase project;
  • google-services.json.

Файлы

mobile/android/app/google-services.json
data/fcm-service-account.json

Оба файла не входят в Git.

Config

{
  "appId": "ru.primemeet.app",
  "appName": "PrimeMeet",
  "server": {
    "url": "https://prime-meet.ru/meet",
    "androidScheme": "https",
    "cleartext": false
  }
}

Сборка

cd mobile
npm ci
npx cap sync android
cd android
./gradlew assembleDebug

APK находится в:

mobile/android/app/build/outputs/apk/debug/

Production signing

Release keystore хранится вне Git, имеет backup, защищен паролем и не меняется между обновлениями. Если подписать новый APK другим ключом, Android не установит его поверх существующего.

Иконка

Для Android используйте adaptive icon: foreground с безопасными полями, background, maskable assets и проверка круглой, квадратной и squircle маски.

Настройка Web Push

Ключи VAPID хранятся в data/vapid.json.

API

GET  /api/push/vapid-key
POST /api/push/register
POST /api/push/unregister

Service worker

frontend/sw.js принимает push, показывает notification, управляет PWA cache, не кэширует /api, /livekit, /ws и использует network-first для HTML.

iOS

Условия работы push на iOS: PWA установлено на экран «Домой», пользователь сам вызвал запрос разрешения, уведомления разрешены в iOS, service worker активен.

Настройка email и SMS

SMTP

SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=<user>
SMTP_PASS=<password>
SMTP_SECURE=false
SMTP_FROM=PrimeMeet <no-reply@example.com>
APP_BASE_URL=https://prime-meet.ru

Используется для подтверждения email, восстановления пароля и приглашений на встречи.

Проверка

Проверьте DNS, SPF, DKIM, DMARC, from address, TLS и spam folder.

SMS

SMS_RU_API_ID=<api-id>

Без провайдера SMS-функция может работать только в dev-режиме согласно текущей реализации.

Настройка PrimeResume worker

Установка

cd workers/whisper
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

Запуск

uvicorn app:app --host 127.0.0.1 --port 8001

Backend:

WHISPER_WORKER_URL=http://127.0.0.1:8001

Engines

Поддерживаются faster-whisper и sherpa.

Faster Whisper

WHISPER_MODEL=small
WHISPER_DEVICE=cpu
WHISPER_COMPUTE=int8
ASR_ENGINE=faster-whisper

Для CUDA:

WHISPER_DEVICE=cuda
WHISPER_COMPUTE=float16

Проверяйте совместимость CUDA, драйвера и ctranslate2.

Локальный русский ASR

ASR_ENGINE=sherpa
SHERPA_MODEL_DIR=./workers/whisper/models/gigaam-v2

Каталог production-модели должен содержать:

encoder.int8.onnx
decoder.onnx
joiner.onnx
tokens.txt

Модели не хранятся в Git.

Диаризация

DIARIZATION_SEGMENTATION_MODEL=./workers/whisper/models/diarization/pyannote-segmentation-3.0/model.int8.onnx
DIARIZATION_EMBEDDING_MODEL=./workers/whisper/models/diarization/nemo_en_titanet_small.onnx
DIARIZATION_CLUSTER_THRESHOLD=0.90
DIARIZATION_SPEAKER_MATCH_THRESHOLD=0.65
DIARIZATION_WINDOW_SECONDS=120
DIARIZATION_WINDOW_OVERLAP_SECONDS=10
DIARIZATION_MIN_SPEAKER_TURN_SECONDS=1.2

Фильтр аудио

ASR_AUDIO_FILTER=highpass=f=70,lowpass=f=7600,afftdn=nf=-40,loudnorm=I=-23:LRA=7:TP=-2
FFMPEG_BIN=/usr/bin/ffmpeg

Systemd

[Unit]
Description=PrimeResume ASR worker
After=network-online.target

[Service]
User=primebroadcast
Group=primebroadcast
WorkingDirectory=/opt/primebroadcast/workers/whisper
EnvironmentFile=/opt/primebroadcast/runtime/env
ExecStart=/opt/primebroadcast/workers/whisper/venv/bin/uvicorn app:app --host 127.0.0.1 --port 8001
Restart=on-failure

[Install]
WantedBy=multi-user.target

Health

curl -fsS http://127.0.0.1:8001/health

Настройка DeepSeek

DeepSeek используется для summary конференции, recap, шаблонов отчетов и генерации отчета.

Переменные

DEEPSEEK_API_KEY=<secret>
DEEPSEEK_MODEL=deepseek-v4-flash
DEEPSEEK_BASE_URL=https://api.deepseek.com

Без ключа

Базовая транскрипция работает; LLM summary/recap/report завершается понятной ошибкой или остается недоступным; приложение не должно падать.

Безопасность

Не логируйте key, не отправляйте лишние персональные данные, документируйте внешнюю обработку, ротируйте key и задайте usage limits.

Настройка файлов и LibreOffice

Пакеты

sudo apt-get install --no-install-recommends \
  libreoffice-core \
  libreoffice-writer \
  libreoffice-calc \
  libreoffice-impress \
  fonts-liberation

Переменные

CHAT_FILE_MAX_BYTES=209715200
CHAT_TEXT_PREVIEW_BYTES=1048576
CHAT_OFFICE_PREVIEW_MAX_BYTES=67108864
OFFICE_PREVIEW_TIMEOUT_MS=90000
LIBREOFFICE_BIN=/usr/bin/libreoffice

Проверка

  1. Отправьте DOCX.
  2. Откройте preview.
  3. Проверьте PDF.
  4. Скачайте оригинал.
  5. Убедитесь, что оригинал не заменен PDF.

Права

Пользователь backend должен иметь запись в:

data/uploads/
data/office-previews/

Настройка MediaMTX

MediaMTX используется для HDMI/RTSP/HLS-сценариев PrimeCast-интеграции.

Подготовка

node scripts/setup-mediamtx.js

Пути

MEDIA_WORK_DIR=./.bin/mediamtx
MEDIA_BINARY_PATH=./.bin/mediamtx/mediamtx
APP_RUNTIME_DIR=./runtime

Internal auth

POST /internal/mediamtx/auth

Proxy

/mtx → MediaMTX WebRTC/HLS

Важно. Не публикуйте control API без защиты.

Дальше — Эксплуатация production.

Обновлено: 3 августа 2026 г.