JakgritB Claude Sonnet 4.6 commited on
Commit
f066cd2
·
1 Parent(s): 70fbcf2

fix(hf-space): add HF Spaces config and root Dockerfile

Browse files

- Add YAML frontmatter to README.md (sdk: docker) so HF Space
recognises the repo as a Docker-based Space
- Add root Dockerfile: multi-stage build that compiles React with
VITE_API_BASE_URL="" then runs FastAPI on port 7860 (HF default)
- FastAPI now serves the built React SPA as a catch-all when
/app/static/ exists, keeping dev setup unchanged

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Files changed (3) hide show
  1. Dockerfile +35 -0
  2. README.md +9 -0
  3. backend/app/main.py +13 -0
Dockerfile ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Stage 1: build React frontend
2
+ FROM node:22-alpine AS frontend-builder
3
+ WORKDIR /frontend
4
+ COPY frontend/package*.json ./
5
+ RUN npm ci
6
+ COPY frontend/ ./
7
+ # Empty string = same-origin API calls (FastAPI serves both)
8
+ ENV VITE_API_BASE_URL=""
9
+ RUN npm run build
10
+
11
+ # Stage 2: FastAPI backend (CPU, demo mode for HF Space)
12
+ FROM python:3.11-slim
13
+ WORKDIR /app
14
+
15
+ RUN apt-get update && \
16
+ apt-get install -y --no-install-recommends ffmpeg git curl && \
17
+ rm -rf /var/lib/apt/lists/*
18
+
19
+ COPY backend/pyproject.toml ./
20
+ RUN pip install --no-cache-dir -e "."
21
+
22
+ COPY backend/app ./app
23
+
24
+ # Copy built frontend so FastAPI can serve it
25
+ COPY --from=frontend-builder /frontend/dist ./static
26
+
27
+ RUN mkdir -p /app/data
28
+
29
+ ENV DEMO_MODE=true
30
+ ENV STORAGE_DIR=/app/data
31
+ ENV FRONTEND_ORIGIN=https://elevenclip-ai.hf.space
32
+
33
+ EXPOSE 7860
34
+
35
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "7860"]
README.md CHANGED
@@ -1,3 +1,12 @@
 
 
 
 
 
 
 
 
 
1
  # ElevenClip.AI
2
 
3
  ElevenClip.AI is an AI-powered clip studio for turning long-form videos into personalized short-form content for TikTok, YouTube Shorts, and Instagram Reels.
 
1
+ ---
2
+ title: ElevenClip AI
3
+ emoji: 🎬
4
+ colorFrom: purple
5
+ colorTo: red
6
+ sdk: docker
7
+ pinned: false
8
+ ---
9
+
10
  # ElevenClip.AI
11
 
12
  ElevenClip.AI is an AI-powered clip studio for turning long-form videos into personalized short-form content for TikTok, YouTube Shorts, and Instagram Reels.
backend/app/main.py CHANGED
@@ -1,3 +1,5 @@
 
 
1
  from fastapi import BackgroundTasks, FastAPI, File, Form, HTTPException, UploadFile
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from fastapi.responses import FileResponse
@@ -32,6 +34,17 @@ app.add_middleware(
32
  )
33
  app.mount("/media", StaticFiles(directory=settings.storage_dir), name="media")
34
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
  @app.get("/health", response_model=HealthResponse)
37
  async def health() -> HealthResponse:
 
1
+ from pathlib import Path
2
+
3
  from fastapi import BackgroundTasks, FastAPI, File, Form, HTTPException, UploadFile
4
  from fastapi.middleware.cors import CORSMiddleware
5
  from fastapi.responses import FileResponse
 
34
  )
35
  app.mount("/media", StaticFiles(directory=settings.storage_dir), name="media")
36
 
37
+ _STATIC_DIR = Path(__file__).parent.parent.parent / "static"
38
+ if _STATIC_DIR.is_dir():
39
+ app.mount("/assets", StaticFiles(directory=_STATIC_DIR / "assets"), name="frontend-assets")
40
+
41
+ @app.get("/{full_path:path}", include_in_schema=False)
42
+ async def serve_spa(full_path: str) -> FileResponse:
43
+ candidate = _STATIC_DIR / full_path
44
+ if candidate.is_file():
45
+ return FileResponse(candidate)
46
+ return FileResponse(_STATIC_DIR / "index.html")
47
+
48
 
49
  @app.get("/health", response_model=HealthResponse)
50
  async def health() -> HealthResponse: