This commit is contained in:
2026-02-06 12:15:43 +03:00
parent d654b1ffc8
commit 6d96372682
7 changed files with 60 additions and 11 deletions

6
.gitattributes vendored Normal file
View File

@ -0,0 +1,6 @@
# Force LF line endings for shell scripts (critical for Docker)
*.sh text eol=lf
docker/entrypoint-*.sh text eol=lf
# Default behavior
* text=auto

View File

@ -15,14 +15,16 @@ async function bootstrap() {
// Security // Security
app.use(helmet()); app.use(helmet());
// CORS (веб на 3080) // CORS — allow the web frontend origin (from NEXT_PUBLIC_APP_URL) + localhost for dev
const appUrl = configService.get('NEXT_PUBLIC_APP_URL');
const allowedOrigins = [ const allowedOrigins = [
configService.get('NEXT_PUBLIC_APP_URL'), ...new Set(
'http://localhost:3080', [appUrl, 'http://localhost:3080', 'http://localhost:3000'].filter(Boolean) as string[],
'http://localhost:3000', ),
].filter(Boolean) as string[]; ];
console.log('CORS allowed origins:', allowedOrigins);
app.enableCors({ app.enableCors({
origin: allowedOrigins.length ? allowedOrigins : 'http://localhost:3080', origin: allowedOrigins,
credentials: true, credentials: true,
}); });

View File

@ -72,6 +72,7 @@ services:
SUPABASE_SERVICE_ROLE_KEY: ${SUPABASE_SERVICE_ROLE_KEY} SUPABASE_SERVICE_ROLE_KEY: ${SUPABASE_SERVICE_ROLE_KEY}
NEXT_PUBLIC_SUPABASE_URL: ${NEXT_PUBLIC_SUPABASE_URL} NEXT_PUBLIC_SUPABASE_URL: ${NEXT_PUBLIC_SUPABASE_URL}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${NEXT_PUBLIC_SUPABASE_ANON_KEY} NEXT_PUBLIC_SUPABASE_ANON_KEY: ${NEXT_PUBLIC_SUPABASE_ANON_KEY}
NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-http://localhost:3080}
ports: ports:
- "3125:3125" - "3125:3125"
depends_on: depends_on:
@ -100,11 +101,15 @@ services:
dockerfile: docker/Dockerfile.web dockerfile: docker/Dockerfile.web
args: args:
API_URL: http://api:3125 API_URL: http://api:3125
NEXT_PUBLIC_SUPABASE_URL: ${NEXT_PUBLIC_SUPABASE_URL}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${NEXT_PUBLIC_SUPABASE_ANON_KEY}
NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-http://localhost:3080}
container_name: coursecraft-web container_name: coursecraft-web
restart: unless-stopped restart: unless-stopped
env_file: .env env_file: .env
environment: environment:
API_URL: http://api:3125 API_URL: http://api:3125
NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-http://localhost:3080}
PORT: "3080" PORT: "3080"
NODE_ENV: production NODE_ENV: production
ports: ports:

View File

@ -1,5 +1,8 @@
FROM node:20-slim FROM node:20-slim
# Prisma Query Engine needs OpenSSL shared libraries
RUN apt-get update -y && apt-get install -y openssl && rm -rf /var/lib/apt/lists/*
RUN corepack enable && corepack prepare pnpm@9.0.0 --activate RUN corepack enable && corepack prepare pnpm@9.0.0 --activate
WORKDIR /app WORKDIR /app
@ -18,7 +21,7 @@ COPY . .
RUN pnpm build --filter=@coursecraft/api... RUN pnpm build --filter=@coursecraft/api...
COPY docker/entrypoint-api.sh /entrypoint.sh COPY docker/entrypoint-api.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh RUN sed -i 's/\r$//' /entrypoint.sh && chmod +x /entrypoint.sh
EXPOSE 3125 EXPOSE 3125
CMD ["/entrypoint.sh"] CMD ["/entrypoint.sh"]

View File

@ -1,5 +1,8 @@
FROM node:20-slim FROM node:20-slim
# OpenSSL for potential native dependencies
RUN apt-get update -y && apt-get install -y openssl && rm -rf /var/lib/apt/lists/*
RUN corepack enable && corepack prepare pnpm@9.0.0 --activate RUN corepack enable && corepack prepare pnpm@9.0.0 --activate
WORKDIR /app WORKDIR /app
@ -15,9 +18,16 @@ RUN pnpm install --frozen-lockfile
COPY . . COPY . .
# API_URL нужен на этапе сборки: Next.js «запекает» rewrites в билд # These are needed at build time: Next.js inlines NEXT_PUBLIC_* into client bundle
ARG API_URL=http://api:3125 ARG API_URL=http://api:3125
ARG NEXT_PUBLIC_SUPABASE_URL
ARG NEXT_PUBLIC_SUPABASE_ANON_KEY
ARG NEXT_PUBLIC_APP_URL=http://localhost:3080
ENV API_URL=${API_URL} ENV API_URL=${API_URL}
ENV NEXT_PUBLIC_SUPABASE_URL=${NEXT_PUBLIC_SUPABASE_URL}
ENV NEXT_PUBLIC_SUPABASE_ANON_KEY=${NEXT_PUBLIC_SUPABASE_ANON_KEY}
ENV NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL}
RUN pnpm build --filter=@coursecraft/web... RUN pnpm build --filter=@coursecraft/web...

View File

@ -65,11 +65,11 @@ services:
MEILISEARCH_HOST: http://meilisearch:7700 MEILISEARCH_HOST: http://meilisearch:7700
PORT: "3125" PORT: "3125"
NODE_ENV: production NODE_ENV: production
# Явно из хостового .env (подставляются при docker compose up из текущей папки)
JWT_SECRET: ${JWT_SECRET} JWT_SECRET: ${JWT_SECRET}
SUPABASE_SERVICE_ROLE_KEY: ${SUPABASE_SERVICE_ROLE_KEY} SUPABASE_SERVICE_ROLE_KEY: ${SUPABASE_SERVICE_ROLE_KEY}
NEXT_PUBLIC_SUPABASE_URL: ${NEXT_PUBLIC_SUPABASE_URL} NEXT_PUBLIC_SUPABASE_URL: ${NEXT_PUBLIC_SUPABASE_URL}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${NEXT_PUBLIC_SUPABASE_ANON_KEY} NEXT_PUBLIC_SUPABASE_ANON_KEY: ${NEXT_PUBLIC_SUPABASE_ANON_KEY}
NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-http://localhost:3080}
ports: ports:
- "3125:3125" - "3125:3125"
depends_on: depends_on:
@ -96,11 +96,17 @@ services:
build: build:
context: .. context: ..
dockerfile: docker/Dockerfile.web dockerfile: docker/Dockerfile.web
args:
API_URL: http://api:3125
NEXT_PUBLIC_SUPABASE_URL: ${NEXT_PUBLIC_SUPABASE_URL}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${NEXT_PUBLIC_SUPABASE_ANON_KEY}
NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-http://localhost:3080}
container_name: coursecraft-web container_name: coursecraft-web
restart: unless-stopped restart: unless-stopped
env_file: ../.env env_file: ../.env
environment: environment:
API_URL: http://api:3125 API_URL: http://api:3125
NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-http://localhost:3080}
PORT: "3080" PORT: "3080"
NODE_ENV: production NODE_ENV: production
ports: ports:

View File

@ -1,5 +1,22 @@
#!/bin/sh #!/bin/sh
set -e set -e
# Синхронизация схемы БД при старте (таблицы создадутся, если их ещё нет)
cd /app/packages/database && npx prisma db push --skip-generate --accept-data-loss 2>/dev/null || true echo "=== CourseCraft API Entrypoint ==="
echo "DATABASE_URL is set: $([ -n "$DATABASE_URL" ] && echo 'yes' || echo 'NO — this will fail!')"
echo "REDIS_HOST=$REDIS_HOST REDIS_PORT=$REDIS_PORT"
# Ensure PostgreSQL extensions exist (idempotent)
echo "Ensuring PostgreSQL extensions..."
cd /app/packages/database
npx prisma db execute --stdin <<'SQL' || echo "WARNING: extension creation returned non-zero (may already exist)"
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS vector;
SQL
# Push Prisma schema (create/update tables)
echo "Running prisma db push..."
npx prisma db push --skip-generate --accept-data-loss
echo "Prisma db push completed successfully."
echo "Starting API server..."
cd /app && exec node apps/api/dist/main.js cd /app && exec node apps/api/dist/main.js