feat: Add initial backend application and update Dockerfile for its setup.

This commit is contained in:
Bruno Charest 2026-03-13 09:33:07 -04:00
parent 023e399d1d
commit 05b44a5404
2 changed files with 24 additions and 3 deletions

View File

@ -34,16 +34,17 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
# Create non-root user
RUN useradd --create-home --shell /bin/bash foxy
WORKDIR /app
RUN chown foxy:foxy /app
# Python dependencies
COPY backend/requirements.txt ./
COPY --chown=foxy:foxy backend/requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
# Backend source
COPY backend/app ./app
COPY --chown=foxy:foxy backend/app ./app
# Frontend static files (served by FastAPI)
COPY --from=frontend-build /build/dist ./static
COPY --chown=foxy:foxy --from=frontend-build /build/dist ./static
# Healthcheck
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \

View File

@ -9,6 +9,9 @@ from contextlib import asynccontextmanager
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
import os
from app.config import settings
from app.database import init_db
@ -62,6 +65,23 @@ app.include_router(logs.router)
app.include_router(workflows.router)
app.include_router(config.router)
# ─── Static Files ─────────────────────────────────────────────────────────────
if os.path.exists("static"):
app.mount("/assets", StaticFiles(directory="static/assets"), name="assets")
@app.get("/{full_path:path}")
async def serve_spa(full_path: str):
# API requests should already be handled by routers
# If not an API request, serve index.html
if full_path.startswith("api/") or full_path.startswith("ws/"):
return None # Should not happen due to router order
index_path = os.path.join("static", "index.html")
if os.path.exists(index_path):
return FileResponse(index_path)
return {"detail": "Frontend not found"}
# ─── WebSocket ─────────────────────────────────────────────────────────────────