# IndexTTS-2 — Bilibili's emotion-controllable zero-shot TTS, served
# behind our own thin FastAPI wrapper (stacks/index-tts/app.py).
#
# Why this stack exists alongside qwen3-tts and cosyvoice:
# IndexTTS-2 disentangles timbre from emotion — emotion can be cloned
# from a separate audio reference, set via 8-vector, or derived from
# free text. Neither qwen3-tts nor cosyvoice expose this cleanly in
# English. See stacks/index-tts/README.md for the full rationale.
#
# Build: image is local, built from the Dockerfile in this dir. Pinned
# upstream SHA lives in .env as INDEX_TTS_SHA so rebuilds are
# reproducible.
#
# Model: ~5-7 GB IndexTTS-2 weights download on first start via the
# entrypoint, persisted under ${INDEX_TTS_CACHE_DIR}.
#
# License note: weights carry a custom Bilibili license (free at our
# scale, but not OSI-open). The wrapper code is ours, MIT-by-default.
#
# All tunables live in .env — edit that, not this file.

services:
  index-tts:
    image: local/index-tts:${INDEX_TTS_TAG}
    build:
      context: .
      dockerfile: Dockerfile
      args:
        INDEX_TTS_SHA: ${INDEX_TTS_SHA}
    container_name: index-tts
    restart: unless-stopped
    runtime: nvidia
    ports:
      - "${INDEX_TTS_BIND:-0.0.0.0}:${INDEX_TTS_PORT}:8000"
    environment:
      - NVIDIA_VISIBLE_DEVICES=${INDEX_TTS_GPU_DEVICES:-all}
      - INDEX_TTS_MODEL_DIR=/app/checkpoints
      - INDEX_TTS_VOICES_DIR=/app/voices
      - INDEX_TTS_EMOTIONS_DIR=/app/emotions
      - INDEX_TTS_FP16=${INDEX_TTS_FP16:-1}
      - INDEX_TTS_DEVICE=${INDEX_TTS_DEVICE:-}
      - INDEX_TTS_LOG_LEVEL=${INDEX_TTS_LOG_LEVEL:-INFO}
    volumes:
      - ${INDEX_TTS_CACHE_DIR}:/app/checkpoints
      - ${INDEX_TTS_VOICES_DIR}:/app/voices
      - ${INDEX_TTS_EMOTIONS_DIR}:/app/emotions
    healthcheck:
      # Match Dockerfile's healthcheck. Compose-level entry overrides the
      # image-level one if anything ever needs tweaking per-deploy.
      test: ["CMD-SHELL", "wget -q -O /dev/null http://localhost:8000/healthz || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
      # First boot: ~5-7 GB HF download + IndexTTS-2 import (touches several
      # auxiliary HF repos for MaskGCT, campplus, BigVGAN, w2v-bert) + initial
      # CUDA warmup. Generous deadline to ride that out.
      start_period: 600s
    labels:
      - homepage.group=AI - Dormant
      - homepage.name=IndexTTS-2
      - homepage.icon=mdi-account-music
      - homepage.description=Emotion-controllable TTS w/ voice cloning (irv-ml1)
      - homepage.href=http://10.100.79.3:${INDEX_TTS_PORT}
