Spaces:
Running
Running
| # ββ Stage 1: build the React frontend ββββββββββββββββββββββββββββββββββββ | |
| FROM node:22-slim AS frontend | |
| WORKDIR /build | |
| COPY src/ui/frontend/package.json src/ui/frontend/package-lock.json ./ | |
| RUN npm ci | |
| COPY src/ui/frontend/ ./ | |
| RUN npm run build | |
| # ββ Stage 2: Python runtime ββββββββββββββββββββββββββββββββββββββββββββββ | |
| FROM python:3.11-slim | |
| # ffmpeg: Whisper STT decodes uploads with it. | |
| # libasound2*: runtime dependency of the Azure Speech SDK (name differs | |
| # between Debian bookworm and trixie, hence the fallback). | |
| RUN apt-get update \ | |
| && apt-get install -y --no-install-recommends ffmpeg \ | |
| && (apt-get install -y --no-install-recommends libasound2t64 \ | |
| || apt-get install -y --no-install-recommends libasound2) \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # HF Spaces runs the container as uid 1000 with no writable $HOME by | |
| # default; create a real user so model caches have somewhere to live. | |
| RUN useradd -m -u 1000 user | |
| ENV HOME=/home/user \ | |
| HF_HOME=/home/user/.cache/huggingface \ | |
| PYTHONUNBUFFERED=1 \ | |
| PYTHONDONTWRITEBYTECODE=1 \ | |
| VOICE_BACKEND=real \ | |
| VOICE_TTS=auto | |
| WORKDIR /app | |
| RUN chown user:user /app | |
| USER user | |
| COPY --chown=user:user requirements.txt . | |
| RUN pip install --no-cache-dir --user -r requirements.txt | |
| ENV PATH="/home/user/.local/bin:${PATH}" | |
| # Pre-fetch the voice models at build time so the first request isn't a | |
| # 1.6 GB download repeated on every Space restart (ephemeral disk). | |
| RUN python -c "from transformers import AutoModelForSpeechSeq2Seq, AutoProcessor; \ | |
| AutoModelForSpeechSeq2Seq.from_pretrained('openai/whisper-large-v3-turbo'); \ | |
| AutoProcessor.from_pretrained('openai/whisper-large-v3-turbo')" | |
| RUN python -c "from pathlib import Path; from piper.download_voices import download_voice; \ | |
| d = Path.home() / '.cache' / 'piper-voices'; d.mkdir(parents=True, exist_ok=True); \ | |
| download_voice('ar_JO-kareem-medium', d)" | |
| # App source, knowledge base, and the built frontend bundle. | |
| # Secrets (GITHUB_TOKEN, GROQ_API_KEY, HF_TOKEN, AZURE_SPEECH_KEY) are NOT | |
| # baked in β they come from the environment at runtime. | |
| COPY --chown=user:user src/ ./src/ | |
| COPY --chown=user:user data/chroma_db/ ./data/chroma_db/ | |
| COPY --from=frontend --chown=user:user /build/dist/ ./src/ui/frontend/dist/ | |
| EXPOSE 7860 | |
| CMD ["uvicorn", "src.ui.main:app", "--host", "0.0.0.0", "--port", "7860"] | |