diff --git a/backend/Dockerfile b/backend/Dockerfile index 85c489f..123a928 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -17,4 +17,9 @@ COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma EXPOSE 3000 # Используем shell для лучшего логирования ошибок -CMD sh -c "echo '=== Starting Backend ===' && npx prisma migrate deploy && echo '=== Migrations completed ===' && node dist/main" +# Отключаем буферизацию для Node.js чтобы логи сразу видны +ENV NODE_ENV=production +ENV NODE_NO_WARNINGS=1 + +# Явно выводим логи в stdout/stderr без буферизации +CMD sh -c "echo '========================================' && echo '=== STARTING BACKEND ===' && echo '========================================' && npx prisma migrate deploy && echo '=== MIGRATIONS COMPLETED ===' && exec node --no-warnings dist/main" diff --git a/backend/src/main.ts b/backend/src/main.ts index 322dfc8..d1165d2 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -4,6 +4,16 @@ import { ConfigService } from '@nestjs/config'; import { AppModule } from './app.module'; async function bootstrap() { + // Принудительно выводим в stdout и stderr для Docker/Coolify + const log = (message: string) => { + console.log(message); + console.error(`[LOG] ${message}`); // Дублируем в stderr для надежности + }; + + log('========================================'); + log('=== BACKEND STARTING ==='); + log('========================================'); + const app = await NestFactory.create(AppModule); const configService = app.get(ConfigService); @@ -11,30 +21,37 @@ async function bootstrap() { const corsOrigin = configService.get('CORS_ORIGIN') || 'http://localhost:5173'; const allowedOrigins = corsOrigin.split(',').map(origin => origin.trim()); - console.log('=== Backend Starting ==='); - console.log(`CORS_ORIGIN from env: ${configService.get('CORS_ORIGIN') || 'NOT SET (using default)'}`); - console.log(`CORS allowed origins: ${allowedOrigins.join(', ')}`); + log(`CORS_ORIGIN from env: ${configService.get('CORS_ORIGIN') || 'NOT SET (using default)'}`); + log(`CORS allowed origins: ${allowedOrigins.join(', ')}`); app.enableCors({ origin: (origin, callback) => { // Логируем все входящие запросы - console.log(`[CORS] Request from origin: ${origin || 'NO ORIGIN (direct request)'}`); + const logMsg = `[CORS] Request from origin: ${origin || 'NO ORIGIN (direct request)'}`; + console.log(logMsg); + console.error(logMsg); // Дублируем в stderr // Разрешаем запросы без origin (например, Postman, мобильные приложения) if (!origin) { - console.log(`[CORS] Allowing request without origin`); + const allowMsg = `[CORS] Allowing request without origin`; + console.log(allowMsg); + console.error(allowMsg); return callback(null, true); } // Проверяем, есть ли origin в списке разрешенных if (allowedOrigins.includes(origin)) { - console.log(`[CORS] ✓ Allowed origin: ${origin}`); + const allowedMsg = `[CORS] ✓ Allowed origin: ${origin}`; + console.log(allowedMsg); + console.error(allowedMsg); return callback(null, true); } // Логируем отклоненные запросы для отладки - console.error(`[CORS] ✗ BLOCKED origin: ${origin}`); - console.error(`[CORS] Allowed origins are: ${allowedOrigins.join(', ')}`); + const blockedMsg = `[CORS] ✗ BLOCKED origin: ${origin}`; + const allowedListMsg = `[CORS] Allowed origins are: ${allowedOrigins.join(', ')}`; + console.error(blockedMsg); + console.error(allowedListMsg); return callback(new Error('Not allowed by CORS')); }, credentials: true, @@ -44,7 +61,9 @@ async function bootstrap() { // Добавляем middleware для логирования всех запросов app.use((req, res, next) => { - console.log(`[${new Date().toISOString()}] ${req.method} ${req.path} - Origin: ${req.headers.origin || 'NO ORIGIN'}`); + const requestLog = `[${new Date().toISOString()}] ${req.method} ${req.path} - Origin: ${req.headers.origin || 'NO ORIGIN'}`; + console.log(requestLog); + console.error(requestLog); // Дублируем в stderr next(); }); @@ -57,26 +76,34 @@ async function bootstrap() { const host = configService.get('HOST') || '0.0.0.0'; try { + log(`Attempting to start server on ${host}:${port}...`); await app.listen(port, host); - console.log(`=== Backend Started Successfully ===`); - console.log(`Backend running on http://${host}:${port}`); - console.log(`CORS allowed origins: ${allowedOrigins.join(', ')}`); - console.log(`Environment variables:`); - console.log(` - DATABASE_URL: ${configService.get('DATABASE_URL') ? 'SET' : 'NOT SET'}`); - console.log(` - JWT_SECRET: ${configService.get('JWT_SECRET') ? 'SET' : 'NOT SET'}`); - console.log(` - PORT: ${port}`); - console.log(` - HOST: ${host}`); - console.log(` - CORS_ORIGIN: ${corsOrigin}`); + + log('========================================'); + log('=== BACKEND STARTED SUCCESSFULLY ==='); + log('========================================'); + log(`Backend running on http://${host}:${port}`); + log(`CORS allowed origins: ${allowedOrigins.join(', ')}`); + log(`Environment variables:`); + log(` - DATABASE_URL: ${configService.get('DATABASE_URL') ? 'SET' : 'NOT SET'}`); + log(` - JWT_SECRET: ${configService.get('JWT_SECRET') ? 'SET' : 'NOT SET'}`); + log(` - PORT: ${port}`); + log(` - HOST: ${host}`); + log(` - CORS_ORIGIN: ${corsOrigin}`); + log('========================================'); + log('Backend is ready to accept requests!'); + log('========================================'); } catch (error) { - console.error(`=== Backend Failed to Start ===`); - console.error(`Error: ${error.message}`); - console.error(error); + const errorMsg = `=== Backend Failed to Start ===\nError: ${error.message}\n${error.stack}`; + console.error(errorMsg); + process.stderr.write(errorMsg + '\n'); process.exit(1); } } bootstrap().catch((error) => { - console.error('=== Fatal Error During Bootstrap ==='); - console.error(error); + const fatalError = `=== Fatal Error During Bootstrap ===\n${error.message}\n${error.stack}`; + console.error(fatalError); + process.stderr.write(fatalError + '\n'); process.exit(1); });