diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1e3ced4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM node:20-alpine AS frontend-builder +WORKDIR /app/frontend +COPY frontend/package*.json ./ +RUN npm ci +COPY frontend/ ./ +RUN npm run build + +FROM python:3.12-slim +WORKDIR /app +COPY backend/requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +COPY backend/ . +COPY --from=frontend-builder /app/frontend/dist /app/dist +RUN mkdir -p uploads +EXPOSE 8000 +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/backend/app/main.py b/backend/app/main.py index c3c5d4e..a03a597 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -1,6 +1,9 @@ """FastAPI application entry point.""" +import os + from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware +from fastapi.staticfiles import StaticFiles from app.api.attachments import router as attachments_router from app.api.audit_log import router as audit_log_router @@ -64,13 +67,13 @@ app.include_router(organizations_admin_router, prefix="/api") app.include_router(public_router, prefix="/api") -@app.get("/") -def root() -> dict[str, str]: - """Root endpoint.""" - return {"message": "Space Booking API"} - - @app.get("/health") def health() -> dict[str, str]: """Health check endpoint.""" return {"status": "ok"} + + +# Serve Vue.js frontend in production (when /app/dist exists) +_dist_dir = os.path.join(os.path.dirname(__file__), "..", "..", "dist") +if os.path.isdir(_dist_dir): + app.mount("/", StaticFiles(directory=_dist_dir, html=True), name="static")