Indrajit Ari commited on
Commit
62b7f0a
Β·
1 Parent(s): a6b2429

refactor: drop nginx+standalone, use static export served by FastAPI on :7860

Browse files
Files changed (3) hide show
  1. Dockerfile +21 -36
  2. backend/app_hf.py +1 -0
  3. frontend/next.config.js +10 -5
Dockerfile CHANGED
@@ -1,13 +1,13 @@
1
  # ─────────────────────────────────────────────────────────────────────────────
2
  # Hugging Face Spaces β€” Docker SDK
3
- # Architecture:
4
- # supervisord manages three processes:
5
- # - Next.js standalone server on :3000
6
- # - FastAPI (uvicorn) on :8000
7
- # - nginx on :7860 (routing frontend + backend)
8
  # ─────────────────────────────────────────────────────────────────────────────
9
 
10
- # ── Stage 1: Build Next.js ──────────────────────────────────────────────────
11
  FROM node:20-slim AS frontend-builder
12
 
13
  WORKDIR /build/frontend
@@ -15,28 +15,29 @@ COPY frontend/package*.json ./
15
  RUN npm ci
16
 
17
  COPY frontend/ ./
 
 
18
  ENV NEXT_PUBLIC_API_URL=""
19
- ENV BUILD_STANDALONE=1
 
20
  RUN npm run build
21
 
22
- # ── Stage 2: Runtime ────────────────────────────────────────────────────────
23
  FROM python:3.10-slim
24
 
25
- # System deps
26
  RUN apt-get update && apt-get install -y \
27
  ffmpeg libgl1 libglib2.0-0 \
28
- nginx supervisor curl \
29
- && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
30
- && apt-get install -y nodejs \
31
  && apt-get clean && rm -rf /var/lib/apt/lists/*
32
 
33
  WORKDIR /app
34
 
35
- # ── Python deps ──────────────────────────────────────────────────────────────
36
  RUN pip install --no-cache-dir \
37
  torch==2.1.2 torchvision==0.16.2 \
38
  --index-url https://download.pytorch.org/whl/cpu
39
 
 
40
  RUN pip install --no-cache-dir \
41
  "fastapi>=0.110.0" \
42
  "uvicorn[standard]>=0.29.0" \
@@ -48,33 +49,17 @@ RUN pip install --no-cache-dir \
48
  "imageio>=2.33.0" \
49
  "imageio-ffmpeg>=0.4.9"
50
 
51
- # ── Copy app code ────────────────────────────────────────────────────────────
52
  COPY backend/ ./backend/
53
 
54
- # ── Copy Next.js standalone build ───────────────────────────────────────────
55
- COPY --from=frontend-builder /build/frontend/.next/standalone ./frontend/
56
- COPY --from=frontend-builder /build/frontend/.next/static ./frontend/.next/static
57
- COPY --from=frontend-builder /build/frontend/public ./frontend/public
58
 
59
- # ── Configs ──────────────────────────────────────────────────────────────────
60
- COPY nginx.conf /etc/nginx/nginx.conf
61
- COPY supervisord.conf /etc/supervisor/conf.d/app.conf
62
-
63
- # ── Directories, Permissions & Cleanup ───────────────────────────────────────
64
- # Remove default nginx config to prevent conflicts
65
- RUN rm -f /etc/nginx/sites-enabled/default
66
-
67
- # Ensure all runtime directories exist and are writable by any user
68
- RUN mkdir -p /tmp/video_seg/uploads /tmp/video_seg/outputs \
69
- && mkdir -p /tmp/client_temp /tmp/proxy_temp /tmp/fastcgi_temp /tmp/uwsgi_temp /tmp/scgi_temp \
70
- && mkdir -p /var/log/supervisor /var/run /var/lib/nginx /var/log/nginx \
71
- && chmod -R 777 /tmp \
72
- && chmod -R 777 /var/log/supervisor \
73
- && chmod -R 777 /var/lib/nginx \
74
- && chmod -R 777 /var/log/nginx \
75
- && chmod -R 777 /var/run
76
 
77
  # HF Spaces requires port 7860
78
  EXPOSE 7860
79
 
80
- CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"]
 
 
1
  # ─────────────────────────────────────────────────────────────────────────────
2
  # Hugging Face Spaces β€” Docker SDK
3
+ #
4
+ # Architecture (simplified β€” NO nginx, NO Next.js server process):
5
+ # 1. Build Next.js as a static export β†’ ./frontend/out/
6
+ # 2. FastAPI serves the static files + handles /api/* and /ws/*
7
+ # 3. Single process: uvicorn on port 7860
8
  # ─────────────────────────────────────────────────────────────────────────────
9
 
10
+ # ── Stage 1: Build Next.js static export ────────────────────────────────────
11
  FROM node:20-slim AS frontend-builder
12
 
13
  WORKDIR /build/frontend
 
15
  RUN npm ci
16
 
17
  COPY frontend/ ./
18
+ # Empty API URL β†’ NEXT_PUBLIC_API_URL="" means relative /api/* calls
19
+ # which FastAPI will handle directly (same-origin)
20
  ENV NEXT_PUBLIC_API_URL=""
21
+ # Trigger output: 'export' mode in next.config.js
22
+ ENV BUILD_EXPORT=1
23
  RUN npm run build
24
 
25
+ # ── Stage 2: Runtime (Python only, no nginx, no Node) ───────────────────────
26
  FROM python:3.10-slim
27
 
28
+ # System deps: ffmpeg + OpenCV
29
  RUN apt-get update && apt-get install -y \
30
  ffmpeg libgl1 libglib2.0-0 \
 
 
 
31
  && apt-get clean && rm -rf /var/lib/apt/lists/*
32
 
33
  WORKDIR /app
34
 
35
+ # ── Python: CPU-only torch ───────────────────────────────────────────────────
36
  RUN pip install --no-cache-dir \
37
  torch==2.1.2 torchvision==0.16.2 \
38
  --index-url https://download.pytorch.org/whl/cpu
39
 
40
+ # ── Python: app dependencies ─────────────────────────────────────────────────
41
  RUN pip install --no-cache-dir \
42
  "fastapi>=0.110.0" \
43
  "uvicorn[standard]>=0.29.0" \
 
49
  "imageio>=2.33.0" \
50
  "imageio-ffmpeg>=0.4.9"
51
 
52
+ # ── Copy backend code ────────────────────────────────────────────────────────
53
  COPY backend/ ./backend/
54
 
55
+ # ── Copy Next.js static export ───────────────────────────────────────────────
56
+ COPY --from=frontend-builder /build/frontend/out ./frontend/out
 
 
57
 
58
+ # ── Storage dirs ─────────────────────────────────────────────────────────────
59
+ RUN mkdir -p /tmp/video_seg/uploads /tmp/video_seg/outputs
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
  # HF Spaces requires port 7860
62
  EXPOSE 7860
63
 
64
+ # Single process: FastAPI serves both the API and the static frontend
65
+ CMD ["uvicorn", "backend.app_hf:app", "--host", "0.0.0.0", "--port", "7860", "--workers", "1"]
backend/app_hf.py CHANGED
@@ -30,6 +30,7 @@ logger = logging.getLogger(__name__)
30
 
31
  UPLOAD_DIR = Path(os.getenv("UPLOAD_DIR", "/tmp/video_seg/uploads"))
32
  OUTPUT_DIR = Path(os.getenv("OUTPUT_DIR", "/tmp/video_seg/outputs"))
 
33
  STATIC_DIR = Path(__file__).parent.parent / "frontend" / "out"
34
 
35
  UPLOAD_DIR.mkdir(parents=True, exist_ok=True)
 
30
 
31
  UPLOAD_DIR = Path(os.getenv("UPLOAD_DIR", "/tmp/video_seg/uploads"))
32
  OUTPUT_DIR = Path(os.getenv("OUTPUT_DIR", "/tmp/video_seg/outputs"))
33
+ # In Docker: /app/backend/../frontend/out = /app/frontend/out
34
  STATIC_DIR = Path(__file__).parent.parent / "frontend" / "out"
35
 
36
  UPLOAD_DIR.mkdir(parents=True, exist_ok=True)
frontend/next.config.js CHANGED
@@ -1,14 +1,19 @@
1
  /** @type {import('next').NextConfig} */
2
  const nextConfig = {
3
- // Local dev: talks directly to FastAPI on :8000
4
- // Docker/HF build: NEXT_PUBLIC_API_URL="" β€” nginx routes /api/* to FastAPI
5
  env: {
6
  NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL ?? 'http://localhost:8000',
7
  },
8
 
9
- // Standalone output is needed for Docker (HF Spaces).
10
- // Set BUILD_STANDALONE=1 in Dockerfile; omit for local dev.
11
- ...(process.env.BUILD_STANDALONE === '1' ? {
 
 
 
 
 
 
 
12
  output: 'standalone',
13
  eslint: { ignoreDuringBuilds: true },
14
  typescript: { ignoreBuildErrors: true },
 
1
  /** @type {import('next').NextConfig} */
2
  const nextConfig = {
 
 
3
  env: {
4
  NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL ?? 'http://localhost:8000',
5
  },
6
 
7
+ // Docker/HF Spaces: static export served by FastAPI directly on :7860
8
+ ...(process.env.BUILD_EXPORT === '1' ? {
9
+ output: 'export',
10
+ eslint: { ignoreDuringBuilds: true },
11
+ typescript: { ignoreBuildErrors: true },
12
+ images: { unoptimized: true },
13
+ } : {}),
14
+
15
+ // Standalone build (not currently used but kept for reference)
16
+ ...(process.env.BUILD_STANDALONE === '1' ? {
17
  output: 'standalone',
18
  eslint: { ignoreDuringBuilds: true },
19
  typescript: { ignoreBuildErrors: true },