fix: use npm install in Dockerfile, add static file serving
- Dockerfile uses npm install (no lockfile yet, kaniko builds in-cluster) - Server serves client build from ./public in production - SPA fallback for client-side routing
This commit is contained in:
+6
-6
@@ -1,16 +1,16 @@
|
|||||||
# Stage 1: Build client
|
# Stage 1: Build client
|
||||||
FROM node:20-alpine AS client-build
|
FROM node:20-alpine AS client-build
|
||||||
WORKDIR /app/client
|
WORKDIR /app/client
|
||||||
COPY client/package.json client/package-lock.json* ./
|
COPY client/package.json ./
|
||||||
RUN npm ci
|
RUN npm install
|
||||||
COPY client/ ./
|
COPY client/ ./
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
# Stage 2: Build server
|
# Stage 2: Build server
|
||||||
FROM node:20-alpine AS server-build
|
FROM node:20-alpine AS server-build
|
||||||
WORKDIR /app/server
|
WORKDIR /app/server
|
||||||
COPY server/package.json server/package-lock.json* ./
|
COPY server/package.json ./
|
||||||
RUN npm ci
|
RUN npm install
|
||||||
COPY server/ ./
|
COPY server/ ./
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
@@ -25,8 +25,8 @@ RUN addgroup -g 1001 -S appgroup && \
|
|||||||
adduser -S appuser -u 1001 -G appgroup
|
adduser -S appuser -u 1001 -G appgroup
|
||||||
|
|
||||||
# Copy server production dependencies
|
# Copy server production dependencies
|
||||||
COPY server/package.json server/package-lock.json* ./
|
COPY server/package.json ./
|
||||||
RUN npm ci --omit=dev && npm cache clean --force
|
RUN npm install --omit=dev && npm cache clean --force
|
||||||
|
|
||||||
# Copy server build output
|
# Copy server build output
|
||||||
COPY --from=server-build /app/server/dist ./dist
|
COPY --from=server-build /app/server/dist ./dist
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import express from 'express';
|
import express from 'express';
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
|
import path from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
import { createServer } from 'http';
|
import { createServer } from 'http';
|
||||||
import { config } from './config.js';
|
import { config } from './config.js';
|
||||||
import { closeDb } from './db/index.js';
|
import { closeDb } from './db/index.js';
|
||||||
@@ -10,6 +12,8 @@ import authRoutes from './routes/auth.js';
|
|||||||
import connectionsRoutes from './routes/connections.js';
|
import connectionsRoutes from './routes/connections.js';
|
||||||
import messagesRoutes from './routes/messages.js';
|
import messagesRoutes from './routes/messages.js';
|
||||||
|
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
app.use(cors({ origin: config.CORS_ORIGIN, credentials: true }));
|
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/connections', connectionsRoutes);
|
||||||
app.use('/api/messages', messagesRoutes);
|
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);
|
const server = createServer(app);
|
||||||
|
|
||||||
createWebSocketServer(server);
|
createWebSocketServer(server);
|
||||||
|
|||||||
Reference in New Issue
Block a user