10 KiB
Текущая ситуация проекта CourseCraft
Документ описывает состояние репозитория и способы запуска (на хосте и в Docker).
Состояние проекта
Монорепозиторий (pnpm workspaces + Turbo)
- apps/api — NestJS API (авторизация, курсы, генерация, платежи, поиск). Порт по умолчанию: 3125.
- apps/web — Next.js 14 (App Router). Порт по умолчанию: 3080.
- apps/ai-service — воркер AI-пайплайна (OpenRouter, BullMQ). Без своего HTTP-порта, подключается к Redis.
- packages/database — Prisma-схема и клиент. Для
prisma db pushнужен свой.envвpackages/database/сDATABASE_URL. - packages/shared — общие типы и константы.
Порты
| Сервис | Порт | Описание |
|---|---|---|
| API | 3125 | Бэкенд, Swagger на /api/docs |
| Web | 3080 | Фронтенд |
| Postgres | 5432 | БД |
| Redis | 6395 | Очереди (на хосте 6395→6379) |
| Meilisearch | 7700 | Поиск |
Переменные окружения
Критичные для работы:
- Supabase:
NEXT_PUBLIC_SUPABASE_URL,NEXT_PUBLIC_SUPABASE_ANON_KEY,SUPABASE_SERVICE_ROLE_KEY - JWT:
JWT_SECRET(подпись токенов после обмена с Supabase) - БД:
DATABASE_URL(PostgreSQL) - Redis:
REDIS_URL,REDIS_HOST,REDIS_PORT - OpenRouter:
OPENROUTER_API_KEY - Meilisearch:
MEILISEARCH_HOST,MEILISEARCH_API_KEY
Корневой .env используется при запуске приложений на хосте и при docker compose (см. ниже).
Запуск: два варианта
1. Всё в Docker (рекомендуется для сервера)
Вся инфраструктура и приложения в контейнерах; после отключения от сервера процессы не падают.
Важно: Compose и .env должны быть в корне проекта. Используется корневой docker-compose.yml (не docker/docker-compose.yml).
Шаги:
cd /usr/local/course-craft-service # или путь к репозиторию
Убедиться, что в корне есть .env с нужными ключами (Supabase, JWT_SECRET и т.д.).
docker compose --env-file .env up -d --build
Или через pnpm (то же самое):
pnpm docker:up
После первого запуска таблицы в БД создаются при старте API (entrypoint делает prisma db push). Данные БД/Redis/Meilisearch лежат в docker/data/.
Проверка:
- Web:
http://<хост>:3080 - API:
http://<хост>:3125/api - Переменные в контейнере API:
docker exec coursecraft-api env | grep -E "JWT_SECRET|SUPABASE"
значения не должны быть пустыми.
Остановка:
docker compose down
Логи:
docker compose logs -f
# или по сервису
docker logs coursecraft-api -f
2. Только инфраструктура в Docker, приложения на хосте
Удобно для разработки: БД, Redis, Meilisearch в Docker; API, Web и AI-service — через pnpm.
Шаги:
-
Поднять только инфраструктуру (если используется корневой compose):
cd /usr/local/course-craft-service docker compose --env-file .env up -d postgres redis meilisearchЛибо старый вариант только инфраструктуры из
docker/(без api, web, ai-service). -
Применить схему БД (один раз или после изменений в Prisma):
В корне должен быть
.envсDATABASE_URL. Для Prisma также нуженpackages/database/.env:echo 'DATABASE_URL="postgresql://postgres:postgres@localhost:5432/coursecraft?schema=public"' > packages/database/.env pnpm db:push -
Запуск приложений:
pnpm startИли в режиме разработки:
pnpm dev
Доступ: Web — 3080, API — 3125 (или как задано в .env: PORT, скрипты next).
Скрипт run.sh (деплой на сервере)
run.sh в корне репозитория:
- Останавливает Docker Compose (старый путь
docker/docker-compose.yml). - Делает
git pull. - Выполняет
pnpm installиpnpm build. - Поднимает Docker Compose.
- В фоне запускает
pnpm start(API, Web, AI-service на хосте).
То есть он смешивает: инфраструктура через Docker, приложения — процессы на хосте. Для «всё в Docker» лучше использовать только docker compose --env-file .env up -d из корня (или pnpm docker:up), без шага с pnpm start.
Важные моменты
-
Корневой
.env
При запускеdocker composeиз корня с--env-file .envпеременные подставляются вdocker-compose.ymlи передаются в контейнеры. Без этого JWT и Supabase в API будут пустыми → 500 на/api/auth/exchangeи т.п. -
Откуда запускать Compose
Запуск только из корня проекта (где лежит.envиdocker-compose.yml). Не из папкиdocker/. -
Prisma в контейнере API
Используется образ на базеnode:20-slim(не Alpine), чтобы не было ошибок сlibssl.so.1.1у нативного движка Prisma. -
Прокси API во фронте
Web обращается к API по относительному пути/api/...; Next.js проксирует запросы на бэкенд (в Docker — на сервисapi:3125). Один билд веба работает при любом хосте. -
Два compose-файла
- Корень:
docker-compose.yml— основной, сenv_file: .envи путями от корня. Использовать его для полного запуска в Docker. - docker/docker-compose.yml — старый вариант (можно оставить для только инфраструктуры или выровнять с корневым при необходимости).
- Корень:
Если в Docker 500 на /api/auth/exchange и /api/courses (а через pnpm run — всё ок)
Чаще всего API в контейнере не получает переменные окружения или получает их с ошибкой (например, из-за Windows).
1. Запуск обязательно с --env-file .env из корня проекта:
cd d:\Github\course-craft-service
docker compose --env-file .env up -d --build
Или через pnpm: pnpm docker:up (если скрипт использует --env-file .env).
2. Проверка переменных в контейнере API:
docker exec coursecraft-api env | findstr "JWT_SECRET SUPABASE DATABASE"
Должны быть непустые JWT_SECRET, NEXT_PUBLIC_SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, DATABASE_URL=postgresql://postgres:postgres@postgres:5432/.... Если что-то пустое — Compose не подхватил .env (запуск не из корня или не указан --env-file .env).
3. Windows: перевод строк в .env
Если .env сохранён с CRLF (Windows), значения могут содержать \r и ломать JWT/подключения. Сохраните .env в кодировке UTF-8 с окончаниями строк LF (в редакторе: «Save with Encoding» → UTF-8, в Git: git config core.autocrlf input и пересохраните файл).
4. Логи API при 500:
После правок при следующей ошибке API при старте покажет явную причину, если не задан JWT_SECRET. Для любых необработанных ошибок смотрите логи:
docker logs coursecraft-api -f
Перед запросом к /api/auth/exchange или /api/courses в логах будет стек или сообщение об ошибке (БД, Supabase, JWT и т.д.).
5. Web должен проксировать на контейнер API
В контейнере web при старте должна быть переменная API_URL=http://api:3125 (задаётся в docker-compose.yml). Тогда Next.js отправляет запросы на сервис api, а не на localhost. Проверка:
docker exec coursecraft-web env | findstr API_URL
Ожидается: API_URL=http://api:3125.
Краткая шпаргалка
| Задача | Команда |
|---|---|
| Всё в Docker | cd <корень> && docker compose --env-file .env up -d или pnpm docker:up |
| Только инфраструктура | docker compose --env-file .env up -d postgres redis meilisearch |
| Схема БД (на хосте) | packages/database/.env с DATABASE_URL, затем pnpm db:push |
| Приложения на хосте | pnpm start или pnpm dev |
| Логи Docker | docker compose logs -f или docker logs coursecraft-api -f |
| Остановить Docker | docker compose down |