> ## Documentation Index
> Fetch the complete documentation index at: https://hanabiaiinc-fish-772-self-host-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Registry access

> Create a deploy token and authenticate Docker and Helm against the Fish Audio registry

Self-hosted images and charts are distributed from a private Fish Audio registry.
Your team authenticates to it with a **deploy token** that you create in the
fish.audio dashboard.

## Prerequisites

* Self-hosting enabled for your team under an enterprise agreement.
* A fish.audio account that is a member of that team.
* Docker, and Helm 3.8 or newer for the OCI chart commands.

If **Developer → Self Host** reports that self-host deployment is not enabled for
your team, contact your account manager.

Sign in to fish.audio and open **Developer → Self Host**. **Your deployment**
lists the delivery forms your team is granted; if it is empty, contact fish.audio
to get access. That page builds the install commands for your team, with the
registry host, the artifact references, and the version you pick already filled
in — copy them from there.

<Note>
  The registry host, the artifact references, and the versions available to you
  are shown in the dashboard and are specific to your team. This documentation
  writes them as placeholders such as `<registry-host>` and `<chart-reference>`.
</Note>

## Create a deploy token

<Steps>
  <Step title="Open the Deploy Tokens card">
    On **Developer → Self Host**, select **Create Deploy Token**.
  </Step>

  <Step title="Name it for where it will be used">
    Use a name that identifies the consumer, such as `prod-cluster` or
    `ci-mirror`. The name appears in the token list alongside the creation date
    and last-used time.
  </Step>

  <Step title="Copy the token immediately">
    The token value is shown once, at creation. Store it in your secret manager
    before closing the dialog. If you lose it, rotate the token to issue a new
    one.
  </Step>
</Steps>

A team can hold up to five deploy tokens at a time. Tokens carry the grants of
the team that owns them, not of the person who created them, and follow those
grants as they change — there is no token to recreate when your entitlement is
updated.

## Authenticate Docker

Set your values once, then reuse them in the commands below.

```bash theme={null}
REGISTRY_HOST='<registry-host>'
LOGIN_USER='<your-email>'
```

Read the token at a prompt rather than assigning it. Run this line on its own,
paste the token when the cursor moves to a blank line, and press Enter. Nothing is
echoed, and unlike an assignment the token does not end up in your shell history.

```bash theme={null}
read -rs DEPLOY_TOKEN
```

Sign in with your account email as the username and the deploy token as the
password:

```bash theme={null}
printf '%s' "$DEPLOY_TOKEN" | docker login "$REGISTRY_HOST" -u "$LOGIN_USER" --password-stdin
```

A successful login prints `Login Succeeded`. Teams granted the All-in-One form
can also verify a pull with the reference from
[All-in-One container](/developer-guide/self-hosting/all-in-one); Helm-only teams
verify against the chart in the next section.

## Authenticate Helm

Charts are served as OCI artifacts, so Helm authenticates against the same
registry host:

```bash theme={null}
helm registry login "$REGISTRY_HOST" -u "$LOGIN_USER" --password-stdin <<< "$DEPLOY_TOKEN"
```

Confirm the chart is reachable, using the version shown on the Self Host page:

```bash theme={null}
helm show chart '<chart-reference>' --version '<chart-version>'
```

## Create the Kubernetes pull secret

The cluster pulls images with the same credentials, in a pull secret the chart
expects to find in the release namespace. The token is fed in on standard input
rather than as an argument: `--docker-password` would put it in the process's
command line, where anyone else on the host can read it with `ps`.

```bash theme={null}
kubectl -n fish-audio create secret generic fish-audio-registry \
  --type=kubernetes.io/dockerconfigjson \
  --from-file=.dockerconfigjson=/dev/stdin \
  --dry-run=client -o yaml <<EOF | kubectl apply -f -
{"auths":{"$REGISTRY_HOST":{"auth":"$(printf '%s:%s' "$LOGIN_USER" "$DEPLOY_TOKEN" | base64 | tr -d '\n')"}}}
EOF
```

The secret is the same either way — `create secret docker-registry` is a shorthand
that builds this document for you.

Reference it from the release so every workload uses it:

```yaml theme={null}
global:
  imagePullSecrets:
    - name: fish-audio-registry
```

## Managing tokens

| Action    | Effect                                                                                                                                   |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| Rotate    | Issues a new token value and invalidates the old one immediately. Update every consumer before rotating, or new pods will fail to pull.  |
| Delete    | Revokes the token immediately. Any deployment still using it stops pulling images. Running pods keep running until they are rescheduled. |
| Last used | Shows when the token last authenticated, which identifies tokens that are safe to retire.                                                |

Recommended practice:

* Issue one token per consumer — production cluster, staging cluster, CI mirror —
  so a single revocation never takes down more than one of them.
* Store tokens in your secret manager, not in values files or version control.
* Rotate on your normal credential schedule and whenever someone with access to a
  token leaves the team.

## Next step

With the registry reachable, continue to
[Kubernetes deployment](/developer-guide/self-hosting/kubernetes) or the
[All-in-One container](/developer-guide/self-hosting/all-in-one).
