| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Dockerfile for HuggingFace Spaces (Docker SDK) | |
| # | |
| # Hardware target: CPU Space (free tier) or GPU Space (T4-small recommended). | |
| # Port 7860 is the HF Spaces standard. | |
| # | |
| # Build order: | |
| # 1. System deps (libsndfile for soundfile, git for pip installs) | |
| # 2. Python packages (cached layer) | |
| # 3. App code (invalidates only on source changes) | |
| # 4. Switch to non-root user (HF Spaces requirement) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| FROM python:3.11-slim | |
| WORKDIR /app | |
| # ββ System dependencies βββββββββββββββββββββββββββββββββββββββββββββββββββββ # | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| libsndfile1 \ | |
| libgomp1 \ | |
| git \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # ββ Python dependencies (cached unless requirements.txt changes) ββββββββββββ # | |
| COPY requirements.txt . | |
| # Install CPU-only torch first (saves ~1 GB over default CUDA wheel). | |
| # Comment these two lines out and use the plain pip install if you have a GPU Space. | |
| RUN pip install --no-cache-dir \ | |
| torch==2.5.1+cpu torchaudio==2.5.1+cpu \ | |
| --index-url https://download.pytorch.org/whl/cpu | |
| RUN pip install --no-cache-dir -r requirements.txt | |
| # ββ Application code βββββββββββββββββββββββββββββββββββββββββββββββββββββββ # | |
| COPY . . | |
| # ββ Non-root user for HF Spaces compatibility βββββββββββββββββββββββββββββββ # | |
| RUN useradd -m -u 1000 appuser \ | |
| && chown -R appuser:appuser /app | |
| USER 1000 | |
| # ββ Model cache lives in the user home so HF Spaces can persist it ββββββββββ # | |
| ENV HF_HOME=/home/appuser/.cache/huggingface | |
| ENV PORT=7860 | |
| EXPOSE 7860 | |
| # ββ Healthcheck βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # | |
| HEALTHCHECK --interval=60s --timeout=10s --start-period=300s \ | |
| CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:7860/health')" | |
| CMD ["python", "-m", "uvicorn", "app:app", \ | |
| "--host", "0.0.0.0", \ | |
| "--port", "7860", \ | |
| "--log-level", "info", \ | |
| "--ws-ping-interval", "30", \ | |
| "--ws-ping-timeout", "60"] | |