feat(P01): SLICE-01+02 — Dockerfile, .dockerignore, docker-compose.yml, FastAPI StaticFiles, PRAXIS_DB_PATH env (G-102 fix)
SLICE-01 (lead-developer): multi-stage Dockerfile (node:22-slim→python:3.12-slim), .dockerignore (excludes secrets/node_modules/.git), docker-compose.yml (port 8789, SQLite volume, env injection for all voice-service vars) SLICE-02 (backend-engineer+data-engineer): FastAPI mounts client/dist as StaticFiles at / after API routes (D-023, REQ-DEPLOY-13). G-102 MUST fix: db/store.py + db/migrate.py now read PRAXIS_DB_PATH from env so the Docker volume mount persists SQLite data. G-105 FIX: Dockerfile copies pyproject.toml before source (pip install layer cached, source changes don't invalidate). REQ-DEPLOY-01, 02, 13, 16 covered. ---ci--- project: praxis phase: 1 milestone: v0.2 status: execute slice: 01-02 wave: 1 ---/ci---
This commit is contained in:
@@ -29,6 +29,7 @@ except ImportError: # pragma: no cover
|
||||
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from pipecat.transports.smallwebrtc.connection import SmallWebRTCConnection
|
||||
|
||||
from server.pipeline import build_pipeline
|
||||
@@ -116,6 +117,19 @@ async def webrtc_offer(offer: WebRTCOffer) -> dict[str, str]:
|
||||
raise HTTPException(status_code=500, detail=str(exc))
|
||||
|
||||
|
||||
# ── Static client serving (D-023, REQ-DEPLOY-13) ────────────────────
|
||||
# Mount client/dist as StaticFiles at "/" AFTER all API routes so they
|
||||
# take precedence. html=True serves index.html for "/" (SPA root).
|
||||
# The client has no React Router (single-view state machine: start→live
|
||||
# →debrief), so no SPA fallback fallback route is needed per RESEARCH.md Q3.
|
||||
_CLIENT_DIST = _env("PRAXIS_CLIENT_DIST", "client/dist")
|
||||
if os.path.isdir(_CLIENT_DIST):
|
||||
app.mount("/", StaticFiles(directory=_CLIENT_DIST, html=True), name="client")
|
||||
logger.info(f"Serving client from {_CLIENT_DIST}")
|
||||
else:
|
||||
logger.warning(f"Client dist not found at {_CLIENT_DIST} — API-only mode")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
"""Run the server with uvicorn."""
|
||||
import uvicorn
|
||||
|
||||
Reference in New Issue
Block a user