# TalkToDoc production image. # Built to be interchangeable across hosts: Hugging Face Spaces, Render # (Docker deploy), Fly.io, Cloud Run, or any other platform that runs a # standard Docker image. Nothing here is tied to one specific host. # Configuration comes entirely from environment variables set by # whichever platform runs it (PORT, DATABASE_URL, OPENAI_API_KEY, # SECRET_KEY, ENVIRONMENT). FROM python:3.11-slim # Whisper needs ffmpeg to read audio files, this installs it at the # system level since it can't come from pip. build-essential is needed # because some packages in requirements.txt compile C extensions during # install, and the slim base image has no compiler by default. RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ ffmpeg \ && rm -rf /var/lib/apt/lists/* # Run as a non-root user, standard practice and specifically expected by # Hugging Face Spaces' Docker SDK. RUN useradd -m -u 1000 user USER user ENV PATH="/home/user/.local/bin:$PATH" WORKDIR /home/user/app COPY --chown=user requirements.txt . RUN pip install --no-cache-dir --upgrade -r requirements.txt # YarnGPT downloads its WavTokenizer checkpoint itself on first import, # using a bare requests.get() call with no error checking. If that # download hiccups at runtime (inside the running container, on the # app's first request), it silently saves a corrupted or partial file # and the app fails later with a confusing, unrelated error. # # This downloads the exact same two files ahead of time, at build time, # using huggingface_hub's properly tested download function instead. If # this fails, the build fails clearly, right here, instead of the app # failing mysteriously after it's already live. YarnGPT's own downloader # checks whether the file already exists before downloading, so it will # find these already in place and skip straight past its own fragile # download step. RUN python - <<'PY' from huggingface_hub import hf_hub_download import os target = "/home/user/.yarngpt/models" os.makedirs(target, exist_ok=True) hf_hub_download( repo_id="novateur/WavTokenizer-large-speech-75token", filename="wavtokenizer_large_speech_320_24k.ckpt", revision="c5512c1bd34afef082035923e4bae245f3da9e5f", local_dir=target, ) hf_hub_download( repo_id="novateur/WavTokenizer-medium-speech-75token", filename="wavtokenizer_mediumdata_frame75_3s_nq1_code4096_dim512_kmeans200_attn.yaml", local_dir=target, ) print("WavTokenizer files downloaded.") PY COPY --chown=user . . ENV ENVIRONMENT=production # 7860 is Hugging Face Spaces' default port. Other platforms (like # Render) set $PORT themselves, and this falls back to that automatically. EXPOSE 7860 CMD gunicorn app:app --bind 0.0.0.0:${PORT:-7860} --timeout 120 --workers 1