fix: single container without nginx — Express serves frontend

- Remove separate backend/ and frontend/ Dockerfiles
- Add root Dockerfile (3-stage: frontend build → backend build → runtime)
- Frontend static files served by Express from /public
- Simplify docker-compose to 3 services: mongodb, redis, app (port 3579)
- Fix vite proxy not to strip /api prefix from paths
- Default API URL to relative /api instead of hardcoded localhost

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
MichaelandClaude Haiku 4.5 committed 2026-04-16 10:43:06 +02:00
1 parent a8787857b5
commit 1822ab1afe
9 files changed
+158 -481

No files matched your search

+19 -4
View File
@@ -1,14 +1,18 @@
import express from 'express';
import cors from 'cors';
import 'dotenv/config';
import path from 'path';
import { fileURLToPath } from 'url';
import { connectDB } from './config/database';
import { initRedis, closeRedis } from './config/redis';
import { authenticate, optional } from './middleware/auth';
import { errorHandler, notFoundHandler } from './middleware/errorHandler';
import { errorHandler } from './middleware/errorHandler';
import authRoutes from './routes/authRoutes';
import podcastRoutes from './routes/podcastRoutes';
import episodeRoutes from './routes/episodeRoutes';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const app = express();
const PORT = process.env.PORT || 5000;
@@ -48,8 +52,19 @@ app.use('/api/auth', authRoutes);
app.use('/api/podcasts', podcastRoutes);
app.use('/api/episodes', episodeRoutes);
// 404 handler
app.use(notFoundHandler);
// Serve frontend static files in production
const frontendDist = path.join(__dirname, '..', 'public');
app.use(express.static(frontendDist));
// SPA fallback — return index.html for any non-API route
app.get('*', (req, res) => {
const indexFile = path.join(frontendDist, 'index.html');
res.sendFile(indexFile, (err) => {
if (err) {
res.status(404).json({ success: false, message: 'Not found' });
}
});
});
// Error handler (must be last)
app.use(errorHandler);