drzg15 commited on
Commit
7aebb63
·
1 Parent(s): 7371761

Configure full-stack Docker setup for Hugging Face Spaces

Browse files
Files changed (3) hide show
  1. Dockerfile +33 -7
  2. README.md +1 -1
  3. backend/app/main.py +18 -0
Dockerfile CHANGED
@@ -1,19 +1,45 @@
1
- FROM python:3.13.5-slim
 
 
2
 
 
 
 
 
 
 
 
 
3
  WORKDIR /app
4
 
 
5
  RUN apt-get update && apt-get install -y \
6
  build-essential \
7
  curl \
8
  git \
9
  && rm -rf /var/lib/apt/lists/*
10
 
11
- COPY requirements.txt ./
12
- COPY src/ ./src/
 
 
 
 
 
 
 
 
 
 
 
13
 
14
- RUN pip install --no-cache-dir uv
15
- RUN uv pip install --system -r requirements.txt
 
16
 
17
- EXPOSE 8501
 
18
 
19
- CMD streamlit run src/home.py --server.port=8501 --server.address=0.0.0.0 --server.enableXsrfProtection=false
 
 
 
1
+ # --- Build Stage for Frontend ---
2
+ FROM node:20-alpine AS frontend-builder
3
+ WORKDIR /app/frontend
4
 
5
+ COPY frontend/package.json frontend/package-lock.json* ./
6
+ RUN npm ci || npm install
7
+
8
+ COPY frontend/ ./
9
+ RUN npm run build
10
+
11
+ # --- Build Stage for Backend ---
12
+ FROM python:3.13-slim
13
  WORKDIR /app
14
 
15
+ # Install system dependencies
16
  RUN apt-get update && apt-get install -y \
17
  build-essential \
18
  curl \
19
  git \
20
  && rm -rf /var/lib/apt/lists/*
21
 
22
+ # Copy backend requirements
23
+ COPY backend/pyproject.toml backend/requirements.txt* ./backend/
24
+ # Check if requirements.txt exists and install it, else install from pyproject.toml
25
+ RUN cd backend && \
26
+ if [ -f requirements.txt ]; then pip install --no-cache-dir -r requirements.txt; fi && \
27
+ pip install --no-cache-dir uvicorn fastapi
28
+
29
+ # Copy backend code
30
+ COPY backend/ ./backend/
31
+ RUN cd backend && pip install -e .
32
+
33
+ # Copy built frontend from the frontend-builder stage
34
+ COPY --from=frontend-builder /app/frontend/dist /app/frontend/dist
35
 
36
+ # Also copy other necessary directories from root if the backend needs them
37
+ COPY cop_analysis/ ./cop_analysis/
38
+ COPY data/ ./data/
39
 
40
+ # Expose Hugging Face Space port
41
+ EXPOSE 7860
42
 
43
+ # Run uvicorn server
44
+ WORKDIR /app/backend
45
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "7860"]
README.md CHANGED
@@ -3,7 +3,7 @@ title: Heattransplanapp
3
  colorFrom: red
4
  colorTo: red
5
  sdk: docker
6
- app_port: 8501
7
  tags:
8
  - streamlit
9
  pinned: false
 
3
  colorFrom: red
4
  colorTo: red
5
  sdk: docker
6
+ app_port: 7860
7
  tags:
8
  - streamlit
9
  pinned: false
backend/app/main.py CHANGED
@@ -32,3 +32,21 @@ app.include_router(assets.router, prefix="/api/assets", tags=["Assets"])
32
  @app.get("/api/health")
33
  async def health():
34
  return {"status": "ok"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  @app.get("/api/health")
33
  async def health():
34
  return {"status": "ok"}
35
+
36
+ # Serve frontend static files
37
+ import os
38
+ from fastapi.staticfiles import StaticFiles
39
+ from fastapi.responses import FileResponse
40
+
41
+ frontend_dist = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "frontend", "dist")
42
+ if os.path.isdir(frontend_dist):
43
+ app.mount("/assets", StaticFiles(directory=os.path.join(frontend_dist, "assets")), name="assets")
44
+
45
+ @app.get("/{full_path:path}")
46
+ async def serve_frontend(full_path: str):
47
+ # Serve specific files from root if they exist
48
+ target_file = os.path.join(frontend_dist, full_path)
49
+ if os.path.isfile(target_file):
50
+ return FileResponse(target_file)
51
+ # Otherwise fallback to index.html for SPA routing
52
+ return FileResponse(os.path.join(frontend_dist, "index.html"))