Lior-0618 Claude Sonnet 4.6 commited on
Commit
cb1bd97
Β·
1 Parent(s): f55ad8e

feat: add HuggingFace Spaces Docker deployment

Browse files

- Dockerfile: python:3.11-slim + Node 22, builds all 3 layers
- nginx.conf: routes /api/* and /health to Node proxy (3000),
everything else to Next.js standalone (3030); listens on 7860
- supervisord.conf: manages model + server + frontend + nginx
- .dockerignore: excludes node_modules, .venv, .next, .env.local
- next.config.ts: enable standalone output for Docker
- README.md: add HF Spaces YAML frontmatter (sdk: docker, port: 7860)

NEXT_PUBLIC_API_URL="" at build time β†’ relative /api/* URLs β†’
nginx proxies to Node β†’ Node proxies to Python model.
Model weights cached in /data/models (HF Spaces persistent storage).

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

Files changed (6) hide show
  1. .dockerignore +24 -0
  2. Dockerfile +55 -0
  3. README.md +10 -0
  4. demo/next.config.ts +1 -1
  5. nginx.conf +39 -0
  6. supervisord.conf +54 -0
.dockerignore ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Build artifacts
2
+ demo/.next/
3
+ demo/out/
4
+
5
+ # Dependencies (installed inside Docker)
6
+ demo/node_modules/
7
+ demo/server/node_modules/
8
+ model/voxtral-server/.venv/
9
+
10
+ # Local env overrides
11
+ demo/.env.local
12
+ demo/.env*.local
13
+
14
+ # Python cache
15
+ **/__pycache__/
16
+ **/*.pyc
17
+ **/*.pyo
18
+ **/*.egg-info/
19
+
20
+ # Git
21
+ .git/
22
+
23
+ # Logs
24
+ *.log
Dockerfile ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Ethos Studio β€” HuggingFace Spaces Docker deployment
2
+ # Architecture: Python model (8000) + Node proxy (3000) + Next.js (3030)
3
+ # nginx on port 7860 routes traffic between layers
4
+
5
+ FROM python:3.11-slim
6
+
7
+ # ─── System dependencies ──────────────────────────────────────────────────────
8
+ RUN apt-get update && apt-get install -y --no-install-recommends \
9
+ ffmpeg curl nginx supervisor \
10
+ && rm -rf /var/lib/apt/lists/*
11
+
12
+ # Node.js 22
13
+ RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
14
+ && apt-get install -y --no-install-recommends nodejs \
15
+ && rm -rf /var/lib/apt/lists/*
16
+
17
+ WORKDIR /app
18
+
19
+ # ─── Model layer: Python dependencies ────────────────────────────────────────
20
+ COPY model/voxtral-server/requirements.txt model/voxtral-server/requirements.txt
21
+ RUN pip install --no-cache-dir -r model/voxtral-server/requirements.txt
22
+
23
+ COPY model/voxtral-server/ model/voxtral-server/
24
+
25
+ # ─── Proxy server: Node dependencies ─────────────────────────────────────────
26
+ COPY demo/server/package*.json demo/server/
27
+ RUN cd demo/server && npm ci --omit=dev
28
+
29
+ COPY demo/server/ demo/server/
30
+
31
+ # ─── Frontend: Next.js build ──────────────────────────────────────────────────
32
+ COPY demo/package*.json demo/
33
+ RUN cd demo && npm ci
34
+
35
+ COPY demo/ demo/
36
+
37
+ # Build with empty API base β†’ browser uses relative paths β†’ nginx routes /api/*
38
+ RUN cd demo && NEXT_PUBLIC_API_URL="" npm run build \
39
+ && cp -r public .next/standalone/public \
40
+ && cp -r .next/static .next/standalone/.next/static
41
+
42
+ # ─── Process manager + reverse proxy config ───────────────────────────────────
43
+ COPY nginx.conf /etc/nginx/nginx.conf
44
+ COPY supervisord.conf /etc/supervisor/conf.d/app.conf
45
+
46
+ # ─── Model weight cache ───────────────────────────────────────────────────────
47
+ # /data is persisted across Space restarts on HuggingFace Spaces
48
+ RUN mkdir -p /data/models
49
+ ENV TRANSFORMERS_CACHE=/data/models
50
+ ENV HF_HOME=/data/models
51
+
52
+ # HuggingFace Spaces public port
53
+ EXPOSE 7860
54
+
55
+ CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/app.conf"]
README.md CHANGED
@@ -1,3 +1,13 @@
 
 
 
 
 
 
 
 
 
 
1
  # Ethos Studio β€” Emotional Speech Recognition
2
 
3
  Speech-to-text service with VAD sentence segmentation and per-segment emotion analysis, powered by [Voxtral Mini 4B](https://huggingface.co/mistralai/Voxtral-Mini-4B-Realtime-2602). Three-layer architecture: **Model** (Python) + **Server** (Node) + **Frontend** (Next.js).
 
1
+ ---
2
+ title: Ethos Studio
3
+ emoji: 🎀
4
+ colorFrom: purple
5
+ colorTo: indigo
6
+ sdk: docker
7
+ app_port: 7860
8
+ pinned: false
9
+ ---
10
+
11
  # Ethos Studio β€” Emotional Speech Recognition
12
 
13
  Speech-to-text service with VAD sentence segmentation and per-segment emotion analysis, powered by [Voxtral Mini 4B](https://huggingface.co/mistralai/Voxtral-Mini-4B-Realtime-2602). Three-layer architecture: **Model** (Python) + **Server** (Node) + **Frontend** (Next.js).
demo/next.config.ts CHANGED
@@ -1,7 +1,7 @@
1
  import type { NextConfig } from "next";
2
 
3
  const nextConfig: NextConfig = {
4
- /* config options here */
5
  };
6
 
7
  export default nextConfig;
 
1
  import type { NextConfig } from "next";
2
 
3
  const nextConfig: NextConfig = {
4
+ output: "standalone",
5
  };
6
 
7
  export default nextConfig;
nginx.conf ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ worker_processes 1;
2
+ error_log /dev/stderr warn;
3
+ pid /tmp/nginx.pid;
4
+
5
+ events {
6
+ worker_connections 512;
7
+ }
8
+
9
+ http {
10
+ include /etc/nginx/mime.types;
11
+ default_type application/octet-stream;
12
+ access_log /dev/stdout;
13
+ client_max_body_size 100M;
14
+
15
+ server {
16
+ listen 7860;
17
+
18
+ # API + health check β†’ Node proxy server (port 3000)
19
+ location ~ ^/(api|health)(/|$) {
20
+ proxy_pass http://127.0.0.1:3000;
21
+ proxy_read_timeout 660s;
22
+ proxy_send_timeout 660s;
23
+ proxy_connect_timeout 10s;
24
+ proxy_set_header Host $host;
25
+ proxy_set_header X-Real-IP $remote_addr;
26
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
27
+ }
28
+
29
+ # All other requests β†’ Next.js standalone (port 3030)
30
+ location / {
31
+ proxy_pass http://127.0.0.1:3030;
32
+ proxy_set_header Host $host;
33
+ proxy_set_header X-Real-IP $remote_addr;
34
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
35
+ proxy_set_header Upgrade $http_upgrade;
36
+ proxy_set_header Connection "upgrade";
37
+ }
38
+ }
39
+ }
supervisord.conf ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [supervisord]
2
+ nodaemon=true
3
+ logfile=/dev/null
4
+ logfile_maxbytes=0
5
+ pidfile=/tmp/supervisord.pid
6
+
7
+ ; ─── Model layer: Voxtral FastAPI (port 8000) ─────────────────────────────────
8
+ [program:model]
9
+ command=uvicorn main:app --host 127.0.0.1 --port 8000
10
+ directory=/app/model/voxtral-server
11
+ autostart=true
12
+ autorestart=true
13
+ stdout_logfile=/dev/stdout
14
+ stdout_logfile_maxbytes=0
15
+ stderr_logfile=/dev/stderr
16
+ stderr_logfile_maxbytes=0
17
+ priority=10
18
+
19
+ ; ─── Proxy server: Node/Express (port 3000) ───────────────────────────────────
20
+ [program:server]
21
+ command=node index.js
22
+ directory=/app/demo/server
23
+ autostart=true
24
+ autorestart=true
25
+ stdout_logfile=/dev/stdout
26
+ stdout_logfile_maxbytes=0
27
+ stderr_logfile=/dev/stderr
28
+ stderr_logfile_maxbytes=0
29
+ environment=PORT="3000",MODEL_URL="http://127.0.0.1:8000"
30
+ priority=20
31
+
32
+ ; ─── Frontend: Next.js standalone (port 3030) ─────────────────────────────────
33
+ [program:frontend]
34
+ command=node .next/standalone/server.js
35
+ directory=/app/demo
36
+ autostart=true
37
+ autorestart=true
38
+ stdout_logfile=/dev/stdout
39
+ stdout_logfile_maxbytes=0
40
+ stderr_logfile=/dev/stderr
41
+ stderr_logfile_maxbytes=0
42
+ environment=PORT="3030",HOSTNAME="127.0.0.1"
43
+ priority=20
44
+
45
+ ; ─── nginx reverse proxy (port 7860 β€” HF Spaces public port) ─────────────────
46
+ [program:nginx]
47
+ command=nginx -g "daemon off;"
48
+ autostart=true
49
+ autorestart=true
50
+ stdout_logfile=/dev/stdout
51
+ stdout_logfile_maxbytes=0
52
+ stderr_logfile=/dev/stderr
53
+ stderr_logfile_maxbytes=0
54
+ priority=30