6.6 KiB
Edu Helper
Веб-приложение для обучения с ИИ: чат, вопросы, учебники, тесты, «Зал» с фотографиями по датам. Два типа пользователей — наставник и ученик (роли и связка наставник ↔ ученик задаются в БД).
Стек
- Frontend: React 19, Vite, TypeScript, Tailwind CSS
- Backend: Node.js, Express, Prisma ORM
- БД: PostgreSQL 16
- ИИ: DeepSeek API (ключ в настройках или переменной окружения)
- Деплой: Docker Compose (один контейнер с API + статикой фронта, отдельно Postgres)
Требования
- Docker и Docker Compose (для продакшен-сборки)
- или Node.js 22+ и локальный PostgreSQL (для разработки без Docker)
Быстрый старт (Docker)
-
Склонируйте репозиторий и перейдите в каталог проекта.
-
Создайте файл
.envв корне репозитория (можно скопировать шаблон):cp .env.docker.example .env -
Отредактируйте
.env:- задайте
JWT_SECRET— длинная случайная строка (не короткий пароль); - задайте
SEED_TUTOR_PASSWORDиSEED_STUDENT_PASSWORD— пароли первых пользователей (создаются только при пустой таблицеUser); - при необходимости укажите
DEEPSEEK_API_KEY; - для работы по HTTPS за прокси выставьте
COOKIE_SECURE=true; для обычного http://localhost оставьтеCOOKIE_SECURE=false, иначе cookie с сессией не установится.
- задайте
-
Запуск:
docker compose up -d --build -
Откройте в браузере: http://localhost:3107 (или порт из
APP_PORTв.env). -
Проверка API:
curl http://localhost:3107/api/health
При первом старте контейнер приложения выполняет prisma migrate deploy и сид пользователей (если пользователей ещё нет).
Windows: exec /docker-entrypoint.sh: no such file or directory
Обычно это CRLF в docker-entrypoint.sh после клонирования на Windows. В репозитории задан .gitattributes (для *.sh — только LF). Обновите репозиторий и пересоберите образ без кэша:
git pull
docker compose build --no-cache app
docker compose up -d
Если проблема осталась: git config core.autocrlf false, затем git add --renormalize . и зафиксируйте изменения или переклонируйте репозиторий; либо в редакторе сохраните docker-entrypoint.sh с окончаниями строк LF (Unix). При сборке образа символы \r в скрипте также удаляются автоматически.
Тома данных
-
pgdata— данные PostgreSQL. Пароль пользователя БД задаётся вPOSTGRES_PASSWORDтолько при первом создании тома. Если сменить пароль в.envпозже, сам PostgreSQL не пересоздаст пароль автоматически — приложение не подключится (ошибка PrismaP1000). Варианты: вернуть в.envстарый пароль, либо сменить пароль вручную в Postgres, либо один раз пересоздать том (данные БД пропадут):docker compose down -v docker compose up -d --build -
uploads— загруженные файлы «Зала».
Локальная разработка (без Docker)
-
Поднимите PostgreSQL и создайте базу (например
edu_helper). -
В каталоге
backendсоздайте.envсDATABASE_URLи остальными переменными по аналогии с корневым.env.docker.example. -
Установка и миграции:
cd backend && npm ci && npx prisma migrate deploy -
Запуск бэкенда (по умолчанию порт 3001):
npm run dev -
В другом терминале — фронт:
cd frontend && npm ci && npm run devVite откроется на http://localhost:5173; запросы к
/apiпроксируются на бэкенд (см.frontend/vite.config.ts).
Корневой скрипт npm run dev (из корня репозитория, после npm install в корне) поднимает backend и frontend одновременно через concurrently.
Структура репозитория
| Путь | Назначение |
|---|---|
frontend/ |
SPA (React + Vite) |
backend/ |
API, Prisma-схема и миграции |
Dockerfile |
Сборка фронта и бэка, один образ Node |
docker-compose.yml |
Сервисы app и db, тома pgdata и uploads |
docker-entrypoint.sh |
Миграции Prisma и сид перед стартом Node |
.env.docker.example |
Шаблон переменных для Docker |
Файл .env в git не коммитится (см. .gitignore).
Переменные окружения (кратко)
| Переменная | Описание |
|---|---|
POSTGRES_* |
Пользователь, пароль и имя БД для контейнера Postgres |
DATABASE_URL |
Строка подключения Prisma (в Docker задаётся из POSTGRES_*) |
JWT_SECRET |
Секрет подписи JWT (обязательно задать) |
SEED_*_USERNAME / SEED_*_PASSWORD |
Логины и пароли для первичного сида |
DEEPSEEK_API_KEY |
Опционально: ключ API по умолчанию |
COOKIE_SECURE |
true только при HTTPS |
APP_PORT |
Проброс порта хоста на контейнер приложения (по умолчанию 3107) |