diff --git a/Dockerfile b/Dockerfile index d1f1adc..7c65995 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,16 @@ # Stage 1: Build client FROM node:20-alpine AS client-build WORKDIR /app/client -COPY client/package.json client/package-lock.json* ./ -RUN npm ci +COPY client/package.json ./ +RUN npm install COPY client/ ./ RUN npm run build # Stage 2: Build server FROM node:20-alpine AS server-build WORKDIR /app/server -COPY server/package.json server/package-lock.json* ./ -RUN npm ci +COPY server/package.json ./ +RUN npm install COPY server/ ./ RUN npm run build @@ -25,8 +25,8 @@ RUN addgroup -g 1001 -S appgroup && \ adduser -S appuser -u 1001 -G appgroup # Copy server production dependencies -COPY server/package.json server/package-lock.json* ./ -RUN npm ci --omit=dev && npm cache clean --force +COPY server/package.json ./ +RUN npm install --omit=dev && npm cache clean --force # Copy server build output COPY --from=server-build /app/server/dist ./dist diff --git a/server/src/index.ts b/server/src/index.ts index 4c5d69c..91f77e5 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -1,5 +1,7 @@ import express from 'express'; import cors from 'cors'; +import path from 'path'; +import { fileURLToPath } from 'url'; import { createServer } from 'http'; import { config } from './config.js'; import { closeDb } from './db/index.js'; @@ -10,6 +12,8 @@ import authRoutes from './routes/auth.js'; import connectionsRoutes from './routes/connections.js'; import messagesRoutes from './routes/messages.js'; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + const app = express(); app.use(cors({ origin: config.CORS_ORIGIN, credentials: true })); @@ -23,6 +27,16 @@ app.use('/api/auth', authRoutes); app.use('/api/connections', connectionsRoutes); app.use('/api/messages', messagesRoutes); +// Serve static frontend in production +const publicPath = path.resolve(__dirname, '../public'); +app.use(express.static(publicPath)); +app.get('*', (_req, res, next) => { + if (_req.path.startsWith('/api') || _req.path.startsWith('/ws')) { + return next(); + } + res.sendFile(path.join(publicPath, 'index.html')); +}); + const server = createServer(app); createWebSocketServer(server);