# ========================================== # 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"]