FROM python:3.9-slim WORKDIR /app # System deps: audio libs, phonemizer backend, compiler toolchain, healthcheck RUN apt-get update && apt-get install -y \ libsndfile1 \ espeak-ng \ espeak-ng-data \ build-essential \ python3-dev \ curl \ ffmpeg \ && rm -rf /var/lib/apt/lists/* # Modern pip for reliable resolution RUN pip install --no-cache-dir --upgrade pip # Force CPU-only PyTorch first to avoid CUDA wheels and heavy resolution # (keeps downstream deps like spacy-curated-transformers from pulling GPU builds) RUN pip install --no-cache-dir --extra-index-url https://download.pytorch.org/whl/cpu "torch==2.3.0+cpu" # Prefer wheels to avoid compiling spaCy/thinc/blis from source on slim images ENV PIP_ONLY_BINARY=:all: PIP_PREFER_BINARY=1 # Python deps COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # App code COPY app.py . # Ensure phonemizer finds eSpeak NG on Debian ENV PHONEMIZER_ESPEAK_LIBRARY=/usr/lib/x86_64-linux-gnu/libespeak-ng.so.1 # IMPORTANT: avoid model prefetch during build; load at runtime instead # (prevents HF Hub/network hiccups from failing the build) # RUN python -c "from kittentts import KittenTTS; KittenTTS('KittenML/kitten-tts-nano-0.1')" # Non-root RUN useradd -m -u 1000 appuser && chown -R appuser /app USER appuser # Expose and healthcheck on 7860 to match the uvicorn port below EXPOSE 7860 HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD curl -f http://localhost:7860/ || exit 1 CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860", "--workers", "1"]