From 845245f62ab33151dad683416edee36842c526e6 Mon Sep 17 00:00:00 2001 From: Wajahat Islam Gul Date: Tue, 2 Sep 2025 13:24:38 +0500 Subject: [PATCH 1/6] feat: deploy to render as a monolith --- Dockerfile | 41 +++++++++++++++++++ apps/api-gateway/src/main.ts | 25 ++++++++++- apps/auth-service/src/main.ts | 13 +++++- apps/chat-service/src/main.ts | 19 +++++++++ .../src/controller/order.controller.ts | 2 +- apps/order-service/src/main.ts | 19 +++++++-- apps/product-service/src/main.ts | 13 +++++- ecosystem.config.js | 9 ++++ render.yaml | 19 +++++++++ 9 files changed, 152 insertions(+), 8 deletions(-) create mode 100644 Dockerfile create mode 100644 ecosystem.config.js create mode 100644 render.yaml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..37c1016 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,41 @@ +FROM node:18-alpine AS base +WORKDIR /app + +# Install OS deps for prisma / openssl +RUN apk add --no-cache openssl + +# Copy manifests and sources +COPY package*.json nx.json tsconfig.json tsconfig.base.json ./ +COPY apps ./apps +COPY packages ./packages +COPY prisma ./prisma + +# Install deps +RUN npm ci --legacy-peer-deps + +# Generate prisma client +RUN npx prisma generate + +# Build services +RUN npx nx build api-gateway auth-service product-service order-service chat-service --configuration=production + +# Runtime +FROM node:18-alpine AS runtime +WORKDIR /app +RUN apk add --no-cache openssl + +# Copy built output and minimal files +COPY --from=base /app/apps /app/apps +COPY --from=base /app/node_modules /app/node_modules +COPY --from=base /app/prisma /app/prisma +COPY ecosystem.config.js ./ecosystem.config.js + +ENV NODE_ENV=production +ENV PORT=8080 +EXPOSE 8080 + +RUN npm i -g pm2 + +CMD npx prisma migrate deploy && pm2-runtime ecosystem.config.js + + diff --git a/apps/api-gateway/src/main.ts b/apps/api-gateway/src/main.ts index 18dcf87..1912bdd 100644 --- a/apps/api-gateway/src/main.ts +++ b/apps/api-gateway/src/main.ts @@ -2,6 +2,7 @@ import express from 'express'; import * as path from 'path'; import cors from 'cors'; import proxy from 'express-http-proxy'; +import { createProxyMiddleware } from 'http-proxy-middleware'; import morgan from 'morgan'; import rateLimit from 'express-rate-limit'; import cookieParser from 'cookie-parser'; @@ -11,7 +12,18 @@ const app = express(); app.use( cors({ - origin: ['http://localhost:3000', 'http://localhost:3001'], + origin: (origin, callback) => { + const allowedOriginsEnv = process.env.CORS_ORIGINS || ''; + const allowedOrigins = allowedOriginsEnv + ? allowedOriginsEnv.split(',').map((o) => o.trim()) + : ['http://localhost:3000', 'http://localhost:3001']; + + if (!origin || allowedOrigins.includes(origin)) { + callback(null, true); + } else { + callback(new Error('Not allowed by CORS')); + } + }, allowedHeaders: ['Authorization', 'Content-Type'], credentials: true, }), @@ -44,7 +56,16 @@ app.get('/gateway-health', (req, res) => { app.use('/product', proxy('http://localhost:6002')); //app.use('/seller', proxy('http://localhost:6003')); app.use('/order', proxy('http://localhost:6004')); -app.use('/chat', proxy('http://localhost:6005')); + +// WebSocket proxy for chat-service +app.use( + '/chat', + createProxyMiddleware({ + target: 'http://localhost:6005', + changeOrigin: true, + ws: true, + }), +); app.use('/', proxy('http://localhost:6001')); diff --git a/apps/auth-service/src/main.ts b/apps/auth-service/src/main.ts index ae47428..e99afea 100644 --- a/apps/auth-service/src/main.ts +++ b/apps/auth-service/src/main.ts @@ -12,7 +12,18 @@ const app = express(); app.use( cors({ - origin: ['http://localhost:3000'], + origin: (origin, callback) => { + const allowedOriginsEnv = process.env.CORS_ORIGINS || ''; + const allowedOrigins = allowedOriginsEnv + ? allowedOriginsEnv.split(',').map((o) => o.trim()) + : ['http://localhost:3000']; + + if (!origin || allowedOrigins.includes(origin)) { + callback(null, true); + } else { + callback(new Error('Not allowed by CORS')); + } + }, allowedHeaders: ['Authorization', 'Content-Type'], credentials: true, }), diff --git a/apps/chat-service/src/main.ts b/apps/chat-service/src/main.ts index 3917922..a26dcbf 100644 --- a/apps/chat-service/src/main.ts +++ b/apps/chat-service/src/main.ts @@ -1,10 +1,29 @@ import express from 'express'; +import cors from 'cors'; import cookieParser from 'cookie-parser'; import { startConsumer } from './chat-message.consumer'; import { createWebSocketServer } from './websocket'; import chatRoutes from './routes/chat.routes'; const app = express(); +app.use( + cors({ + origin: (origin, callback) => { + const allowedOriginsEnv = process.env.CORS_ORIGINS || ''; + const allowedOrigins = allowedOriginsEnv + ? allowedOriginsEnv.split(',').map((o) => o.trim()) + : ['http://localhost:3000']; + + if (!origin || allowedOrigins.includes(origin)) { + callback(null, true); + } else { + callback(new Error('Not allowed by CORS')); + } + }, + allowedHeaders: ['Authorization', 'Content-Type'], + credentials: true, + }), +); app.use(express.json()); app.use(cookieParser()); diff --git a/apps/order-service/src/controller/order.controller.ts b/apps/order-service/src/controller/order.controller.ts index d8b2b96..9e4c238 100644 --- a/apps/order-service/src/controller/order.controller.ts +++ b/apps/order-service/src/controller/order.controller.ts @@ -37,7 +37,7 @@ interface VerifySessionRequest extends Request { }; } -interface WebhookRequest extends Request { +export interface WebhookRequest extends Request { headers: { 'stripe-signature': string; }; diff --git a/apps/order-service/src/main.ts b/apps/order-service/src/main.ts index d1c3567..3cb5ea9 100644 --- a/apps/order-service/src/main.ts +++ b/apps/order-service/src/main.ts @@ -2,6 +2,7 @@ import express from 'express'; import cors from 'cors'; import cookieParser from 'cookie-parser'; import bodyParser from 'body-parser'; +import { Request, Response, NextFunction } from 'express'; import { errorMiddleware } from '@packages/error-handler/error-middleware'; import orderRouter from './routes/order.route'; import { createOrder } from './controller/order.controller'; @@ -10,7 +11,18 @@ const app = express(); app.use( cors({ - origin: ['http://localhost:3000'], + origin: (origin, callback) => { + const allowedOriginsEnv = process.env.CORS_ORIGINS || ''; + const allowedOrigins = allowedOriginsEnv + ? allowedOriginsEnv.split(',').map((o) => o.trim()) + : ['http://localhost:3000']; + + if (!origin || allowedOrigins.includes(origin)) { + callback(null, true); + } else { + callback(new Error('Not allowed by CORS')); + } + }, allowedHeaders: ['Authorization', 'Content-Type'], credentials: true, }), @@ -20,11 +32,12 @@ app.use( app.post( '/api/create-order', bodyParser.raw({ type: 'application/json' }), - (req, res, next) => { + (req: Request, res: Response, next: NextFunction) => { (req as any).rawBody = req.body; next(); }, - createOrder, + + (req: Request, res: Response, next: NextFunction) => createOrder(req as any, res, next), ); app.use(express.json({ limit: '200mb' })); diff --git a/apps/product-service/src/main.ts b/apps/product-service/src/main.ts index 754b2ba..28071cc 100644 --- a/apps/product-service/src/main.ts +++ b/apps/product-service/src/main.ts @@ -12,7 +12,18 @@ const app = express(); app.use( cors({ - origin: ['http://localhost:3000'], + origin: (origin, callback) => { + const allowedOriginsEnv = process.env.CORS_ORIGINS || ''; + const allowedOrigins = allowedOriginsEnv + ? allowedOriginsEnv.split(',').map((o) => o.trim()) + : ['http://localhost:3000']; + + if (!origin || allowedOrigins.includes(origin)) { + callback(null, true); + } else { + callback(new Error('Not allowed by CORS')); + } + }, allowedHeaders: ['Authorization', 'Content-Type'], credentials: true, }), diff --git a/ecosystem.config.js b/ecosystem.config.js new file mode 100644 index 0000000..88bc9af --- /dev/null +++ b/ecosystem.config.js @@ -0,0 +1,9 @@ +module.exports = { + apps: [ + { name: 'auth-service', script: 'apps/auth-service/dist/main.js' }, + { name: 'product-service', script: 'apps/product-service/dist/main.js' }, + { name: 'order-service', script: 'apps/order-service/dist/main.js' }, + { name: 'chat-service', script: 'apps/chat-service/dist/main.js' }, + { name: 'api-gateway', script: 'apps/api-gateway/dist/main.js' }, + ], +}; diff --git a/render.yaml b/render.yaml new file mode 100644 index 0000000..63e2011 --- /dev/null +++ b/render.yaml @@ -0,0 +1,19 @@ +services: + - type: web + name: eshop-monolith + env: docker + autoDeploy: true + plan: free + envVars: + - fromGroup: eshop-shared-vars + - key: PORT + value: 8080 + - key: NODE_ENV + value: production + buildFilter: + paths: + - apps/** + - packages/** + - prisma/** + - Dockerfile + - ecosystem.config.js From 01574198dec5726dba3116db43b4da1e2600aff2 Mon Sep 17 00:00:00 2001 From: Wajahat Islam Gul Date: Fri, 5 Sep 2025 11:10:49 +0500 Subject: [PATCH 2/6] fix: fix websockets connection by moving it to a different url --- Dockerfile | 11 ++++-- apps/api-gateway/src/main.ts | 35 ++++++++++++------- .../src/context/websocket-context.tsx | 2 +- apps/user-ui/CHAT_SETUP.md | 2 +- .../user-ui/src/context/websocket-context.tsx | 2 +- docker-compose.yml | 9 +++++ ecosystem.config.js | 30 +++++++++++++--- env.template | 27 ++++++++++++++ render.yaml | 2 -- 9 files changed, 94 insertions(+), 26 deletions(-) create mode 100644 docker-compose.yml create mode 100644 env.template diff --git a/Dockerfile b/Dockerfile index 37c1016..db19b8d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,21 @@ FROM node:18-alpine AS base WORKDIR /app +ENV NPM_CONFIG_AUDIT=false # Install OS deps for prisma / openssl RUN apk add --no-cache openssl # Copy manifests and sources -COPY package*.json nx.json tsconfig.json tsconfig.base.json ./ +COPY package*.json nx.json tsconfig.json tsconfig.base.json eslint.config.mjs ./ COPY apps ./apps COPY packages ./packages COPY prisma ./prisma +# Copy environment file if it exists +COPY .env* ./ + # Install deps -RUN npm ci --legacy-peer-deps +RUN npm ci --legacy-peer-deps --no-audit # Generate prisma client RUN npx prisma generate @@ -28,6 +32,7 @@ RUN apk add --no-cache openssl COPY --from=base /app/apps /app/apps COPY --from=base /app/node_modules /app/node_modules COPY --from=base /app/prisma /app/prisma +COPY --from=base /app/.env* ./ COPY ecosystem.config.js ./ecosystem.config.js ENV NODE_ENV=production @@ -36,6 +41,6 @@ EXPOSE 8080 RUN npm i -g pm2 -CMD npx prisma migrate deploy && pm2-runtime ecosystem.config.js +CMD pm2-runtime ecosystem.config.js diff --git a/apps/api-gateway/src/main.ts b/apps/api-gateway/src/main.ts index 1912bdd..8e31d7e 100644 --- a/apps/api-gateway/src/main.ts +++ b/apps/api-gateway/src/main.ts @@ -1,8 +1,10 @@ -import express from 'express'; +import express, { Request } from 'express'; import * as path from 'path'; import cors from 'cors'; import proxy from 'express-http-proxy'; -import { createProxyMiddleware } from 'http-proxy-middleware'; +import httpProxy from 'http-proxy'; +import { IncomingMessage } from 'http'; +import { Socket } from 'net'; import morgan from 'morgan'; import rateLimit from 'express-rate-limit'; import cookieParser from 'cookie-parser'; @@ -37,11 +39,11 @@ app.set('trust proxy', 1); //Rate limiting const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes - max: (req: any) => (req.user ? 1000 : 1000), // Limit each IP to + max: () => 1000, // Limit each IP to message: { error: 'Too many requests. Please try again later' }, standardHeaders: true, legacyHeaders: true, - keyGenerator: (req: any) => req.ip, + keyGenerator: (req: Request) => req.ip || 'unknown', }); app.use(limiter); @@ -57,15 +59,8 @@ app.use('/product', proxy('http://localhost:6002')); //app.use('/seller', proxy('http://localhost:6003')); app.use('/order', proxy('http://localhost:6004')); -// WebSocket proxy for chat-service -app.use( - '/chat', - createProxyMiddleware({ - target: 'http://localhost:6005', - changeOrigin: true, - ws: true, - }), -); +// Chat HTTP under /chat -> forwards to chat-service /api +app.use('/chat', proxy('http://localhost:6005')); app.use('/', proxy('http://localhost:6001')); @@ -80,4 +75,18 @@ const server = app.listen(port, () => { console.error('Error initializing site config:', error); } }); + +// WS endpoint at /chat-ws -> forwards to chat-service WS root +const wsProxy = httpProxy.createProxyServer({ + target: 'ws://localhost:6005', + changeOrigin: true, + ws: true, +}); + +server.on('upgrade', (req: IncomingMessage, socket: Socket, head: Buffer) => { + if (req.url && req.url.startsWith('/chat-ws')) { + req.url = req.url.replace(/^\/chat-ws/, ''); + wsProxy.ws(req, socket, head); + } +}); server.on('error', console.error); diff --git a/apps/seller-ui/src/context/websocket-context.tsx b/apps/seller-ui/src/context/websocket-context.tsx index 6eb84e2..2e4d51e 100644 --- a/apps/seller-ui/src/context/websocket-context.tsx +++ b/apps/seller-ui/src/context/websocket-context.tsx @@ -49,7 +49,7 @@ export const WebSocketProvider: React.FC = ({ seller, ch useEffect(() => { if (!seller?.id) return; - const wsUri = process.env.NEXT_PUBLIC_CHAT_WEBSOCKET_URI || 'ws://localhost:6005'; + const wsUri = process.env.NEXT_PUBLIC_CHAT_WEBSOCKET_URI || 'ws://localhost:8080/chat'; setIsConnecting(true); setError(null); diff --git a/apps/user-ui/CHAT_SETUP.md b/apps/user-ui/CHAT_SETUP.md index 5afac07..fdcd2e7 100644 --- a/apps/user-ui/CHAT_SETUP.md +++ b/apps/user-ui/CHAT_SETUP.md @@ -6,7 +6,7 @@ Create a `.env.local` file in the `apps/user-ui` directory with the following: ```bash # Chat Service Configuration -NEXT_PUBLIC_CHAT_WEBSOCKET_URI=ws://localhost:6005 +NEXT_PUBLIC_CHAT_WEBSOCKET_URI=ws://localhost:8080/chat ``` ## Features Implemented diff --git a/apps/user-ui/src/context/websocket-context.tsx b/apps/user-ui/src/context/websocket-context.tsx index 6e30527..0b0a8fa 100644 --- a/apps/user-ui/src/context/websocket-context.tsx +++ b/apps/user-ui/src/context/websocket-context.tsx @@ -50,7 +50,7 @@ export const WebSocketProvider: React.FC = ({ user, chil useEffect(() => { if (!user?.id) return; - const wsUri = process.env.NEXT_PUBLIC_CHAT_WEBSOCKET_URI || 'ws://localhost:6005'; + const wsUri = process.env.NEXT_PUBLIC_CHAT_WEBSOCKET_URI || 'ws://localhost:8080/chat'; setIsConnecting(true); setError(null); diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..3f83559 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,9 @@ +services: + eshop-app: + build: . + ports: + - '8080:8080' + env_file: + - .env + environment: + - NODE_ENV=production diff --git a/ecosystem.config.js b/ecosystem.config.js index 88bc9af..e25e42d 100644 --- a/ecosystem.config.js +++ b/ecosystem.config.js @@ -1,9 +1,29 @@ module.exports = { apps: [ - { name: 'auth-service', script: 'apps/auth-service/dist/main.js' }, - { name: 'product-service', script: 'apps/product-service/dist/main.js' }, - { name: 'order-service', script: 'apps/order-service/dist/main.js' }, - { name: 'chat-service', script: 'apps/chat-service/dist/main.js' }, - { name: 'api-gateway', script: 'apps/api-gateway/dist/main.js' }, + { + name: 'auth-service', + script: 'apps/auth-service/dist/main.js', + env: { PORT: 6001 }, + }, + { + name: 'product-service', + script: 'apps/product-service/dist/main.js', + env: { PORT: 6002 }, + }, + { + name: 'order-service', + script: 'apps/order-service/dist/main.js', + env: { PORT: 6004 }, + }, + { + name: 'chat-service', + script: 'apps/chat-service/dist/main.js', + env: { PORT: 6005 }, + }, + { + name: 'api-gateway', + script: 'apps/api-gateway/dist/main.js', + env: { PORT: 8080 }, + }, ], }; diff --git a/env.template b/env.template new file mode 100644 index 0000000..60971ee --- /dev/null +++ b/env.template @@ -0,0 +1,27 @@ +# Database Configuration +DATABASE_URL="mongodb://your-mongodb-host:27017/eshop" +MONGODB_URI="mongodb://your-mongodb-host:27017/eshop" + +# JWT Configuration +JWT_SECRET="your-super-secret-jwt-key-change-this-in-production" +JWT_EXPIRES_IN="7d" + +# Redis Configuration +REDIS_URL="redis://your-redis-host:6379" + +# Kafka Configuration +KAFKA_BROKERS="your-kafka-host:9092" +KAFKA_CLIENT_ID="eshop-app" +KAFKA_GROUP_ID="eshop-group" + +# API Gateway Configuration +API_GATEWAY_PORT=8080 + +# Service Ports +AUTH_SERVICE_PORT=6001 +PRODUCT_SERVICE_PORT=6002 +ORDER_SERVICE_PORT=6004 +CHAT_SERVICE_PORT=6005 + +# Other Configuration +NODE_ENV=production diff --git a/render.yaml b/render.yaml index 63e2011..c011dcf 100644 --- a/render.yaml +++ b/render.yaml @@ -6,8 +6,6 @@ services: plan: free envVars: - fromGroup: eshop-shared-vars - - key: PORT - value: 8080 - key: NODE_ENV value: production buildFilter: From a040c87acccd2dafd9913df6a293d115ccbc5f25 Mon Sep 17 00:00:00 2001 From: Wajahat Islam Gul Date: Fri, 5 Sep 2025 11:22:37 +0500 Subject: [PATCH 3/6] fix: Fix product service not found error on render --- Dockerfile | 2 +- ecosystem.config.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index db19b8d..24354d1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,7 +29,7 @@ WORKDIR /app RUN apk add --no-cache openssl # Copy built output and minimal files -COPY --from=base /app/apps /app/apps +COPY --from=base /app/dist /app/dist COPY --from=base /app/node_modules /app/node_modules COPY --from=base /app/prisma /app/prisma COPY --from=base /app/.env* ./ diff --git a/ecosystem.config.js b/ecosystem.config.js index e25e42d..6334d8b 100644 --- a/ecosystem.config.js +++ b/ecosystem.config.js @@ -2,27 +2,27 @@ module.exports = { apps: [ { name: 'auth-service', - script: 'apps/auth-service/dist/main.js', + script: 'dist/apps/auth-service/main.js', env: { PORT: 6001 }, }, { name: 'product-service', - script: 'apps/product-service/dist/main.js', + script: 'dist/apps/product-service/main.js', env: { PORT: 6002 }, }, { name: 'order-service', - script: 'apps/order-service/dist/main.js', + script: 'dist/apps/order-service/main.js', env: { PORT: 6004 }, }, { name: 'chat-service', - script: 'apps/chat-service/dist/main.js', + script: 'dist/apps/chat-service/main.js', env: { PORT: 6005 }, }, { name: 'api-gateway', - script: 'apps/api-gateway/dist/main.js', + script: 'dist/apps/api-gateway/main.js', env: { PORT: 8080 }, }, ], From a13e0e0a780abbb168e9a870a56e4fa8f23d30ba Mon Sep 17 00:00:00 2001 From: Wajahat Islam Gul Date: Fri, 5 Sep 2025 11:22:37 +0500 Subject: [PATCH 4/6] fix: Fix product service not found error on render --- Dockerfile | 2 +- ecosystem.config.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index db19b8d..24354d1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,7 +29,7 @@ WORKDIR /app RUN apk add --no-cache openssl # Copy built output and minimal files -COPY --from=base /app/apps /app/apps +COPY --from=base /app/dist /app/dist COPY --from=base /app/node_modules /app/node_modules COPY --from=base /app/prisma /app/prisma COPY --from=base /app/.env* ./ diff --git a/ecosystem.config.js b/ecosystem.config.js index e25e42d..6334d8b 100644 --- a/ecosystem.config.js +++ b/ecosystem.config.js @@ -2,27 +2,27 @@ module.exports = { apps: [ { name: 'auth-service', - script: 'apps/auth-service/dist/main.js', + script: 'dist/apps/auth-service/main.js', env: { PORT: 6001 }, }, { name: 'product-service', - script: 'apps/product-service/dist/main.js', + script: 'dist/apps/product-service/main.js', env: { PORT: 6002 }, }, { name: 'order-service', - script: 'apps/order-service/dist/main.js', + script: 'dist/apps/order-service/main.js', env: { PORT: 6004 }, }, { name: 'chat-service', - script: 'apps/chat-service/dist/main.js', + script: 'dist/apps/chat-service/main.js', env: { PORT: 6005 }, }, { name: 'api-gateway', - script: 'apps/api-gateway/dist/main.js', + script: 'dist/apps/api-gateway/main.js', env: { PORT: 8080 }, }, ], From 562428e098d6b6470605af9d71ee9aa3142056ab Mon Sep 17 00:00:00 2001 From: Wajahat Islam Gul Date: Mon, 8 Sep 2025 10:46:34 +0500 Subject: [PATCH 5/6] fix: main.js file not found issue --- Dockerfile | 1 + ecosystem.config.js | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index db19b8d..58d5c00 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,6 +30,7 @@ RUN apk add --no-cache openssl # Copy built output and minimal files COPY --from=base /app/apps /app/apps +COPY --from=base /app/dist /app/dist COPY --from=base /app/node_modules /app/node_modules COPY --from=base /app/prisma /app/prisma COPY --from=base /app/.env* ./ diff --git a/ecosystem.config.js b/ecosystem.config.js index e25e42d..6334d8b 100644 --- a/ecosystem.config.js +++ b/ecosystem.config.js @@ -2,27 +2,27 @@ module.exports = { apps: [ { name: 'auth-service', - script: 'apps/auth-service/dist/main.js', + script: 'dist/apps/auth-service/main.js', env: { PORT: 6001 }, }, { name: 'product-service', - script: 'apps/product-service/dist/main.js', + script: 'dist/apps/product-service/main.js', env: { PORT: 6002 }, }, { name: 'order-service', - script: 'apps/order-service/dist/main.js', + script: 'dist/apps/order-service/main.js', env: { PORT: 6004 }, }, { name: 'chat-service', - script: 'apps/chat-service/dist/main.js', + script: 'dist/apps/chat-service/main.js', env: { PORT: 6005 }, }, { name: 'api-gateway', - script: 'apps/api-gateway/dist/main.js', + script: 'dist/apps/api-gateway/main.js', env: { PORT: 8080 }, }, ], From 3daceab7517d35bae517f65be7f097fcb7b1b992 Mon Sep 17 00:00:00 2001 From: Wajahat Islam Gul Date: Mon, 8 Sep 2025 10:54:00 +0500 Subject: [PATCH 6/6] fix another deployment error --- Dockerfile | 5 ++--- ecosystem.config.js | 10 +++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 58d5c00..f162e34 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,8 +20,8 @@ RUN npm ci --legacy-peer-deps --no-audit # Generate prisma client RUN npx prisma generate -# Build services -RUN npx nx build api-gateway auth-service product-service order-service chat-service --configuration=production +# Build services (all required apps) +RUN npx nx run-many --target=build --projects=api-gateway,auth-service,product-service,order-service,chat-service --configuration=production # Runtime FROM node:18-alpine AS runtime @@ -30,7 +30,6 @@ RUN apk add --no-cache openssl # Copy built output and minimal files COPY --from=base /app/apps /app/apps -COPY --from=base /app/dist /app/dist COPY --from=base /app/node_modules /app/node_modules COPY --from=base /app/prisma /app/prisma COPY --from=base /app/.env* ./ diff --git a/ecosystem.config.js b/ecosystem.config.js index 6334d8b..e25e42d 100644 --- a/ecosystem.config.js +++ b/ecosystem.config.js @@ -2,27 +2,27 @@ module.exports = { apps: [ { name: 'auth-service', - script: 'dist/apps/auth-service/main.js', + script: 'apps/auth-service/dist/main.js', env: { PORT: 6001 }, }, { name: 'product-service', - script: 'dist/apps/product-service/main.js', + script: 'apps/product-service/dist/main.js', env: { PORT: 6002 }, }, { name: 'order-service', - script: 'dist/apps/order-service/main.js', + script: 'apps/order-service/dist/main.js', env: { PORT: 6004 }, }, { name: 'chat-service', - script: 'dist/apps/chat-service/main.js', + script: 'apps/chat-service/dist/main.js', env: { PORT: 6005 }, }, { name: 'api-gateway', - script: 'dist/apps/api-gateway/main.js', + script: 'apps/api-gateway/dist/main.js', env: { PORT: 8080 }, }, ],