Files
course-craft-service/situation.md
2026-02-06 11:52:30 +03:00

10 KiB
Raw Permalink Blame History

Текущая ситуация проекта 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.

Шаги:

  1. Поднять только инфраструктуру (если используется корневой compose):

    cd /usr/local/course-craft-service
    docker compose --env-file .env up -d postgres redis meilisearch
    

    Либо старый вариант только инфраструктуры из docker/ (без api, web, ai-service).

  2. Применить схему БД (один раз или после изменений в 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
    
  3. Запуск приложений:

    pnpm start
    

    Или в режиме разработки:

    pnpm dev
    

Доступ: Web — 3080, API — 3125 (или как задано в .env: PORT, скрипты next).


Скрипт run.sh (деплой на сервере)

run.sh в корне репозитория:

  1. Останавливает Docker Compose (старый путь docker/docker-compose.yml).
  2. Делает git pull.
  3. Выполняет pnpm install и pnpm build.
  4. Поднимает Docker Compose.
  5. В фоне запускает pnpm start (API, Web, AI-service на хосте).

То есть он смешивает: инфраструктура через Docker, приложения — процессы на хосте. Для «всё в Docker» лучше использовать только docker compose --env-file .env up -d из корня (или pnpm docker:up), без шага с pnpm start.


Важные моменты

  1. Корневой .env
    При запуске docker compose из корня с --env-file .env переменные подставляются в docker-compose.yml и передаются в контейнеры. Без этого JWT и Supabase в API будут пустыми → 500 на /api/auth/exchange и т.п.

  2. Откуда запускать Compose
    Запуск только из корня проекта (где лежит .env и docker-compose.yml). Не из папки docker/.

  3. Prisma в контейнере API
    Используется образ на базе node:20-slim (не Alpine), чтобы не было ошибок с libssl.so.1.1 у нативного движка Prisma.

  4. Прокси API во фронте
    Web обращается к API по относительному пути /api/...; Next.js проксирует запросы на бэкенд (в Docker — на сервис api:3125). Один билд веба работает при любом хосте.

  5. Два 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