# dots.tts OpenAI-compatible TTS server (thin FastAPI over DotsTtsRuntime).
# GPU access is via `runtime: nvidia` at run time (torch ships its own CUDA
# runtime; no CUDA toolkit / nvcc needed to build — the model uses no custom
# compiled kernels, confirmed on the irv-ml1 venv).
FROM python:3.11-slim

RUN apt-get update && apt-get install -y --no-install-recommends \
        libsndfile1 ffmpeg git curl ca-certificates \
    && rm -rf /var/lib/apt/lists/*

RUN pip install --no-cache-dir uv

WORKDIR /app

# Pin the proven-working version set (captured from the running v1 image).
# NOT using upstream constraints/recommended.txt: as of 2026-08-10 it pins
# gradio==6.17.0, which does not exist on PyPI and makes a fresh resolve
# unsatisfiable (upstream regression). dots.tts 0.2.1 pulls a working gradio
# (6.17.3) on its own; torch/numpy/soundfile pinned to the v1-image versions.
RUN uv pip install --system \
        dots.tts==0.2.1 torch==2.8.0 torchaudio==2.8.0 numpy==2.2.6 soundfile==0.13.1 \
        fastapi "uvicorn[standard]"

# C compiler for the RUNTIME (not build): optimize=True drives torch.compile /
# inductor / triton, which JIT-compile kernels via gcc on model load. Without it
# the runtime dies with "Failed to find C compiler". Placed after the pip layer
# so it doesn't invalidate the expensive torch install cache.
RUN apt-get update && apt-get install -y --no-install-recommends build-essential \
    && rm -rf /var/lib/apt/lists/*

COPY app.py /app/app.py

# Persist the inductor compile cache on the mounted (rw) HF cache so kernel
# JIT doesn't re-run on every container restart (~70s warmup otherwise).
ENV HF_HOME=/hf_cache DOTS_PORT=8198 CC=gcc CXX=g++ TORCHINDUCTOR_CACHE_DIR=/hf_cache/inductor
EXPOSE 8198
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8198"]
