| # ========================================== | |
| # Stage 1: Build the React + Vite Frontend | |
| # ========================================== | |
| FROM node:20-slim AS frontend-builder | |
| WORKDIR /app/frontend | |
| # Copy frontend source files | |
| COPY frontend/package*.json ./ | |
| RUN npm ci | |
| COPY frontend/ ./ | |
| RUN npm run build | |
| # ========================================== | |
| # Stage 2: Build the FastAPI + PyTorch Backend | |
| # ========================================== | |
| FROM python:3.10-slim | |
| # Install system dependencies (libsndfile1 is required by soundfile, espeak for pyttsx3 Linux speech) | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| libsndfile1 \ | |
| espeak \ | |
| ffmpeg \ | |
| git \ | |
| && rm -rf /var/lib/apt/lists/* | |
| WORKDIR /app | |
| # Create a non-root user with UID 1000 (Hugging Face Spaces requirement) | |
| RUN useradd -m -u 1000 user | |
| ENV HOME=/home/user \ | |
| PATH=/home/user/.local/bin:$PATH \ | |
| PYTHONUNBUFFERED=1 | |
| # Pre-create writable directories for audio caches and temp audio files | |
| RUN mkdir -p /app/static/temp && \ | |
| mkdir -p /home/user/.cache/huggingface && \ | |
| chown -R user:user /app /home/user | |
| # Switch to the non-root user | |
| USER user | |
| # Install CPU-only PyTorch first to keep the container extremely lightweight (~1.5GB instead of 5GB) | |
| RUN pip3 install --no-cache-dir --user torch torchaudio --index-url https://download.pytorch.org/whl/cpu | |
| # Copy backend requirements and install dependencies | |
| COPY --chown=user:user requirements.txt . | |
| RUN pip3 install --no-cache-dir --user -r requirements.txt | |
| # Install VibeVoice package with --no-deps to prevent compiling unused/heavy packages (like aiortc and av) | |
| RUN pip3 install --no-cache-dir --user --no-deps git+https://github.com/shijincai/VibeVoice.git | |
| # Copy FastAPI backend code and assets | |
| COPY --chown=user:user app.py . | |
| COPY --chown=user:user static/ static/ | |
| # Copy the built React static bundles from Stage 1 | |
| COPY --chown=user:user --from=frontend-builder /app/frontend/dist ./frontend/dist | |
| # Expose Hugging Face Space port | |
| EXPOSE 7860 | |
| ENV PORT=7860 | |
| # Start the FastAPI server dynamically binding to port 7860 | |
| CMD ["python3", "app.py"] | |