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:
Jason Preston
2026-08-08 23:56:15 -06:00
parent c59ac7ad0f
commit 2c8e4a536c
2 changed files with 20 additions and 6 deletions
+6 -6
View File
@@ -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
+14
View File
@@ -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);