fix: serve frontend in production — multi-stage Dockerfile with Node build + StaticFiles mount
- Dockerfile: add Node.js frontend build stage (vite build) - Dockerfile: copy frontend/dist into runtime image - app/main.py: mount /assets static files + SPA catch-all fallback - app/main.py: serve index.html for all non-API routes - Fixes: https://crm.media-on.de/ returning 404 (frontend not served)
This commit is contained in:
+25
-1
@@ -6,9 +6,12 @@ import time
|
||||
import traceback
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi import FastAPI, HTTPException, Request
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import FileResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from starlette.middleware.base import BaseHTTPMiddleware
|
||||
import os
|
||||
|
||||
from app.config import get_settings
|
||||
from app.core.db import close_engine, get_engine
|
||||
@@ -123,6 +126,27 @@ def create_app() -> FastAPI:
|
||||
app.include_router(ai_copilot.router)
|
||||
app.include_router(workflows.router)
|
||||
|
||||
# ─── Serve frontend static files (SPA) ───────────────────────────────
|
||||
# Mount built frontend assets (JS, CSS, images)
|
||||
frontend_dist = os.path.join(os.path.dirname(__file__), "..", "frontend", "dist")
|
||||
if os.path.isdir(frontend_dist):
|
||||
# Serve static assets at /assets
|
||||
assets_path = os.path.join(frontend_dist, "assets")
|
||||
if os.path.isdir(assets_path):
|
||||
app.mount("/assets", StaticFiles(directory=assets_path), name="assets")
|
||||
|
||||
# SPA catch-all: serve index.html for all non-API routes
|
||||
@app.get("/{full_path:path}")
|
||||
async def spa_spa(full_path: str):
|
||||
"""Serve index.html for all non-API routes (SPA fallback)."""
|
||||
# Don't intercept API routes
|
||||
if full_path.startswith(("api/", "docs", "openapi", "redoc")):
|
||||
raise HTTPException(status_code=404, detail="Not Found")
|
||||
index_path = os.path.join(frontend_dist, "index.html")
|
||||
if os.path.isfile(index_path):
|
||||
return FileResponse(index_path)
|
||||
raise HTTPException(status_code=404, detail="Frontend not built")
|
||||
|
||||
return app
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user