Skip to content

Self-hosting docs: match the dashboard, and add Releases - #125

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

Self-hosting docs: match the dashboard, and add Releases#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

Takes over #113 and updates it for what changed since it was written. Do not merge yet — the procedures here have not been walked end to end, which is the next step once a version is published.

What #113 assumed that is no longer true

The Self Host page lost its Connection Values card, and the card listing what a team holds now names delivery forms rather than repository references. Three pages walked customers through copying values and image references out of cards that no longer exist.

Those sections now point at the install commands the dashboard builds, and every per-team value stays a placeholder — <registry-host>, <chart-reference>, <all-in-one-image>. This site is public; a registry host, a chart name and an artifact path are only shown to a team that was granted them, so they do not belong here. #113's own <Note> saying exactly that is restored.

What the chart changed

Both deployment profiles now ship inside the chart, so the Kubernetes page starts from helm pull --untar --untardir ./chart and a copy of one, instead of a hand-written values file. The "what to change" table names the exact keys, verified by rendering:

  • MODEL_DISCOVERY_NAMESPACE is an entry under edge-api-production.env, not a dotted path — --set edge-api-production.env[].X is a parse error.
  • Tolerations belong at sglang.worker.tolerations; sglang.tolerations renders nothing and the schema accepts it silently.
  • The online form has two S3_ENDPOINT_URL settings. Setting one leaves the vocoder pointed at the original bucket.
  • Replica counts apply on install but not on helm upgrade, where the running count wins.

Air-gapped mirroring could not run

Three failures, each reproduced:

Step What happened
docker save "repo:tag@sha256:…" invalid reference format — save rejects the pinned form outright
docker pull by digest the image lands with no name to save under
docker tag … "target@sha256:…" refusing to create a tag with a digest reference

The images are now renamed for the internal registry on the connected side, before the transfer. Two references (the bundled Redis pair) render digest-only with no tag, so they get a fixed one rather than landing on :latest. The page also now says to clear the pinned digests when pointing the chart at a mirror — a digest does not survive docker save, so leaving one in place fails the pull.

Reference archives are staged at <sharedStorageHostPath>/<namespace>/<release>/reference-archives/#113 had this right; an earlier revision of this branch shortened it to the container path and it is restored.

New page

enterprise-releases.mdx — what identifies a version for each delivery form, and how an upgrade is applied. It is the target of the dashboard's "What's new" link.

Known gaps

  • The air-gapped procedure has not been executed end to end. It should be before we stand behind it.
  • Where the online form's object-storage credentials come from is written as "your account team issues them", pending a decision on how that is delivered.

Part of FISH-772.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Summary by CodeRabbit

  • Documentation
    • Added a self-hosting introduction covering deployment options, capabilities, prerequisites, and architecture.
    • Added comprehensive guides for Kubernetes, All-in-One, and air-gapped deployments.
    • Added guidance on requirements, registry access, enterprise releases, upgrades, monitoring, authentication, storage, GPU configuration, offline usage, and troubleshooting.
    • Reorganized self-hosting navigation and added redirects from legacy paths.
    • Removed outdated local setup, Docker deployment, and standalone inference documentation.

@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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately identifies the main documentation updates: aligning self-hosting content with the dashboard and adding release guidance.
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.
✨ 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 on lines +39 to +42
Both Helm forms share one deployment procedure and differ only in a few values.
See [Kubernetes deployment](/developer-guide/self-hosting/kubernetes) for the
Helm forms and [All-in-One container](/developer-guide/self-hosting/all-in-one)
for the single-container form.

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 | 🏗️ Heavy lift

Use relative paths for internal links.

These pages use root-absolute paths for internal documentation links. Convert them to paths relative to the current page. Keep the external https://fish.audio/enterprise link absolute.

  • developer-guide/self-hosting/introduction.mdx#L39-L42: Convert markdown links and all internal Card href values to relative paths.
  • developer-guide/self-hosting/requirements.mdx#L53-L54: Convert internal markdown links to relative paths.
  • developer-guide/self-hosting/registry-access.mdx#L72-L75: Convert internal markdown links to relative paths.
  • developer-guide/self-hosting/kubernetes.mdx#L13-L17: Convert internal markdown links to relative paths.
  • developer-guide/self-hosting/enterprise-releases.mdx#L23-L29: Convert internal markdown links to relative paths.
  • developer-guide/self-hosting/all-in-one.mdx#L17-L19: Convert internal markdown links to relative paths.

As per coding guidelines, use relative paths for internal links and never use absolute URLs for internal links.

📍 Affects 6 files
  • developer-guide/self-hosting/introduction.mdx#L39-L42 (this comment)
  • developer-guide/self-hosting/requirements.mdx#L53-L54
  • developer-guide/self-hosting/registry-access.mdx#L72-L75
  • developer-guide/self-hosting/kubernetes.mdx#L13-L17
  • developer-guide/self-hosting/enterprise-releases.mdx#L23-L29
  • developer-guide/self-hosting/all-in-one.mdx#L17-L19
🤖 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/introduction.mdx` around lines 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.

Source: Coding guidelines

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

@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 on lines +54 to +58
docker run -d --name fish-audio \
--gpus all \
--shm-size 16g --ulimit memlock=-1 --ulimit stack=67108864 \
-p 8088:8088 \
-v fishaudio-shared:/mnt/shared \

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Run the All-in-One procedure before publishing.

The PR objective states that end-to-end validation remains pending. Validate the complete flow on a supported two-GPU host, including startup, readiness, inference, persistence, and cleanup, before publishing this command as executable guidance.

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/all-in-one.mdx` around lines 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.

Source: Coding guidelines

| Symptom | Cause and fix |
| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Errors or not-ready responses for the first several minutes after start | The worker and vocoder are still compiling on a cold start. Wait, and keep the cache volume so it does not repeat. |
| Vocoder never becomes ready, or every request fails after warmup | Check `docker logs fish-audio` for vocoder startup errors. The container manages its own GPU multi-process service internally; no host-side setup is required. |

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate and inspect the relevant section and nearby NVIDIA runtime/toolkit mentions.
file="developer-guide/self-hosting/all-in-one.mdx"
if [ -f "$file" ]; then
  echo "== file exists =="
  wc -l "$file"
  echo
  echo "== lines 1-240 =="
  sed -n '1,240p' "$file" | nl -ba | sed -n '1,260p'
else
  echo "File $file not found"
  echo "Candidate mdx files:"
  fd 'all-in-one\.mdx$|self-hosting' .
fi

echo
echo "== targeted searches in file =="
rg -n "nvidia|NVIDIA|Container Toolkit|runtime|--gpus|GPU|warmup|no host-side|host-side" "$file" || true

Repository: fishaudio/docs

Length of output: 278


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="developer-guide/self-hosting/all-in-one.mdx"

echo "== file exists and size =="
[ -f "$file" ] && wc -l "$file"

echo
echo "== first 245 lines =="
awk '{printf "%6d\t%s\n", NR, $0}' "$file" | sed -n '1,245p'

echo
echo "== targeted searches in file =="
rg -n "nvidia|NVIDIA|Container Toolkit|runtime|--gpus|GPU|warmup|no host-side|host-side" "$file" || true

Repository: fishaudio/docs

Length of output: 15928


Qualify “no host-side setup” for the All-in-One GPU runtime.

Line 216 says no host-side setup is required, but the run command uses --gpus all and line 220 still depends on NVIDIA Container Toolkit configuration for Docker GPU access. Say that only a separate host-side GPU service is not required after NVIDIA Container Toolkit is configured.

Proposed wording
-| The container manages its own GPU multi-process service internally; no host-side setup is required.
+| The container manages its own GPU multi-process service internally; after NVIDIA Container Toolkit is configured, no separate host-side GPU service is required.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
| Vocoder never becomes ready, or every request fails after warmup | Check `docker logs fish-audio` for vocoder startup errors. The container manages its own GPU multi-process service internally; no host-side setup is required. |
| Vocoder never becomes ready, or every request fails after warmup | Check `docker logs fish-audio` for vocoder startup errors. The container manages its own GPU multi-process service internally; after NVIDIA Container Toolkit is configured, no separate host-side GPU service is required. |
🧰 Tools
🪛 GitHub Check: Mintlify Validation (hanabiaiinc) - vale-spellcheck

[warning] 216-216: developer-guide/self-hosting/all-in-one.mdx#L216
Did you really mean 'Vocoder'?


[warning] 216-216: developer-guide/self-hosting/all-in-one.mdx#L216
Did you really mean 'vocoder'?

🤖 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` at 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.

| ----------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| 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
Replace the open-source self-hosting pages with guides for what is actually
delivered: the two Helm forms, the All-in-One appliance, registry access, and
the requirements each one really has.

The model-asset secret is described as what it is. Both the in-cluster store
and the workers read it — `rclone serve s3 --auth-key` on one side, the client
credentials on the other — so its value is yours to choose, but it is enforced
between them, and an operator rotating it has to restart both sides.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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