Skip to content

Self-hosting guides for the enterprise delivery - #125

Open
M2Night wants to merge 1 commit into
mainfrom
fish-772-self-host-docs
Open

Self-hosting guides for the enterprise delivery#125
M2Night wants to merge 1 commit into
mainfrom
fish-772-self-host-docs

Conversation

@M2Night

@M2Night M2Night commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Replaces the open-source self-hosting pages with guides for the enterprise product: the three delivery forms and how to choose between them, requirements, registry access, the Kubernetes and All-in-One deliveries, air-gapped operation, day-two operations, and how versions are identified.

What these pages are for, and what they deliberately do not carry

A prospect reads these to decide whether they can run this and what to plan for. Everything about how — commands, values, troubleshooting — lives in the deployment runbook, which ships in the documentation bundle alongside the chart version it describes.

That split is not a style preference. This site is not versioned with the chart, so any command or value printed here drifts out of agreement with what a customer actually holds. Each page says so at the top, and names the runbook as the authority when the two differ.

The result: eight pages, zero command blocks. Registry host, artifact references, and versions stay in the dashboard, which filters them by grant.

Corrections from three rounds of customer-view testing

An engineer with no knowledge of the product installed the delivery forms using only these pages and the dashboard. Each item below is theirs, reproduced before fixing.

The pull secret has to move with the images. It holds a login for one host and a kubelet matches pull secrets by host, so a private mirror answers every pull with a 401. The page said only the staging machine needed registry access.

The ledger told customers to verify signatures with a public key Fish Audio supplies, and gave a runnable command whose first line names a file that does not exist. There is no key to ship: the signing key is injected at build time from outside the repositories. Verification is something Fish Audio does on a ledger you send; what a customer can do is check the hash chain, which needs no key.

Zero-egress checks all cut the network and looked for a failure. That proves the deployment does not need the internet, not that it makes no calls when there is some — the question a telemetry or data-residency review asks. The distinction, and the exercise, are now the runbook's; this page says the capability exists and what it costs.

Requirements were wrong in three places. The inference worker pre-allocates a fraction of whatever card it runs on, so the old fixed VRAM figure was a 32 GB observation stated as a constant and contradicted the H100/H200 row beside it. The disk figure did not distinguish pulling the image from carrying it as a file. The validation pod used kubectl run --limits, removed in kubectl 1.24, against a CUDA 12 base image that cannot reproduce the CUDA 13 driver failure it is meant to catch — all now in the runbook, versioned with the chart.

Housekeeping

  • The three open-source pages (local-setup, docker-deployment, running-inference) are removed with redirects, plus one for /self-host, which used to 404.
  • Component names in the architecture table are generic. Deployment names and the inference engine are visible in the dashboard only after a grant, so they do not belong on a public page.
  • The timestamp aligner is described by role rather than by model name, matching how the delivery forms table already refers to it.

Verification

  • Every intra-section link and anchor resolves; checked mechanically across all eight pages.
  • Cross-checked against the Self Host dashboard PR: entry point, email + token authentication, the five-token limit, commands filled in after picking a version, and one chart version shared by both Helm forms.

Part of FISH-772.

Not in this PR

@mintlify

mintlify Bot commented Aug 9, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
hanabiaiinc 🟢 Ready View Preview Aug 9, 2026, 4:25 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR replaces legacy self-hosting pages with Enterprise documentation for requirements, registry access, Kubernetes, All-in-One, air-gapped deployments, releases, and operations. It updates navigation and redirects, and removes the previous local setup, Docker deployment, and inference guides.

Changes

Enterprise self-hosting documentation

Layer / File(s) Summary
Self-hosting overview and access
developer-guide/self-hosting/introduction.mdx, developer-guide/self-hosting/requirements.mdx, developer-guide/self-hosting/registry-access.mdx, docs.json
Adds delivery-form comparisons, architecture, prerequisites, registry authentication, navigation, and redirects.
Kubernetes deployment lifecycle
developer-guide/self-hosting/kubernetes.mdx
Adds preflight checks, secrets, Helm configuration, installation, validation, upgrades, rollback, and uninstall procedures.
All-in-One deployment and inference
developer-guide/self-hosting/all-in-one.mdx
Adds image loading, startup, health checks, REST and WebSocket requests, reference voices, offline authentication, usage ledgers, concurrency, and troubleshooting.
Air-gapped operation and verification
developer-guide/self-hosting/air-gapped.mdx
Adds offline artifact transfer, model serving, signed-ledger verification, retention, reconciliation, and egress-isolation procedures.
Operations and support procedures
developer-guide/self-hosting/operations.mdx
Adds monitoring, scaling, backup, staged upgrades, diagnostics, GPU checks, and escalation procedures.
Enterprise release management
developer-guide/self-hosting/enterprise-releases.mdx
Adds version identifiers, upgrade procedures, air-gapped release guidance, and upgrade advisories.
Legacy guide removal
developer-guide/self-hosting/docker-deployment.mdx, developer-guide/self-hosting/local-setup.mdx, developer-guide/self-hosting/running-inference.mdx
Removes the previous Docker deployment, local setup, and inference guides.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • fishaudio/docs#113: Covers the same Enterprise self-hosting documentation migration.
  • fishaudio/docs#124: Modifies the Enterprise releases guide with related deployment version and upgrade information.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding and updating enterprise self-hosting guides.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fish-772-self-host-docs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🤖 Prompt for all review comments with 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.

Inline comments:
In `@developer-guide/self-hosting/air-gapped.mdx`:
- Around line 138-142: Update the air-gapped bearer-token guidance to require a
dedicated non-secret opaque identifier for each tenant instead of reusable
credentials; explicitly prohibit reusing API keys or externally valid bearer
tokens, and state that ledger files, backups, and reconciliation exports require
the same protection as tenant data.
- Line 19: Update the internal links in
developer-guide/self-hosting/air-gapped.mdx at lines 19, 104-110, 123-125, and
275 to use the specified page-relative targets: ./registry-access,
./kubernetes#install, ./all-in-one#run, ./kubernetes#stage-reference-voices,
./all-in-one#reference-voices, and ./kubernetes#smoke-test. Update the links in
developer-guide/self-hosting/operations.mdx at lines 7-8 to use
./all-in-one#operations; make no other changes.
- Around line 65-69: Update the All-in-One image instructions to pull the
digest-pinned reference, retag it as fish-audio-all-in-one:mirrored, and use
that tag in the docker save command and disconnected-side workflow instead of
passing <all-in-one-image> directly.

In `@developer-guide/self-hosting/all-in-one.mdx`:
- Around line 186-194: Replace the incomplete docker run snippet in the
concurrency guidance with instructions to add -e LIMIT_MODEL_CONCURRENCY=64 to
the complete command in the Run section, preserving required options including
--gpus, the persistent volume, JWT_SECRET, and the image reference.
- Around line 89-97: Bound the readiness loop around the curl health check to a
finite retry count, while retaining the existing delay between attempts. After
the final failed attempt, print an error and exit nonzero instead of continuing
indefinitely; preserve the successful “ready” output when curl succeeds.

In `@developer-guide/self-hosting/introduction.mdx`:
- Around line 39-42: Replace every root-absolute internal documentation link
with the correct relative path: update markdown links and internal Card href
values in developer-guide/self-hosting/introduction.mdx (39-42), and markdown
links in requirements.mdx (53-54), registry-access.mdx (72-75), kubernetes.mdx
(13-17), enterprise-releases.mdx (23-29), and all-in-one.mdx (17-19). Keep the
external https://fish.audio/enterprise link absolute and do not alter unrelated
content.

In `@developer-guide/self-hosting/registry-access.mdx`:
- Around line 57-63: Add a reusable NAMESPACE variable alongside REGISTRY_HOST,
LOGIN_USER, and DEPLOY_TOKEN, then update the pull-secret kubectl command to
target that NAMESPACE instead of hardcoding fish-audio. Preserve the existing
secret name and command behavior.

In `@developer-guide/self-hosting/requirements.mdx`:
- Around line 106-139: Validate every self-hosted deployment command in
supported environments before publishing:
developer-guide/self-hosting/requirements.mdx lines 106-139, registry-access.mdx
lines 59-111, kubernetes.mdx lines 51-309, and all-in-one.mdx lines 29-217. Test
the credential, deployment, persistence, inference, upgrade, rollback,
uninstall, and troubleshooting flows described at each site, and revise or
remove any untested examples; no direct change is specified for a particular
command.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a8281f54-e262-4a58-bd1c-7822aad64e5a

📥 Commits

Reviewing files that changed from the base of the PR and between 2e68889 and 634ee16.

📒 Files selected for processing (12)
  • developer-guide/self-hosting/air-gapped.mdx
  • developer-guide/self-hosting/all-in-one.mdx
  • developer-guide/self-hosting/docker-deployment.mdx
  • developer-guide/self-hosting/enterprise-releases.mdx
  • developer-guide/self-hosting/introduction.mdx
  • developer-guide/self-hosting/kubernetes.mdx
  • developer-guide/self-hosting/local-setup.mdx
  • developer-guide/self-hosting/operations.mdx
  • developer-guide/self-hosting/registry-access.mdx
  • developer-guide/self-hosting/requirements.mdx
  • developer-guide/self-hosting/running-inference.mdx
  • docs.json
💤 Files with no reviewable changes (3)
  • developer-guide/self-hosting/docker-deployment.mdx
  • developer-guide/self-hosting/running-inference.mdx
  • developer-guide/self-hosting/local-setup.mdx


Everything below runs on a **connected staging machine** first, then on the
disconnected side. Only the staging machine needs
[registry access](/developer-guide/self-hosting/registry-access).

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 | 🟠 Major | ⚡ Quick win

Use page-relative paths for internal links.

Replace root-relative paths with paths relative to each MDX file.

  • developer-guide/self-hosting/air-gapped.mdx#L19-L19: Use ./registry-access.
  • developer-guide/self-hosting/air-gapped.mdx#L104-L110: Use ./kubernetes#install and ./all-in-one#run.
  • developer-guide/self-hosting/air-gapped.mdx#L123-L125: Use ./kubernetes#stage-reference-voices and ./all-in-one#reference-voices.
  • developer-guide/self-hosting/air-gapped.mdx#L275-L275: Use ./kubernetes#smoke-test.
  • developer-guide/self-hosting/operations.mdx#L7-L8: Use ./all-in-one#operations.

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/air-gapped.mdx#L19-L19 (this comment)
  • developer-guide/self-hosting/air-gapped.mdx#L104-L110
  • developer-guide/self-hosting/air-gapped.mdx#L123-L125
  • developer-guide/self-hosting/air-gapped.mdx#L275-L275
  • developer-guide/self-hosting/operations.mdx#L7-L8
🤖 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/air-gapped.mdx` at line 19, Update the internal
links in developer-guide/self-hosting/air-gapped.mdx at lines 19, 104-110,
123-125, and 275 to use the specified page-relative targets: ./registry-access,
./kubernetes#install, ./all-in-one#run, ./kubernetes#stage-reference-voices,
./all-in-one#reference-voices, and ./kubernetes#smoke-test. Update the links in
developer-guide/self-hosting/operations.mdx at lines 7-8 to use
./all-in-one#operations; make no other changes.

Source: Coding guidelines

Comment on lines +65 to +69
For the All-in-One image the same pattern applies with a single reference:

```bash
docker save '<all-in-one-image>' | zstd -T0 -o all-in-one.tar.zst
```

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 | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate file =="
git ls-files | grep -F 'developer-guide/self-hosting/air-gapped.mdx' || true

echo "== relevant lines =="
if [ -f developer-guide/self-hosting/air-gapped.mdx ]; then
  sed -n '1,110p' developer-guide/self-hosting/air-gapped.mdx | nl -ba
fi

echo "== search docker save digest/tag patterns =="
rg -n "docker save|docker tag|docker pull|digest|digest-only|All-in-One|all-in-one" developer-guide/self-hosting/air-gapped.mdx || true

echo "== docker local check for digest reference and save/tag =="
command -v docker || true
if command -v docker >/dev/null 2>&1; then
  docker pull busybox:latest >/dev/null 2>&1 || true
  image_ref="$(docker image inspect busybox:latest --format='{{ index .RepoDigests 0 }}')"
  echo "digest reference example: ${image_ref:--N/A}"
  echo "docker save digest-only rc:"
  docker save "$image_ref" >/tmp/test-digest-only.tar 2>/tmp/test-digest-only-save.err || echo "save exit: $?"
  if [ -s /tmp/test-digest-only-save.err ]; then
    head -10 /tmp/test-digest-only-save.err
  fi
  echo "docker tag digest-only rc:"
  docker tag "$image_ref" "test-transfer:mapped" 2>/tmp/test-tag.err || echo "tag exit: $?"
  if [ -s /tmp/test-tag.err ]; then
    cat /tmp/test-tag.err
  fi
fi

Repository: fishaudio/docs

Length of output: 275


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate file =="
git ls-files | grep -F 'developer-guide/self-hosting/air-gapped.mdx' || true

echo "== relevant lines =="
if [ -f developer-guide/self-hosting/air-gapped.mdx ]; then
  python3 - <<'PY'
from pathlib import Path
p = Path('developer-guide/self-hosting/air-gapped.mdx')
for i, line in enumerate(p.read_text(encoding='utf-8').splitlines(), 1):
    if 1 <= i <= 110:
        print(f"{i:4}: {line}")
PY
fi

echo "== search docker save digest/tag patterns =="
rg -n "docker save|docker tag|docker pull|digest|digest-only|All-in-One|all-in-one" developer-guide/self-hosting/air-gapped.mdx || true

echo "== docker local check for digest reference and save/tag =="
command -v docker || true
if command -v docker >/dev/null 2>&1; then
  docker pull busybox:latest >/dev/null 2>&1 || true
  image_ref="$(docker image inspect busybox:latest --format='{{ index .RepoDigests 0 }}')"
  echo "digest reference example: ${image_ref:--N/A}"
  echo "docker save digest-only rc:"
  if docker save "$image_ref" >/tmp/test-digest-only.tar 2>/tmp/test-digest-only-save.err; then
    echo "save exit 0"
  else
    echo "save exit: $?"
  fi
  if [ -s /tmp/test-digest-only-save.err ]; then
    head -10 /tmp/test-digest-only-save.err
  fi
  echo "docker tag digest-only rc:"
  if docker tag "$image_ref" "test-transfer:mapped" 2>/tmp/test-tag.err; then
    echo "tag exit 0"
  else
    echo "tag exit: $?"
  fi
  if [ -s /tmp/test-tag.err ]; then
    cat /tmp/test-tag.err
  fi
fi

Repository: fishaudio/docs

Length of output: 6526


🌐 Web query:

Docker CLI docker save error reference must include repository and tag digest only

💡 Result:

The error message "reference must include repository and tag" is not a standard, built-in error message produced directly by the core docker save command in its official CLI. Instead, users typically encounter related errors such as "invalid reference format," "reference does not exist," or "requires at least 1 argument" when the image identifier is formatted incorrectly [1]. However, the requirement to use a "repository:tag" format is a common functional requirement for docker save if you wish to preserve metadata. When you use docker save <image_id>, Docker saves the image layers but frequently omits the tag and repository metadata in the resulting tarball [2][3][4]. Consequently, when you later use docker load, the image may appear as having no name or tag (often displayed as <none>:<none>) [2][4]. To ensure the repository and tag information are correctly preserved in the saved archive: 1. Always reference the image by its name and tag: docker save -o my-image.tar my-repo:my-tag 2. If you only have the image ID, you can tag it before saving: docker tag <image_id> my-repo:my-tag docker save -o my-image.tar my-repo:my-tag If you are receiving a specific error message about a "reference" needing to include a repository and tag, it is likely being generated by a custom wrapper script, a CI/CD pipeline task (such as a specific DockerCompose task), or a third-party tool that enforces strict naming conventions before executing the underlying docker save command [1]. In such cases, ensure that the image name provided to the tool or script includes both the repository and the tag (e.g., my-image:latest) and avoid using image IDs or incomplete references [1].

Citations:


Tag digest-pinned All-in-One images before saving them.

The Helm image list pulls and retags digest-pinned references before docker save, but the All-in-One section still passes <all-in-one-image> directly. If that reference is digest-only, docker save may fail or lose the image name from the archive. Pull and retag it with fish-audio-all-in-one:mirrored before saving, then use that tag on the disconnected side.

🤖 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/air-gapped.mdx` around lines 65 - 69, Update the
All-in-One image instructions to pull the digest-pinned reference, retag it as
fish-audio-all-in-one:mirrored, and use that tag in the docker save command and
disconnected-side workflow instead of passing <all-in-one-image> directly.

Comment on lines +138 to +142
- Any non-empty `Authorization: Bearer` token is accepted. Empty or missing still
returns 401.
- The token is recorded verbatim as the billing identity, so choose a stable,
distinct value per tenant. Tenants that share a token cannot be told apart in
the ledger.

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

Do not instruct users to persist reusable bearer credentials.

The ledger stores the token verbatim. Ledger files, backups, and reconciliation exports can therefore disclose any credential that a tenant reuses outside this deployment.

Require a dedicated non-secret opaque identifier for each tenant. State that users must not reuse API keys or externally valid bearer tokens. State that ledger access and exports require the same protection as tenant data.

The All-in-One contract at developer-guide/self-hosting/all-in-one.mdx:148-156 confirms that this value persists in the offline ledger.

🤖 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/air-gapped.mdx` around lines 138 - 142, Update
the air-gapped bearer-token guidance to require a dedicated non-secret opaque
identifier for each tenant instead of reusable credentials; explicitly prohibit
reusing API keys or externally valid bearer tokens, and state that ledger files,
backups, and reconciliation exports require the same protection as tenant data.

Comment on lines +89 to +97
```bash
until curl -fsS -m 120 -X POST http://127.0.0.1:8088/v1/tts \
-H 'Authorization: Bearer my-tenant' \
-H 'Content-Type: application/json' \
-H 'model: <model-name>' \
-d '{"text":"ready","format":"mp3"}' -o /tmp/ready.mp3; do
echo "warming up..."; sleep 15
done; echo "ready"
```

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

Bound the readiness retry loop.

This loop never exits for a permanent failure such as 401, an invalid model, or unavailable GPUs. Use a finite retry count. Exit with an error after the final attempt.

🤖 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/all-in-one.mdx` around lines 89 - 97, Bound the
readiness loop around the curl health check to a finite retry count, while
retaining the existing delay between attempts. After the final failed attempt,
print an error and exit nonzero instead of continuing indefinitely; preserve the
successful “ready” output when curl succeeds.

Comment on lines +186 to +194
The single worker admits a bounded number of in-flight requests, set by
`LIMIT_MODEL_CONCURRENCY` (default 32); beyond that, requests queue. The ceiling
is bounded by the inference worker's key-value cache VRAM, so cards with more
memory than the 32 GB baseline can run a higher cap. Raise it at launch without
rebuilding:

```bash
docker run -e LIMIT_MODEL_CONCURRENCY=64 ...
```

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

Replace the incomplete docker run example.

docker run -e LIMIT_MODEL_CONCURRENCY=64 ... is not executable. It also omits required options such as --gpus, the persistent volume, JWT_SECRET, and the image reference.

Tell users to add -e LIMIT_MODEL_CONCURRENCY=64 to the complete command in the Run section.

🤖 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/all-in-one.mdx` around lines 186 - 194, Replace
the incomplete docker run snippet in the concurrency guidance with instructions
to add -e LIMIT_MODEL_CONCURRENCY=64 to the complete command in the Run section,
preserving required options including --gpus, the persistent volume, JWT_SECRET,
and the image reference.

Comment thread developer-guide/self-hosting/introduction.mdx
Comment on lines +57 to +63
Set your values once, then reuse them in the commands below.

```bash
REGISTRY_HOST='<registry-host>'
LOGIN_USER='<your-email>'
DEPLOY_TOKEN='<deploy-token>'
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Create the pull secret in the selected namespace.

Line 98 always creates fish-audio-registry in fish-audio. The Kubernetes procedure supports a different $NAMESPACE. In that case, pods cannot use this secret and private-image pulls fail.

Define NAMESPACE with the other reusable values. Use it in the kubectl command.

Proposed fix
 REGISTRY_HOST='<registry-host>'
 LOGIN_USER='<your-email>'
 DEPLOY_TOKEN='<deploy-token>'
+NAMESPACE=fish-audio
...
-kubectl -n fish-audio create secret docker-registry fish-audio-registry \
+kubectl -n "$NAMESPACE" create secret docker-registry fish-audio-registry \

Also applies to: 98-102

🤖 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/registry-access.mdx` around lines 57 - 63, Add a
reusable NAMESPACE variable alongside REGISTRY_HOST, LOGIN_USER, and
DEPLOY_TOKEN, then update the pull-secret kubectl command to target that
NAMESPACE instead of hardcoding fish-audio. Preserve the existing secret name
and command behavior.

Comment thread developer-guide/self-hosting/requirements.mdx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (2)
developer-guide/self-hosting/requirements.mdx (2)

134-142: ⚠️ Potential issue | 🟠 Major

Run both GPU preflight commands before publishing.

The PR objective states that end-to-end validation remains pending. Run the Kubernetes and Docker checks with the supported kubectl, Docker, NVIDIA Container Toolkit, and image versions. Publish only commands that pass.

As per coding guidelines, “Test all code examples before publishing” and “Do not include untested code examples.”

🤖 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/requirements.mdx` around lines 134 - 142, Run
and validate both documented GPU preflight commands—the Kubernetes check and the
All-in-One Docker check—using the supported kubectl, Docker, NVIDIA Container
Toolkit, and image versions; publish the commands only after both pass,
otherwise correct or remove any untested example.

Source: Coding guidelines


134-142: ⚠️ Potential issue | 🟠 Major

Validate the executable self-hosting examples before publishing.

The PR objective states that end-to-end validation remains pending. These pages contain stateful GPU commands that create containers, modify persistent data, and run inference checks.

  • developer-guide/self-hosting/requirements.mdx#L134-L142: Run the Kubernetes and Docker GPU checks with the supported toolchain and publish only commands that pass.
  • developer-guide/self-hosting/all-in-one.mdx#L54-L58: Run the complete All-in-One launch, readiness, inference, persistence, and cleanup flow on a supported two-GPU host.
  • As per coding guidelines, test all code examples before publishing and do not include untested code examples.
🤖 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/requirements.mdx` around lines 134 - 142,
Validate the executable self-hosting examples before publishing: in
developer-guide/self-hosting/requirements.mdx lines 134-142, run the Kubernetes
and Docker GPU checks with the supported toolchain and retain only commands that
pass; in developer-guide/self-hosting/all-in-one.mdx lines 54-58, run the
complete All-in-One launch, readiness, inference, persistence, and cleanup flow
on a supported two-GPU host, updating or removing any unverified examples.

Source: Coding guidelines

🤖 Prompt for all review comments with 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.

Inline comments:
In `@developer-guide/self-hosting/all-in-one.mdx`:
- Around line 54-58: Before publishing the Docker command in the All-in-One
procedure, run the complete workflow on a supported two-GPU host: verify startup
and readiness, perform inference, confirm persistence, and clean up
successfully. Only retain the command as executable guidance after end-to-end
validation passes.
- Line 216: Update the troubleshooting row near “Vocoder never becomes ready” to
qualify the host-side setup statement: clarify that no separate host-side GPU
service is required, but NVIDIA Container Toolkit must be configured for Docker
GPU access. Preserve the existing guidance to inspect docker logs and the
container’s internal GPU multi-process management.

In `@developer-guide/self-hosting/requirements.mdx`:
- Line 103: Update the NVIDIA driver requirement in the self-hosting
requirements table to state that Linux x86_64 requires NVIDIA driver 580.82.07
or newer for CUDA 13.0.1, replacing the vague “Must support CUDA 13.x” wording
while preserving the existing nvidia-smi verification guidance.

---

Duplicate comments:
In `@developer-guide/self-hosting/requirements.mdx`:
- Around line 134-142: Run and validate both documented GPU preflight
commands—the Kubernetes check and the All-in-One Docker check—using the
supported kubectl, Docker, NVIDIA Container Toolkit, and image versions; publish
the commands only after both pass, otherwise correct or remove any untested
example.
- Around line 134-142: Validate the executable self-hosting examples before
publishing: in developer-guide/self-hosting/requirements.mdx lines 134-142, run
the Kubernetes and Docker GPU checks with the supported toolchain and retain
only commands that pass; in developer-guide/self-hosting/all-in-one.mdx lines
54-58, run the complete All-in-One launch, readiness, inference, persistence,
and cleanup flow on a supported two-GPU host, updating or removing any
unverified examples.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6f12b954-b750-4b93-8449-922360de3e3f

📥 Commits

Reviewing files that changed from the base of the PR and between 634ee16 and cc19868.

📒 Files selected for processing (3)
  • developer-guide/self-hosting/air-gapped.mdx
  • developer-guide/self-hosting/all-in-one.mdx
  • developer-guide/self-hosting/requirements.mdx
🚧 Files skipped from review as they are similar to previous changes (1)
  • developer-guide/self-hosting/air-gapped.mdx

Comment thread developer-guide/self-hosting/all-in-one.mdx Outdated
Comment thread developer-guide/self-hosting/all-in-one.mdx Outdated
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| OS | Linux x86-64. |
| GPUs | 2 GPUs. The first runs the inference worker, the second runs the vocoder. No NVLink required. |
| NVIDIA driver | Must support CUDA 13.x and your card's compute capability. The images ship CUDA 13.0.1. Confirm with `nvidia-smi` before pulling — a driver limited to CUDA 12.x reports a healthy GPU and then fails once the real image starts. |

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 | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file context =="
fd -a 'requirements\.mdx$' . | sed 's#^\./##' || true
file="$(fd 'requirements\.mdx$' developer-guide 2>/dev/null | head -n 1 || true)"
if [ -n "${file:-}" ]; then
  wc -l "$file"
  sed -n '80,115p' "$file" | cat -n -v
fi

echo "== related references =="
rg -n "CUDA 13|CUDA 12|NVIDIA driver|r580|Driver Version|nvidia-smi" developer-guide || true

Repository: fishaudio/docs

Length of output: 5800


🌐 Web query:

NVIDIA CUDA Toolkit 13.0.1 release notes Linux driver R580.82.07

💡 Result:

The NVIDIA CUDA Toolkit 13.0 Update 1 (13.0.1) officially includes and requires the Linux driver version R580.82.07 or newer [1][2][3]. Key details regarding this release include: Technical Documentation: The official release notes for CUDA Toolkit 13.0 Update 1 specify that the required Linux x86_64 driver version is 580.82.07 [1][2]. This driver version serves as the baseline for the 13.0 Update 1 release [1][3]. Driver Characteristics: The 580.82.07 Linux driver was released on September 2, 2025 [4]. Notable improvements and fixes in this driver version include: - A fix for an R580 series regression that caused Vulkan application hangs when running under Wayland [5]. - The introduction of support for NVIDIA Smooth Motion on GeForce RTX 40 series graphics cards [5]. - A fix for a DRM sysfs issue where the enabled attribute incorrectly reported "disabled" for NVIDIA GPU connectors [5]. Compatibility: CUDA 13.0 follows semantic versioning and guarantees ABI stability within the major version series; therefore, releases in the 13.x series are generally ABI-compatible with drivers in the R580 series [1][3]. However, users should always consult the release notes for the specific toolkit version being installed to ensure compliance with the minimum required driver version [1][3]. Installation: The installer package typically used for this release is cuda_13.0.1_580.82.07_linux.run [6][7]. Subsequent updates to the CUDA 13.0 series, such as 13.0 Update 2, have introduced higher minimum driver requirements (e.g., 580.95.05) [3][8].

Citations:


State the required CUDA 13.0.1 driver floor.

CUDA 13.0.1 requires Linux x86_64 NVIDIA driver 580.82.07 or newer. Replace “Must support CUDA 13.x” with that baseline so operators know the exact minimum driver version to check with nvidia-smi.

🤖 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/requirements.mdx` at line 103, Update the NVIDIA
driver requirement in the self-hosting requirements table to state that Linux
x86_64 requires NVIDIA driver 580.82.07 or newer for CUDA 13.0.1, replacing the
vague “Must support CUDA 13.x” wording while preserving the existing nvidia-smi
verification guidance.

Source: MCP tools

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with 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.

Inline comments:
In `@developer-guide/self-hosting/kubernetes.mdx`:
- Around line 40-43: Clarify the Kubernetes documentation so model asset
delivery and S3 bucket serving are documented separately. Reconcile the “Choose
a delivery form” table with the “You usually have to change” guidance: either
document self-hosted S3 serving as supported and explain its routing, or remove
the S3_ENDPOINT_URL recommendations and state that object storage remains an
unused, required secret.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 70420dec-8da5-4ed7-879c-fc60bf47aa4a

📥 Commits

Reviewing files that changed from the base of the PR and between 73c7b13 and 9a8da77.

📒 Files selected for processing (4)
  • developer-guide/self-hosting/air-gapped.mdx
  • developer-guide/self-hosting/introduction.mdx
  • developer-guide/self-hosting/kubernetes.mdx
  • developer-guide/self-hosting/requirements.mdx
🚧 Files skipped from review as they are similar to previous changes (2)
  • developer-guide/self-hosting/requirements.mdx
  • developer-guide/self-hosting/introduction.mdx

Comment thread developer-guide/self-hosting/kubernetes.mdx Outdated
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from 9a8da77 to b253821 Compare August 10, 2026 13:47
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from b253821 to 7c8c019 Compare August 10, 2026 16:38
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from 7c8c019 to 1056196 Compare August 10, 2026 16:44
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from 1056196 to f00987f Compare August 10, 2026 17:02
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from f00987f to b3f46d3 Compare August 10, 2026 17:34
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from b3f46d3 to 745c198 Compare August 10, 2026 17:47
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from 745c198 to 048f239 Compare August 11, 2026 00:54
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from 048f239 to 7186b92 Compare August 11, 2026 01:03
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from 7186b92 to 52740d3 Compare August 11, 2026 01:21
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from 52740d3 to ec29c6c Compare August 11, 2026 07:48
@M2Night M2Night changed the title Self-hosting docs: match the dashboard, and add Releases Self-hosting guides for the enterprise delivery Aug 12, 2026
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from c9047e5 to 5c5d69a Compare August 12, 2026 03:34
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from 5c5d69a to 589b50e Compare August 12, 2026 07:07
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from 589b50e to 3d28574 Compare August 12, 2026 07:17
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from 3d28574 to a46bfe2 Compare August 12, 2026 08:11
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from a46bfe2 to 33cd178 Compare August 12, 2026 09:04
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from 33cd178 to 90a4759 Compare August 12, 2026 09:52
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from 90a4759 to 00a0e4b Compare August 12, 2026 11:39
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from 00a0e4b to 65ea179 Compare August 12, 2026 12:59
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from 65ea179 to 5301bbe Compare August 12, 2026 13:18
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from 5301bbe to b70ee21 Compare August 12, 2026 13:21
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from b70ee21 to 6571299 Compare August 12, 2026 13:26
@M2Night
M2Night force-pushed the fish-772-self-host-docs branch from 6571299 to 832cce1 Compare August 12, 2026 14:17
Replaces the open-source self-hosting pages with guides for the enterprise product:
what the three delivery forms are and how to choose between them, requirements,
registry access, the Kubernetes and All-in-One installs, air-gapped operation,
day-two operations, and how versions are identified.

Corrections from three rounds of customer-view testing, all reproduced:

- **Air-gapped mirroring.** The chart now takes `global.imageRegistry`, so pointing it
  at your own registry is one value plus the two Redis digests it cannot unset itself,
  rather than editing every component. The image list and the push list come from a
  single render through that same flag, which is what keeps them aligned — a default
  render resolves Redis to `repository@digest` with no tag, so a hand-written retag
  invents one the chart never asks for. The pull secret has to move too: it holds a
  login for one host and a kubelet matches by host, so a private mirror answers every
  pull with a 401.
- **The values snippet was a paste-able top-level `global:` block.** Every shipped
  profile already has one, and a YAML document with two is not an error — the last wins
  silently, taking `offlineMode` with it and deploying the online-billing build. Shown
  in place now, and the verification compares the whole image set against what was
  pushed rather than looking for an external host, which cannot see that substitution.
- **Zero egress.** Every check cut the network and looked for a failure, which proves
  the deployment does not need the internet, not that it makes no calls when there is
  some. A packet capture answers that, filtered on the workload's own address rather
  than by excluding private ranges — a cloud host's own address usually sits in one, so
  the exclusions emptied the file whatever the software did.
- **The ledger.** These pages told customers to verify signatures with a public key
  Fish Audio supplies, and gave a runnable command whose first line names a file that
  does not exist. There is no key to ship. What a customer can do — prove the file has
  not been edited — is now separated from what only we can do.
- **Housekeeping.** The pages printed the registry host they promise to write as a
  placeholder, once inside a `sed` that would have sent a customer to a registry they
  were not granted. The air-gap checks started two containers that each hold both GPUs
  and never removed either. Appliance figures are ranges by card, and the disk figure
  distinguishes pulling the image from carrying it as a file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant