Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions developer-guide/self-hosting/enterprise-appliance.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
---
title: "Enterprise Appliance"
description: "Run the Fish Audio TTS stack on your own hardware from a single container"
icon: "server"
---

The enterprise appliance is the whole Fish Audio TTS stack — model weights included — in one
container. It needs no Kubernetes and no network access at runtime, which makes it suitable for
on-prem, single-tenant, and air-gapped deployments.

<Note>
The appliance is part of an enterprise agreement. Your team needs the **Self
Host** feature and a grant for the All-in-One artifact before the commands
below will work. If Developer → Self Host does not appear in your dashboard,
contact your account manager.
</Note>

## What you get

| | |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Exposed port | `8088` — the TTS API. Nothing else is published. |
| GPUs | **2**, validated on 2× RTX 5090 (32 GB) and 2× H100 80 GB. GPU 0 runs the language model, GPU 1 runs the vocoder. No NVLink required. |

Check warning on line 23 in developer-guide/self-hosting/enterprise-appliance.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

developer-guide/self-hosting/enterprise-appliance.mdx#L23

Did you really mean 'GPUs'?

Check warning on line 23 in developer-guide/self-hosting/enterprise-appliance.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

developer-guide/self-hosting/enterprise-appliance.mdx#L23

Did you really mean 'vocoder'?

Check warning on line 23 in developer-guide/self-hosting/enterprise-appliance.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

developer-guide/self-hosting/enterprise-appliance.mdx#L23

Did you really mean 'NVLink'?
| Scaling | one inference worker on two GPUs. It does not shard across more GPUs or nodes — for elastic or multi-tenant throughput, use the Helm deployment instead. |

Check warning on line 24 in developer-guide/self-hosting/enterprise-appliance.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

developer-guide/self-hosting/enterprise-appliance.mdx#L24

Did you really mean 'GPUs'?

Check warning on line 24 in developer-guide/self-hosting/enterprise-appliance.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

developer-guide/self-hosting/enterprise-appliance.mdx#L24

Did you really mean 'GPUs'?
| Network at runtime | none. Weights are baked into the image. |

## 1. Prerequisites

- Docker with the **NVIDIA Container Toolkit** installed and the `nvidia` runtime registered.
Verify with `docker run --rm --gpus all <cuda-image> nvidia-smi`.
- Enough disk for the image: roughly **28 GB compressed, 60 GB unpacked**.
- A **deploy token**, created in Developer → Self Host. That page also shows the version to run.

## 2. Sign in and pull

Your username is your Fish Audio account email; the password is a deploy token.

```bash
echo '<your-deploy-token>' | docker login registry.fish.audio -u '<your-email>' --password-stdin
docker pull registry.fish.audio/self-hosted/enterprise/all-in-one:<version>
```

<Tip>
Developer → Self Host renders both of these commands with your email and the
current version already filled in. Copy them from there rather than typing the
version by hand.
</Tip>

For an air-gapped host, pull on a machine that can reach the registry, then move the image:

```bash
docker save registry.fish.audio/self-hosted/enterprise/all-in-one:<version> \
| zstd -T0 -3 -o all-in-one.tar.zst
# on the target host:
zstd -d -c all-in-one.tar.zst | docker load
```
Comment on lines +49 to +56

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Add zstd to the air-gapped prerequisites.

Both commands require zstd. List it as a prerequisite on the connected host and the target host, or provide an alternative transfer method.

As per coding guidelines, “Include prerequisites at the start of procedural content.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@developer-guide/self-hosting/enterprise-appliance.mdx` around lines 49 - 56,
Add zstd to the prerequisites at the start of the air-gapped host procedure in
the enterprise appliance guide, explicitly covering both the connected machine
and target host used by the docker save/load commands.

Source: Coding guidelines


## 3. Run

Generate a JWT secret **once**, store it, and reuse the same value on every run.

```bash
export FISH_JWT_SECRET="$(openssl rand -hex 32)"

docker run -d --name fish-tts \
--gpus all \
--shm-size 16g --ulimit memlock=-1 --ulimit stack=67108864 \
-p 8088:8088 \
-v fish-tts-shared:/mnt/shared \
-e JWT_SECRET="$FISH_JWT_SECRET" \
Comment on lines +60 to +70

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Document how to persist and restore JWT_SECRET.

The export command only sets the secret in the current shell. A later upgrade can pass an empty value or a new value, which can activate the development default or invalidate existing tokens. Require users to store the value in an approved secret store and load the same value before every docker run.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@developer-guide/self-hosting/enterprise-appliance.mdx` around lines 60 - 70,
Update the enterprise appliance JWT setup around FISH_JWT_SECRET to document
storing the generated secret in an approved secret store, then restoring the
exact same value before every docker run, including upgrades or restarts.
Replace the current session-only export guidance with persistence and retrieval
instructions while preserving the existing JWT_SECRET environment-variable
wiring.

--restart unless-stopped \
registry.fish.audio/self-hosted/enterprise/all-in-one:<version>
```

<Warning>
`JWT_SECRET` is required for any production deployment. Without it the
container falls back to a fixed built-in development default, which is not
secret. Changing the value later invalidates every token and session issued
under the old one.
</Warning>

**`--gpus all`** pins the worker to GPU 0 and the vocoder to GPU 1. On a host with more than two

Check warning on line 82 in developer-guide/self-hosting/enterprise-appliance.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

developer-guide/self-hosting/enterprise-appliance.mdx#L82

Did you really mean 'vocoder'?
GPUs it takes the first two; to choose specific cards use `--gpus '"device=0,1"'`.

Check warning on line 83 in developer-guide/self-hosting/enterprise-appliance.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

developer-guide/self-hosting/enterprise-appliance.mdx#L83

Did you really mean 'GPUs'?

**`-v fish-tts-shared:/mnt/shared`** is one persistent volume for everything that must survive a
restart: the compile and CUDA-graph caches, the vocoder engine, reference voices, and the usage

Check warning on line 86 in developer-guide/self-hosting/enterprise-appliance.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

developer-guide/self-hosting/enterprise-appliance.mdx#L86

Did you really mean 'vocoder'?
ledger. It is what makes restarts fast.

<Note>
The **first start compiles for around 10 minutes** once the image is on the
host. A completely cold host that also has to transfer the ~28 GB image can
take 45–75 minutes end to end, depending on the network. Later starts on the
same volume take minutes. Keep the volume.
</Note>

The container runs fully non-root — PID 1 and every service as UID 1000. A fresh named volume
inherits that ownership and works as-is; an existing volume or a host bind-mount must be writable
by UID 1000.

## 4. Check it is serving

```bash
curl -fsS http://localhost:8088/health
```

## Upgrading

Developer → Self Host shows the version your team recorded and tells you when a newer one is
available, with a link to what changed. Upgrading is: pull the new tag, stop the old container,
start a new one with the same volume and the same `JWT_SECRET`.

```bash
docker pull registry.fish.audio/self-hosted/enterprise/all-in-one:<new-version>
docker stop fish-tts && docker rm fish-tts
# re-run the command from step 3 with the new tag
```

The volume is reused deliberately: the caches in it are keyed by content, so a new image rebuilds
only what actually changed. Keep the old image on the host until the new one has served traffic —
rolling back is then just starting the previous tag again.

See [Appliance Releases](/developer-guide/self-hosting/enterprise-releases) for the version list.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use relative paths for both internal links.

Both links use absolute internal paths.

  • developer-guide/self-hosting/enterprise-appliance.mdx#L122-L122: change the target to ./enterprise-releases.
  • developer-guide/self-hosting/enterprise-releases.mdx#L7-L7: change the target to ./enterprise-appliance.

As per coding guidelines, “Use relative paths for internal links” and “Do not use absolute URLs for internal links.”

📍 Affects 2 files
  • developer-guide/self-hosting/enterprise-appliance.mdx#L122-L122 (this comment)
  • developer-guide/self-hosting/enterprise-releases.mdx#L7-L7
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@developer-guide/self-hosting/enterprise-appliance.mdx` at line 122, Convert
both internal links to relative paths: update
developer-guide/self-hosting/enterprise-appliance.mdx lines 122-122 to target
./enterprise-releases, and developer-guide/self-hosting/enterprise-releases.mdx
lines 7-7 to target ./enterprise-appliance.

Source: Coding guidelines

49 changes: 49 additions & 0 deletions developer-guide/self-hosting/enterprise-releases.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: "Appliance Releases"
description: "Version history for the Fish Audio enterprise appliance"
icon: "tag"
---

Every version of the [enterprise appliance](/developer-guide/self-hosting/enterprise-appliance)
we have released, newest first. Developer → Self Host shows which one your team recorded as
running and links here when a newer one is available.

<Note>
Versions are immutable. A tag always refers to the same image — we never
re-point one at different content, so a deployment pinned to a tag keeps
getting the bytes it was tested with. Fixes ship as a new version.
</Note>

## How to read a version

```
s2.1-pro-20260803-offline
└──┬───┘ └──┬───┘ └──┬──┘
│ │ └─ variant: `offline` records usage to a local signed ledger
│ └─ the date we published it
└─ the model generation it serves
```
Comment on lines +19 to +25

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add a language tag to the version-format block.

Use a text fence for this non-executable example.

As per coding guidelines, “Include language tags on all code blocks.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@developer-guide/self-hosting/enterprise-releases.mdx` around lines 19 - 25,
Add the text language tag to the fenced version-format example containing
s2.1-pro-20260803-offline, without changing its contents or explanatory
annotations.

Source: Coding guidelines


---

## s2.1-pro-20260803-offline

<Update label="2026-08-03" tags={["current"]}>
First generally available build of the appliance.

- Serves the S2.1 Pro voice model, weights baked in — no network access at runtime.
- Two GPUs: language model on GPU 0, vocoder on GPU 1.

Check warning on line 35 in developer-guide/self-hosting/enterprise-releases.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

developer-guide/self-hosting/enterprise-releases.mdx#L35

Did you really mean 'GPUs'?

Check warning on line 35 in developer-guide/self-hosting/enterprise-releases.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

developer-guide/self-hosting/enterprise-releases.mdx#L35

Did you really mean 'vocoder'?
- Usage recorded to a local signed ledger; nothing is reported off the host.
- Runs fully non-root (UID 1000).

**Upgrading:** nothing to migrate — this is the first release.

</Update>

---

## Getting an older version

The dashboard lists the versions we currently recommend. If you need one that is no longer
listed — to reproduce a node exactly as it was, for instance — contact your account manager
rather than guessing a tag.
4 changes: 3 additions & 1 deletion docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,9 @@
"pages": [
"developer-guide/self-hosting/local-setup",
"developer-guide/self-hosting/docker-deployment",
"developer-guide/self-hosting/running-inference"
"developer-guide/self-hosting/running-inference",
"developer-guide/self-hosting/enterprise-appliance",
"developer-guide/self-hosting/enterprise-releases"
]
},
{
Expand Down
Loading