| # ── Base image ──────────────────────────────────────────────────────────────── | |
| FROM python:3.11-slim | |
| # ── System dependencies (ffmpeg required by Whisper) ───────────────────────── | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| ffmpeg \ | |
| git \ | |
| curl \ | |
| build-essential \ | |
| && apt-get clean && rm -rf /var/lib/apt/lists/* | |
| # ── Create non-root user (HF Spaces requirement) ────────────────────────────── | |
| RUN useradd -m -u 1000 appuser | |
| # ── Working directory ───────────────────────────────────────────────────────── | |
| WORKDIR /app | |
| # ── Install Python dependencies first (Docker layer cache) ─────────────────── | |
| COPY requirements.txt . | |
| RUN pip install --no-cache-dir --upgrade pip && \ | |
| pip install --no-cache-dir -r requirements.txt | |
| # ── Copy application code ───────────────────────────────────────────────────── | |
| COPY --chown=appuser:appuser . . | |
| # ── Persistent storage dirs (mounted at /data by HF Spaces paid tier) ───────── | |
| RUN mkdir -p /data/.huggingface /data/.cache/huggingface/hub /tmp/audio_cache && \ | |
| chown -R appuser:appuser /data /tmp/audio_cache | |
| # ── HF cache environment variables ─────────────────────────────────────────── | |
| # All model downloads go to /data so they survive Space restarts | |
| ENV HF_HOME=/data/.huggingface | |
| ENV HUGGINGFACE_HUB_CACHE=/data/.huggingface/hub | |
| ENV TRANSFORMERS_CACHE=/data/.huggingface/hub | |
| ENV XDG_CACHE_HOME=/data/.cache | |
| # Whisper also respects this | |
| ENV WHISPER_CACHE=/data/.huggingface/whisper | |
| # ── App config ──────────────────────────────────────────────────────────────── | |
| ENV PYTHONUNBUFFERED=1 | |
| ENV PYTHONDONTWRITEBYTECODE=1 | |
| # HF Spaces routes external traffic to port 7860 | |
| ENV PORT=7860 | |
| # ── Switch to non-root user ─────────────────────────────────────────────────── | |
| USER appuser | |
| # ── Expose port ─────────────────────────────────────────────────────────────── | |
| EXPOSE 7860 | |
| # ── Start Flask via Gunicorn (production-grade WSGI server) ────────────────── | |
| CMD ["gunicorn", \ | |
| "--bind", "0.0.0.0:7860", \ | |
| "--workers", "1", \ | |
| "--threads", "4", \ | |
| "--timeout", "120", \ | |
| "--worker-class", "gthread", \ | |
| "--log-level", "info", \ | |
| "app:app"] | |