Fish Speech Studio
A small Dockerized web app for saving voice references and generating speech through a separate Fish Speech API server.
Run with Docker
- Run
docker compose up --build. - Open
http://localhost:8000, enter the CUDA PC's reachable Fish Speech address in the TTS Host control, and select Test connection. - After the server check passes, select Save & use. Saved hosts remain available in the URL dropdown.
The app writes its SQLite database and audio files under /data; Compose mounts this directory as a persistent volume. For browser microphone recording from another device, serve the app through HTTPS (for example, with a TLS reverse proxy). localhost works without HTTPS.
Queued jobs can be cancelled before they reach Fish Speech. Cancelling a running job hides and discards its eventual result, but the Fish Speech request may continue using the GPU until it returns; the app waits for it to finish before starting the next queued job.
The Fish Speech host must listen on a network interface reachable by the Docker host, and its firewall must permit the configured API port. If the app container is on a different machine, use the CUDA PC's LAN/VPN hostname or IP, not localhost.
Local development
Backend: python -m venv .venv && . .venv/bin/activate && pip install -r requirements.txt && uvicorn app.main:app --reload
Frontend: cd frontend && npm install && npm run dev. Vite proxies /api requests to http://localhost:8000.
For recorded browser audio, the backend uses ffmpeg to normalize the browser's recording format to WAV. Docker includes it; install it locally for development.
Configuration
FISH_SPEECH_URL: Fish Speech/v1/ttsendpoint (defaulthttp://host.docker.internal:8080/v1/tts).FISH_SPEECH_API_KEY: bearer key (defaultYOUR_API_KEY, matching the Fish Speech client default).DATA_DIR: persistent app data directory (default/datain Docker).MAX_REFERENCE_BYTES: maximum upload size (default 25 MiB).
The UI accepts either a base host such as http://192.168.1.42:8080 or a full endpoint such as http://192.168.1.42:8080/v1/tts. It checks the Fish Speech /v1/health endpoint before saving a URL. The saved URL becomes active for new jobs; queued jobs keep the URL they were created with.
Tests
Backend tests: .venv/bin/python -m pytest
Frontend tests: cd frontend && npm test
Browser smoke tests: install Playwright Chromium with cd frontend && npx playwright install chromium, then run npm run test:e2e.
Production frontend build: cd frontend && npm run build