Приватный мессенджер, который можно поднять на своём компьютере или VPS: личные и групповые чаты, каналы, реакции, вложения, E2E-шифрование на клиенте, звонки через WebRTC, dead drops и лента постов.
| Слой | Технологии |
|---|---|
| Бэкенд | FastAPI, SQLAlchemy 2 (async), Alembic, PostgreSQL, Redis pub/sub, WebSocket |
| Фронтенд | React 18, TypeScript, Vite, Tailwind, IndexedDB (ключи E2E) |
| Шифрование | ECDH P-256 + AES-GCM (WebCrypto), приватный ключ не покидает браузер |
| Инфраструктура | Docker Compose, nginx (TLS), самоподписанный сертификат, S3/MinIO или локальный диск |
Нужен Docker Desktop и свободные порты 5173, 8000, 5432, 6379.
# 1. Конфиг
cp backend/.env.example backend/.env
python -c "import secrets; print('SECRET_KEY=' + secrets.token_hex(32))" >> backend/.env
# 2. Стек (api сам применит миграции при старте)
docker compose -f infra/docker-compose.yml up --buildКогда api поднялся — заполнить демо-данными (второй терминал):
docker compose -f infra/docker-compose.yml exec api python seed.pyОткрыть http://localhost:5173, API и Swagger — http://localhost:8000/docs.
Скрипт backend/seed.py создаёт вымышленных пользователей и переписку:
| Кто | Логин | Пароль |
|---|---|---|
| Алиса | alice |
demo12345 |
| Боб | bob |
demo12345 |
| Кэрол | carol |
demo12345 |
| Дэйв | dave |
demo12345 |
- чат «Общий» (Алиса, Боб, Кэрол) — 9 сообщений, реакции;
- личный чат Алиса ↔ Боб — 6 сообщений;
- два вложения-заглушки:
demo-pixel.pngиdemo-readme.txt(генерируются скриптом).
Скрипт идемпотентен: повторный запуск ничего не дублирует.
База данных не входит в репозиторий — она создаётся при первом запуске в томе pgdata.
Полный сброс: docker compose -f infra/docker-compose.yml down -v (удалит и вложения).
- личные и групповые чаты, каналы, лента постов, карта сети;
- реакции, ответы, правки, удаления, закрепление;
- вложения: фото, файлы, голосовые (S3 или локальный
UPLOAD_DIR); - E2E-шифрование: ключ чата раздаёт владелец, приватный ключ устройства — в IndexedDB;
- звонки WebRTC: оффер после
call:accepted, буферизация входящего оффера, шаринг экрана; - идемпотентная отправка (
messages.client_id+ дедуп на сервере); - доступ к вложениям: прикрепить можно только собственный файл;
- запуск на домашнем ПК с HTTPS:
powershell -ExecutionPolicy Bypass -File infra\host-start.ps1.
- вложения не шифруются — E2E только для текста;
- поиск по зашифрованному чату отключён;
- нет мобильного клиента и push-уведомлений;
- нет CI: проверки ручные (
ruff,pytest,tsc); - E2E: очистка данных сайта = потеря доступа к старым сообщениям (ключ в IndexedDB).
cd backend
pip install -e ".[test]"
pytest
ruff check app tests alembic
cd ../frontend
npm ci
npm run typecheck
npm run buildbackend/
app/ FastAPI: 13 роутеров, модели, WebSocket, воркеры
alembic/ 14 миграций
tests/ pytest
seed.py демо-данные
frontend/
src/ React + TypeScript
infra/
docker-compose.yml локальный стек
docker-compose.prod.yml прод с HTTPS
DEPLOY.md деплой на VPS
host-start.ps1 локальный HTTPS-хостинг
.env, сертификаты,uploads/,*.db— в.gitignore;- токены и ключи только в переменных окружения, в коде значений нет;
S3_ENABLED=falseпо умолчанию: файлы лежат локально;- пароль демо-аккаунтов — только для локального стенда, для публичного инстанса смените.
- VPS с HTTPS — infra/DEPLOY.md;
- домашний ПК с доступом по VPN —
infra/host-start.ps1иinfra/host-check.ps1.