Important
This repository is in early development. The current launcher is a tested prototype, not yet the promised one-click Gum and PowerShell experience. It will not create anything in Runpod unless you explicitly run the launcher with a configured account.
Launch an IndexTTS2 GPU Pod from WSL2, wait for it to become ready, and print the URL and API key that a local application can use.
The public address is provided by Runpod's HTTPS proxy:
https://<pod-id>-8000.proxy.runpod.net
The default IndexTTS API key is intentionally simple:
sk-1234notsecure
launchIndex.sh calls the Runpod REST API directly. It:
- Creates a one-GPU Pod from the project's prebuilt image.
- Tries several compatible 24 GB-or-larger NVIDIA GPU types.
- Exposes the container's port
8000through Runpod's HTTPS proxy. - Waits while the image starts, checkpoints download, and IndexTTS loads.
- Prints
INDEXTTS_URL,INDEXTTS_API_KEY, and the Pod ID.
It does not require SSH, Cloudflare Tunnel, Tailscale, Docker Compose, or Docker inside the Pod.
This repository includes a GitHub Actions workflow that builds and publishes the image to GitHub Container Registry.
Push the repository to GitHub, run Build IndexTTS Cloud image, and make the resulting GHCR package public. Its address will look like:
ghcr.io/YOUR_GITHUB_NAME/indextts_cloud:latest
Alternatively, build and push it from WSL2 with Docker:
docker build -t docker.io/YOUR_DOCKER_NAME/indextts-cloud:latest .
docker login
docker push docker.io/YOUR_DOCKER_NAME/indextts-cloud:latestThe build pins upstream IndexTTS to commit 13495845e3028f0bb6ca1462ad22aa0e76349e40, the official model snapshot to 740dcaff396282ffb241903d150ac011cd4b1ede, and uses CUDA 12.8. Model weights are downloaded to /workspace on the first Pod start, so later starts reuse them.
cp .env.example .env
nano .env
chmod +x launchIndex.shSet these two values in .env:
RUNPOD_API_KEY=your-real-runpod-api-key
INDEXTTS_IMAGE=ghcr.io/YOUR_GITHUB_NAME/indextts_cloud:latestRUNPOD_API_KEY is the only sensitive credential. Do not commit .env.
From WSL2:
./launchIndex.shThe shell file is only a convenience wrapper. The launcher uses Python's standard library, so this is equivalent:
python3 launchIndex.py launchThe first start can take a while because Runpod must pull the large CUDA image and download the IndexTTS checkpoints. The final output looks like:
INDEXTTS_URL=https://abc123-8000.proxy.runpod.net
INDEXTTS_API_KEY=sk-1234notsecure
RUNPOD_POD_ID=abc123
The launcher records the active Pod in .runpod-index.json to prevent accidental duplicate Pods.
./launchIndex.sh status
./launchIndex.sh stop
./launchIndex.sh start
./launchIndex.sh terminate --yesstop releases the GPU while retaining the Pod's /workspace volume. terminate --yes permanently deletes the Pod and its attached Pod volume.
Useful launch overrides:
./launchIndex.sh launch --gpu-types "NVIDIA GeForce RTX 4090,NVIDIA GeForce RTX 3090"
./launchIndex.sh launch --cloud-type COMMUNITY
./launchIndex.sh launch --spot
./launchIndex.sh launch --no-waitInteractive documentation is available at:
https://<pod-id>-8000.proxy.runpod.net/docs
Authentication accepts either header:
Authorization: Bearer sk-1234notsecure
X-API-Key: sk-1234notsecurecurl "$INDEXTTS_URL/v1/voices" \
-H "Authorization: Bearer $INDEXTTS_API_KEY" \
-F "voice_id=default" \
-F "file=@voice-reference.wav"Reference audio is fundamental to IndexTTS voice cloning. The current upstream repository does not bundle an example voice, so upload one clip after the first deployment. It persists in /workspace/indextts/voices across Pod stops and starts.
You can upload additional voices the same way with IDs such as hero or narrator.
curl "$INDEXTTS_URL/v1/audio/speech" \
-H "Authorization: Bearer $INDEXTTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"indextts-2","input":"Hello from the cloud.","voice":"default"}' \
--output speech.wavPOST /tts is an alias for the same request. Change "voice":"default" to another uploaded voice ID when needed.
GET /healthz process health; no key required
GET /readyz model readiness; no key required
GET /v1/info capabilities and saved voices
GET /v1/models OpenAI-style model listing
GET /v1/voices saved voice listing
POST /v1/voices upload or replace a reference voice
POST /v1/audio/speech
POST /tts
WAV, MP3, Opus, and FLAC output are supported through the response_format field. Normal game dialogue should fit Runpod's HTTP proxy timeout; very long narration should be split into shorter requests.
The API tests use a fake TTS engine and do not download models or require a GPU:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements-dev.txt
pytest -qActual IndexTTS inference, CUDA compatibility, and first-boot duration still need one real Runpod GPU test after the image is published.