# yaml-language-server: $schema=https://schema.zeabur.app/template.json
apiVersion: zeabur.com/v1
kind: Template
metadata:
    name: RustDesk Server
spec:
    description: |
        Self-hosted RustDesk remote desktop server: official hbbs/hbbr rendezvous + relay,
        plus a custom Rust API and web admin dashboard for managing users and devices.
    coverImage: https://avatars.githubusercontent.com/u/79992466
    icon: https://raw.githubusercontent.com/rustdesk/rustdesk/master/res/logo.svg
    variables:
        - key: PUBLIC_DOMAIN
          type: DOMAIN
          name: Domain
          description: Domain for the RustDesk admin web dashboard (also serves the API via reverse proxy).
        - key: ID_SERVER_DOMAIN
          type: STRING
          name: ID Server Domain
          description: Your own domain (e.g. id.example.com) pointing to hbbs's forwarded host, so the RustDesk client can use a domain instead of a raw IP for the ID Server. After deployment, create a DNS A record for this domain pointing to the host shown in hbbs's Networking tab. Leave blank to use the raw forwarded IP instead.
        - key: RELAY_SERVER_DOMAIN
          type: STRING
          name: Relay Server Domain
          description: Your own domain (e.g. relay.example.com) pointing to hbbr's forwarded host, so the RustDesk client can use a domain instead of a raw IP for the Relay Server. After deployment, create a DNS A record for this domain pointing to the host shown in hbbr's Networking tab. Leave blank to use the raw forwarded IP instead.
    tags:
        - Remote Desktop
        - Networking
    readme: |
        # RustDesk Server

        Self-hosted [RustDesk](https://rustdesk.com) remote desktop server, deployed with:

        - **hbbs** / **hbbr** — the official RustDesk ID/rendezvous and relay servers ([rustdesk-server](https://github.com/rustdesk/rustdesk-server), GPL-3.0).
        - **api** — a custom Rust API server for user/device management, backed by MySQL.
        - **web** — a web admin dashboard (nginx + static SPA) for managing users, devices and address books.
        - **mysql** — database for the API server.

        ## After deployment

        1. Open the `web` admin dashboard at `https://<your-domain>`, and log in with the `ADMIN_USER` /
           `ADMIN_PASS` values shown in the `api` service's environment variables (default user `admin`,
           password is a randomly generated `${PASSWORD}` — check the `api` service's variables tab).
        2. Open the **Networking** tab of the `hbbs` and `hbbr` services to find the externally forwarded
           host/port for each port (21115/21116 on `hbbs`, 21117 on `hbbr`).
        3. (Optional, recommended) `hbbs`/`hbbr` use raw TCP/UDP, so Zeabur cannot bind a domain to them
           directly — the forwarded host is a bare IP that can change on redeploy. If you set
           `ID_SERVER_DOMAIN` / `RELAY_SERVER_DOMAIN`, create a DNS **A record** for each domain pointing
           to the forwarded host from step 2, so the ports below stay reachable at a stable name instead
           of a raw IP.
        4. In the RustDesk client, go to **Settings → Network** and set:
           - **ID Server**: `<ID_SERVER_DOMAIN, or hbbs forwarded host>:<hbbs 21116 forwarded port>`
           - **Relay Server**: `<RELAY_SERVER_DOMAIN, or hbbr forwarded host>:<hbbr 21117 forwarded port>`
           - **API Server**: `https://<your-domain>` (the `web` service reverse-proxies `/api/` to `api`)
           - **Key**: `hbbs` auto-generates an Ed25519 key pair the first time it starts, and persists it
             (`id_ed25519.pub` / `id_ed25519`) in its own data volume. Open a shell in the `hbbs` service
             (Zeabur's service Shell/exec) and run `cat id_ed25519.pub` to get the value. Required —
             clients without the matching key are rejected.

        ## Security note

        `hbbs` auto-generates its own Ed25519 key pair on first start and persists it in its mounted data
        volume, so it survives restarts and redeploys without any manual configuration. Clients must use
        the matching public key (`id_ed25519.pub`, retrieved as described above) to register with `hbbs`.

        `hbbr` runs with no key set, which is the RustDesk upstream default: it does not validate a relay
        key, since clients already need `hbbs`'s key to register a session in the first place. If you want
        `hbbr` to also validate the relay key, copy `hbbs`'s `id_ed25519` / `id_ed25519.pub` files into
        `hbbr`'s data volume and add `-k <the key>` to `hbbr`'s start command yourself.

        To rotate the key, delete `id_ed25519` / `id_ed25519.pub` from the `hbbs` service's data volume
        and restart `hbbs` — a new key pair is generated automatically.

        ## License

        - `hbbs`/`hbbr` are the official RustDesk server binaries, licensed under GPL-3.0.
          Source: https://github.com/rustdesk/rustdesk-server
        - The `api` and `web` services are custom components built for this deployment.
    services:
        - name: mysql
          icon: https://raw.githubusercontent.com/zeabur/service-icons/main/marketplace/mysql.svg
          template: PREBUILT_V2
          spec:
            id: mysql
            source:
                image: mysql:8.0
            ports:
                - id: database
                  port: 3306
                  type: TCP
            volumes:
                - id: data
                  dir: /var/lib/mysql
            instructions:
                - title: MySQL host
                  content: ${MYSQL_HOST}
                - title: MySQL port
                  content: ${MYSQL_PORT}
                - title: MySQL database
                  content: ${MYSQL_DATABASE}
                - title: MySQL user
                  content: ${MYSQL_USER}
                - title: MySQL password
                  content: ${MYSQL_PASSWORD}
            env:
                MYSQL_DATABASE:
                    default: rustdesk
                    expose: true
                MYSQL_HOST:
                    default: ${CONTAINER_HOSTNAME}
                    expose: true
                MYSQL_PASSWORD:
                    default: ${PASSWORD}
                    expose: true
                MYSQL_PORT:
                    default: ${DATABASE_PORT}
                    expose: true
                MYSQL_ROOT_PASSWORD:
                    default: ${PASSWORD}
                MYSQL_USER:
                    default: rustdesk
                    expose: true
            healthCheck:
                type: TCP
                port: database
        - name: hbbr
          icon: https://raw.githubusercontent.com/rustdesk/rustdesk/master/res/logo.svg
          template: PREBUILT_V2
          spec:
            id: hbbr
            source:
                image: rustdesk/rustdesk-server:1.1.16
                command:
                    - hbbr
            ports:
                - id: relay
                  port: 21117
                  type: TCP
                - id: relayweb
                  port: 21119
                  type: TCP
            volumes:
                - id: data
                  dir: /root
            instructions:
                - title: Relay Server (fill into RustDesk client "Relay Server")
                  content: ${PORT_FORWARDED_HOSTNAME}:${RELAY_PORT_FORWARDED_PORT}
                - title: Relay Server via domain (if RELAY_SERVER_DOMAIN is set; point its DNS A record to the host above)
                  content: ${RELAY_SERVER_DOMAIN}:${RELAY_PORT_FORWARDED_PORT}
            env:
                HBBR_HOST:
                    default: ${CONTAINER_HOSTNAME}
                    expose: true
            portForwarding:
                enabled: true
        - name: hbbs
          icon: https://raw.githubusercontent.com/rustdesk/rustdesk/master/res/logo.svg
          template: PREBUILT_V2
          spec:
            id: hbbs
            source:
                image: rustdesk/rustdesk-server:1.1.16
                command:
                    - hbbs
                    - -r
                    - ${HBBR_HOST}:21117
            ports:
                - id: nat
                  port: 21115
                  type: TCP
                - id: id
                  port: 21116
                  type: TCP
                - id: idudp
                  port: 21116
                  type: UDP
                - id: webclient
                  port: 21118
                  type: TCP
            volumes:
                - id: data
                  dir: /root
            instructions:
                - title: ID Server (fill into RustDesk client "ID Server")
                  content: ${PORT_FORWARDED_HOSTNAME}:${ID_PORT_FORWARDED_PORT}
                - title: ID Server via domain (if ID_SERVER_DOMAIN is set; point its DNS A record to the host above)
                  content: ${ID_SERVER_DOMAIN}:${ID_PORT_FORWARDED_PORT}
                - title: Key (auto-generated on first start; persisted in this service's data volume)
                  content: Open a shell in this service and run "cat id_ed25519.pub" to get the value for the client's "Key" field.
            portForwarding:
                enabled: true
        - name: api
          icon: https://raw.githubusercontent.com/rustdesk/rustdesk/master/res/logo.svg
          template: PREBUILT_V2
          spec:
            id: api
            source:
                image: es94111/rustdesk-api:6c462e0
            ports:
                - id: api
                  port: 21114
                  type: HTTP
            env:
                ADMIN_PASS:
                    default: ${PASSWORD}
                    expose: true
                ADMIN_USER:
                    default: admin
                    expose: true
                CORS_ORIGIN:
                    default: '*'
                DATABASE_URL:
                    default: mysql://${MYSQL_USER}:${MYSQL_PASSWORD}@${MYSQL_HOST}:${MYSQL_PORT}/${MYSQL_DATABASE}
                JWT_SECRET:
                    default: ${PASSWORD}
                LISTEN_ADDR:
                    default: 0.0.0.0:21114
            healthCheck:
                type: TCP
                port: api
        - name: web
          icon: https://raw.githubusercontent.com/rustdesk/rustdesk/master/res/logo.svg
          template: PREBUILT_V2
          spec:
            id: web
            source:
                image: es94111/rustdesk-web:6c462e0
            ports:
                - id: web
                  port: 80
                  type: HTTP
          domainKey: PUBLIC_DOMAIN
localization:
    es-ES:
        description: |
            Servidor RustDesk de escritorio remoto autoalojado: hbbs/hbbr oficiales (rendezvous y relay),
            además de una API en Rust y un panel de administración web para gestionar usuarios y dispositivos.
        variables:
            - key: PUBLIC_DOMAIN
              type: STRING
              name: Dominio
              description: Dominio para el panel de administración web de RustDesk (también sirve la API vía proxy inverso).
            - key: ID_SERVER_DOMAIN
              type: STRING
              name: Dominio del servidor de ID
              description: Tu propio dominio (p. ej. id.example.com) apuntando a la dirección externa de hbbs, para que el cliente de RustDesk pueda usar un dominio en vez de una IP en el ID Server. Después del despliegue, crea un registro DNS **A** para este dominio apuntando al host mostrado en la pestaña Networking de hbbs. Déjalo en blanco para usar la IP directamente.
            - key: RELAY_SERVER_DOMAIN
              type: STRING
              name: Dominio del servidor de Relay
              description: Tu propio dominio (p. ej. relay.example.com) apuntando a la dirección externa de hbbr, para que el cliente de RustDesk pueda usar un dominio en vez de una IP en el Relay Server. Después del despliegue, crea un registro DNS **A** para este dominio apuntando al host mostrado en la pestaña Networking de hbbr. Déjalo en blanco para usar la IP directamente.
        readme: |
            # RustDesk Server

            Servidor de escritorio remoto [RustDesk](https://rustdesk.com) autoalojado, desplegado con:

            - **hbbs** / **hbbr** — los servidores oficiales de RustDesk para rendezvous/ID y relay ([rustdesk-server](https://github.com/rustdesk/rustdesk-server), GPL-3.0).
            - **api** — un servidor API en Rust personalizado para gestionar usuarios/dispositivos, respaldado por MySQL.
            - **web** — un panel de administración web (nginx + SPA estática) para gestionar usuarios, dispositivos y libretas de direcciones.
            - **mysql** — base de datos para el servidor API.

            ## Después del despliegue

            1. Abre `https://<tu-dominio>` para acceder al panel `web`, e inicia sesión con los valores
               `ADMIN_USER` / `ADMIN_PASS` que aparecen en las variables de entorno del servicio `api`
               (usuario por defecto `admin`, contraseña generada aleatoriamente `${PASSWORD}`).
            2. Abre la pestaña **Networking** de los servicios `hbbs` y `hbbr` para ver el host/puerto
               reenviado externamente (21115/21116 en `hbbs`, 21117 en `hbbr`).
            3. (Opcional, recomendado) `hbbs`/`hbbr` usan TCP/UDP crudo, así que Zeabur no puede enlazar un
               dominio directamente — el host reenviado es una IP que puede cambiar al redesplegar. Si
               configuraste `ID_SERVER_DOMAIN` / `RELAY_SERVER_DOMAIN`, crea un registro DNS **A** para cada
               dominio apuntando al host del paso 2, así los puertos de abajo quedan accesibles con un nombre
               estable en vez de una IP.
            4. En el cliente de RustDesk, ve a **Settings → Network** y configura:
               - **ID Server**: `<ID_SERVER_DOMAIN, o el host reenviado de hbbs>:<puerto reenviado 21116 de hbbs>`
               - **Relay Server**: `<RELAY_SERVER_DOMAIN, o el host reenviado de hbbr>:<puerto reenviado 21117 de hbbr>`
               - **API Server**: `https://<tu-dominio>` (el servicio `web` reenvía `/api/` a `api` vía proxy inverso)
               - **Key**: `hbbs` genera automáticamente un par de claves Ed25519 la primera vez que arranca, y
                 lo persiste (`id_ed25519.pub` / `id_ed25519`) en su propio volumen de datos. Abre una shell en
                 el servicio `hbbs` (Shell/exec de Zeabur) y ejecuta `cat id_ed25519.pub` para obtenerla.
                 Obligatoria — los clientes sin la clave correcta serán rechazados.

            ## Nota de seguridad

            `hbbs` genera automáticamente su propio par de claves Ed25519 en el primer arranque y lo persiste
            en su volumen de datos montado, así que sobrevive a reinicios y redespliegues sin ninguna
            configuración manual. Los clientes deben usar la clave pública correspondiente (`id_ed25519.pub`,
            obtenida como se describe arriba) para registrarse en `hbbs`.

            `hbbr` arranca sin ninguna clave configurada, que es el comportamiento por defecto de RustDesk:
            como los clientes ya necesitan la clave de `hbbs` para registrar una sesión, `hbbr` no valida
            ninguna clave. Si quieres que `hbbr` también valide la clave de relay, copia los archivos
            `id_ed25519` / `id_ed25519.pub` de `hbbs` al volumen de datos de `hbbr` y añade `-k <esa clave>`
            al comando de inicio de `hbbr` tú mismo.

            Para rotar la clave, borra `id_ed25519` / `id_ed25519.pub` del volumen de datos del servicio
            `hbbs` y reinícialo — se generará un nuevo par de claves automáticamente.

            ## Licencia

            - `hbbs`/`hbbr` son los binarios oficiales del servidor RustDesk, con licencia GPL-3.0.
              Código fuente: https://github.com/rustdesk/rustdesk-server
            - Los servicios `api` y `web` son componentes personalizados creados para este despliegue.
    id-ID:
        description: |
            Server remote desktop RustDesk self-hosted: hbbs/hbbr resmi (rendezvous & relay), ditambah
            API Rust dan dashboard admin web kustom untuk mengelola pengguna dan perangkat.
        variables:
            - key: PUBLIC_DOMAIN
              type: STRING
              name: Domain
              description: Domain untuk dashboard admin web RustDesk (juga menyajikan API lewat reverse proxy).
            - key: ID_SERVER_DOMAIN
              type: STRING
              name: Domain ID Server
              description: Domain milik Anda sendiri (mis. id.example.com) yang mengarah ke alamat eksternal hbbs, agar klien RustDesk bisa memakai domain, bukan IP mentah, di ID Server. Setelah deploy, buat DNS record **A** untuk domain ini mengarah ke host yang tampil di tab Networking hbbs. Biarkan kosong untuk memakai IP mentah.
            - key: RELAY_SERVER_DOMAIN
              type: STRING
              name: Domain Relay Server
              description: Domain milik Anda sendiri (mis. relay.example.com) yang mengarah ke alamat eksternal hbbr, agar klien RustDesk bisa memakai domain, bukan IP mentah, di Relay Server. Setelah deploy, buat DNS record **A** untuk domain ini mengarah ke host yang tampil di tab Networking hbbr. Biarkan kosong untuk memakai IP mentah.
        readme: |
            # RustDesk Server

            Server remote desktop [RustDesk](https://rustdesk.com) self-hosted, mencakup:

            - **hbbs** / **hbbr** — server ID/rendezvous dan relay resmi RustDesk ([rustdesk-server](https://github.com/rustdesk/rustdesk-server), lisensi GPL-3.0).
            - **api** — server API Rust kustom untuk manajemen pengguna/perangkat, menggunakan MySQL.
            - **web** — dashboard admin web (nginx + SPA statis) untuk mengelola pengguna, perangkat, dan address book.
            - **mysql** — database untuk server API.

            ## Setelah deploy

            1. Buka `https://<domain-anda>` untuk masuk ke dashboard `web`, login menggunakan nilai
               `ADMIN_USER` / `ADMIN_PASS` pada environment variable layanan `api` (default `admin`,
               password dibuat otomatis via `${PASSWORD}`, cek di tab variabel layanan `api`).
            2. Buka tab **Networking** pada layanan `hbbs` dan `hbbr` untuk melihat host/port yang
               diteruskan secara eksternal (21115/21116 pada `hbbs`, 21117 pada `hbbr`).
            3. (Opsional, disarankan) `hbbs`/`hbbr` memakai TCP/UDP mentah, jadi Zeabur tidak bisa mengikat
               domain langsung — host yang diteruskan berupa IP mentah yang bisa berubah saat redeploy. Jika
               Anda mengisi `ID_SERVER_DOMAIN` / `RELAY_SERVER_DOMAIN`, buat DNS record **A** untuk masing-masing
               domain mengarah ke host dari langkah 2, agar port di bawah tetap bisa diakses lewat nama domain
               yang stabil, bukan IP mentah.
            4. Pada klien RustDesk, buka **Settings → Network** lalu isi:
               - **ID Server**: `<ID_SERVER_DOMAIN, atau host hbbs yang diteruskan>:<port 21116 hbbs yang diteruskan>`
               - **Relay Server**: `<RELAY_SERVER_DOMAIN, atau host hbbr yang diteruskan>:<port 21117 hbbr yang diteruskan>`
               - **API Server**: `https://<domain-anda>` (layanan `web` mem-proxy `/api/` ke `api`)
               - **Key**: `hbbs` otomatis membuat sepasang kunci Ed25519 saat pertama kali start, dan
                 menyimpannya (`id_ed25519.pub` / `id_ed25519`) secara persisten di volume data miliknya
                 sendiri. Buka shell di layanan `hbbs` (fitur Shell/exec Zeabur) lalu jalankan
                 `cat id_ed25519.pub` untuk mendapatkan nilainya. Wajib diisi — klien tanpa kunci yang cocok
                 akan ditolak.

            ## Catatan keamanan

            `hbbs` otomatis membuat pasangan kunci Ed25519 miliknya sendiri saat pertama kali start, dan
            menyimpannya secara persisten di volume data yang ter-mount, sehingga tidak hilang saat restart
            atau redeploy dan tidak perlu konfigurasi manual apa pun. Klien harus memakai kunci publik yang
            sesuai (`id_ed25519.pub`, cara mendapatkannya lihat di atas) untuk mendaftar ke `hbbs`.

            `hbbr` dijalankan tanpa kunci sama sekali, ini adalah perilaku default resmi RustDesk: karena
            klien sudah butuh kunci `hbbs` lebih dulu untuk mendaftarkan sesi, `hbbr` tidak memvalidasi kunci
            apa pun. Jika Anda ingin `hbbr` juga memvalidasi kunci relay, salin file `id_ed25519` /
            `id_ed25519.pub` milik `hbbs` ke volume data `hbbr`, lalu tambahkan `-k <kunci tersebut>` sendiri
            ke perintah start `hbbr`.

            Untuk merotasi kunci, hapus `id_ed25519` / `id_ed25519.pub` dari volume data layanan `hbbs` lalu
            restart `hbbs` — pasangan kunci baru akan dibuat otomatis.

            ## Lisensi

            - `hbbs`/`hbbr` adalah binari resmi server RustDesk, berlisensi GPL-3.0.
              Sumber: https://github.com/rustdesk/rustdesk-server
            - Layanan `api` dan `web` adalah komponen kustom yang dibuat untuk deployment ini.
    ja-JP:
        description: |
            セルフホスト型の RustDesk リモートデスクトップサーバー。公式の hbbs/hbbr（ランデブー・リレー）に加え、
            ユーザーとデバイスを管理するための自作 Rust API と Web 管理ダッシュボードを含みます。
        variables:
            - key: PUBLIC_DOMAIN
              type: STRING
              name: ドメイン
              description: RustDesk 管理ダッシュボードのドメイン（リバースプロキシ経由で API も提供）。
            - key: ID_SERVER_DOMAIN
              type: STRING
              name: ID サーバードメイン
              description: 'hbbs の外部接続先を指す独自ドメイン（例: id.example.com）。RustDesk クライアントの ID サーバー欄に 生の IP ではなくドメインを設定できます。デプロイ後、hbbs の「ネットワーク」タブに表示されるホストへ このドメインの DNS **A レコード**を作成してください。空欄の場合は生の IP がそのまま使われます。'
            - key: RELAY_SERVER_DOMAIN
              type: STRING
              name: リレーサーバードメイン
              description: 'hbbr の外部接続先を指す独自ドメイン（例: relay.example.com）。RustDesk クライアントのリレーサーバー欄に 生の IP ではなくドメインを設定できます。デプロイ後、hbbr の「ネットワーク」タブに表示されるホストへ このドメインの DNS **A レコード**を作成してください。空欄の場合は生の IP がそのまま使われます。'
        readme: |
            # RustDesk Server

            セルフホスト型の [RustDesk](https://rustdesk.com) リモートデスクトップサーバーです。構成:

            - **hbbs** / **hbbr** — 公式の RustDesk ID/ランデブーサーバーとリレーサーバー（[rustdesk-server](https://github.com/rustdesk/rustdesk-server)、GPL-3.0）。
            - **api** — ユーザー/デバイス管理用の自作 Rust API サーバー（MySQL を使用）。
            - **web** — Web 管理ダッシュボード（nginx + 静的 SPA）。ユーザー、デバイス、アドレス帳を管理。
            - **mysql** — API サーバー用データベース。

            ## デプロイ後の設定

            1. `https://<あなたのドメイン>` を開いて `web` 管理ダッシュボードにアクセスし、`api` サービスの環境変数にある
               `ADMIN_USER` / `ADMIN_PASS` でログインします（デフォルトユーザーは `admin`、パスワードは自動生成された
               `${PASSWORD}`。`api` サービスの変数タブで確認してください）。
            2. `hbbs` と `hbbr` サービスの「ネットワーク」タブで、外部に転送されているホスト/ポート
               （`hbbs` は 21115/21116、`hbbr` は 21117）を確認します。
            3.（任意・推奨）`hbbs`/`hbbr` は生の TCP/UDP を使用するため、Zeabur は直接ドメインを紐付けられません
               ——外部ホストは生の IP で、再デプロイ時に変わることがあります。`ID_SERVER_DOMAIN` /
               `RELAY_SERVER_DOMAIN` を設定した場合は、それぞれのドメインの DNS **A レコード**を手順 2 で
               確認したホストへ向けて作成してください。以降は下記ポートに固定ドメインで接続できます。
            4. RustDesk クライアントの「設定 → ネットワーク」で以下を設定します:
               - **ID サーバー**: `<ID_SERVER_DOMAIN、または hbbs の外部ホスト>:<hbbs 21116 の外部ポート>`
               - **リレーサーバー**: `<RELAY_SERVER_DOMAIN、または hbbr の外部ホスト>:<hbbr 21117 の外部ポート>`
               - **API サーバー**: `https://<あなたのドメイン>`（`web` サービスが `/api/` を `api` へリバースプロキシします）
               - **キー**: `hbbs` は初回起動時に Ed25519 鍵ペアを自動生成し、自身のデータボリュームに
                 （`id_ed25519.pub` / `id_ed25519` として）永続化します。`hbbs` サービスでシェルを開き
                 （Zeabur の Shell/exec 機能）、`cat id_ed25519.pub` を実行すると値を取得できます。
                 必須項目です——一致するキーを持たないクライアントは拒否されます。

            ## セキュリティに関する注意

            `hbbs` は初回起動時に自身の Ed25519 鍵ペアを自動生成し、マウントされたデータボリュームに永続化
            するため、再起動や再デプロイをしても失われず、手動設定も不要です。クライアントは対応する公開鍵
            （`id_ed25519.pub`、取得方法は上記参照）を使って `hbbs` に登録する必要があります。

            `hbbr` はキーを設定せずに起動します。これは RustDesk 本家のデフォルト動作で、クライアントはそもそも
            `hbbs` のキーがないとセッション登録できないため、`hbbr` 側ではキー検証を行いません。`hbbr` でも
            リレーキーの検証を有効にしたい場合は、`hbbs` の `id_ed25519` / `id_ed25519.pub` を `hbbr` の
            データボリュームにコピーし、`hbbr` の起動コマンドに `-k <そのキー>` を自分で追加してください。

            キーをローテーションするには、`hbbs` サービスのデータボリュームから `id_ed25519` /
            `id_ed25519.pub` を削除して `hbbs` を再起動すれば、新しい鍵ペアが自動生成されます。

            ## ライセンス

            - `hbbs`/`hbbr` は公式の RustDesk サーバーバイナリで、GPL-3.0 ライセンスです。ソース: https://github.com/rustdesk/rustdesk-server
            - `api` と `web` はこのデプロイ用に作成された独自コンポーネントです。
    zh-CN:
        description: |
            自建 RustDesk 远程桌面服务器：官方 hbbs/hbbr 中继与转发服务器，加上自制的 Rust API 与网页管理后台，
            用于管理用户与设备。
        variables:
            - key: PUBLIC_DOMAIN
              type: STRING
              name: 域名
              description: RustDesk 管理后台使用的域名（也会通过反向代理提供 API）。
            - key: ID_SERVER_DOMAIN
              type: STRING
              name: ID 服务器域名
              description: 你自己的域名（例如 id.example.com），指向 hbbs 的对外连接地址，让 RustDesk 客户端可以用域名 而不是裸 IP 填写 ID 服务器。部署后请到你的 DNS 服务商为该域名新增 A 记录，指向 hbbs「网络」 标签页显示的对外主机。留空则直接使用裸 IP。
            - key: RELAY_SERVER_DOMAIN
              type: STRING
              name: 中继服务器域名
              description: 你自己的域名（例如 relay.example.com），指向 hbbr 的对外连接地址，让 RustDesk 客户端可以用域名 而不是裸 IP 填写中继服务器。部署后请到你的 DNS 服务商为该域名新增 A 记录，指向 hbbr「网络」 标签页显示的对外主机。留空则直接使用裸 IP。
        readme: |
            # RustDesk Server

            自建的 [RustDesk](https://rustdesk.com) 远程桌面服务器，部署内容包含：

            - **hbbs** / **hbbr** — 官方 RustDesk ID/中继服务器与转发服务器（[rustdesk-server](https://github.com/rustdesk/rustdesk-server)，GPL-3.0 许可）。
            - **api** — 自制 Rust API 服务器，负责用户/设备管理，数据存于 MySQL。
            - **web** — 网页管理后台（nginx + 静态 SPA），可管理用户、设备与通讯录。
            - **mysql** — API 服务器使用的数据库。

            ## 部署后设置

            1. 打开 `https://<你的域名>` 进入 `web` 管理后台，使用 `api` 服务环境变量中的 `ADMIN_USER` /
               `ADMIN_PASS` 登录（默认账号 `admin`，密码为自动生成的 `${PASSWORD}`，请到 `api` 服务的变量页查看）。
            2. 到 `hbbs` 与 `hbbr` 服务的「网络」标签页，查看对外转发的主机与端口（`hbbs` 的 21115/21116，`hbbr` 的 21117）。
            3.（可选，建议设置）`hbbs`/`hbbr` 使用原始 TCP/UDP，Zeabur 无法直接为其绑定域名——对外主机是裸 IP，
               重新部署后可能变化。若你填写了 `ID_SERVER_DOMAIN` / `RELAY_SERVER_DOMAIN`，请为这两个域名分别新增
               DNS **A 记录**，指向步骤 2 中查到的对外主机，之后下方端口就能通过固定域名连接，而不用裸 IP。
            4. 在 RustDesk 客户端「设置 → 网络」填入：
               - **ID 服务器**：`<ID_SERVER_DOMAIN，或 hbbs 对外主机>:<hbbs 21116 对外端口>`
               - **中继服务器**：`<RELAY_SERVER_DOMAIN，或 hbbr 对外主机>:<hbbr 21117 对外端口>`
               - **API 服务器**：`https://<你的域名>`（`web` 服务会把 `/api/` 反向代理到 `api`）
               - **Key**：`hbbs` 首次启动时会自动生成一组 Ed25519 密钥对，并保存（`id_ed25519.pub` /
                 `id_ed25519`）在自己的数据 volume 中。到 `hbbs` 服务打开 Shell（Zeabur 的 Shell / exec 功能），
                 执行 `cat id_ed25519.pub` 即可获取。必填——没有对应密钥的客户端会被拒绝连接。

            ## 安全提示

            `hbbs` 首次启动时会自动生成自己的 Ed25519 密钥对，并保存在挂载的数据 volume 中，重启或重新部署
            都不会丢失，也不需要任何手动设置。客户端必须使用对应的公钥（`id_ed25519.pub`，获取方式见上方）
            才能向 `hbbs` 注册。

            `hbbr` 不设置密钥即启动，这是 RustDesk 官方默认行为：因为客户端一开始就需要 `hbbs` 的密钥才能
            注册连接，所以 `hbbr` 端不校验密钥。若你想让 `hbbr` 也校验中继密钥，可以把 `hbbs` 的
            `id_ed25519` / `id_ed25519.pub` 复制到 `hbbr` 的数据 volume 中，并自行在 `hbbr` 的启动命令加上
            `-k <该密钥>`。

            若要更换密钥，删除 `hbbs` 服务数据 volume 中的 `id_ed25519` / `id_ed25519.pub`，重新启动
            `hbbs` 即会自动生成新的密钥对。

            ## 许可

            - `hbbs`/`hbbr` 为官方 RustDesk 服务器可执行文件，采用 GPL-3.0 许可，源码：https://github.com/rustdesk/rustdesk-server
            - `api` 与 `web` 为此部署自制的组件。
    zh-TW:
        description: |
            自架 RustDesk 遠端桌面伺服器：官方 hbbs/hbbr 中繼與轉發伺服器，加上自製的 Rust API 與網頁管理後台，
            用於管理使用者與裝置。
        variables:
            - key: PUBLIC_DOMAIN
              type: STRING
              name: 網域
              description: RustDesk 管理後台使用的網域（也會透過反向代理提供 API）。
            - key: ID_SERVER_DOMAIN
              type: STRING
              name: ID 伺服器網域
              description: 你自己的網域（例如 id.example.com），指向 hbbs 的對外連線位址，讓 RustDesk 用戶端可以用網域 而非裸 IP 填寫 ID 伺服器。部署後請在你的 DNS 服務商為此網域新增 A 記錄，指向 hbbs「網路」分頁 顯示的對外主機。留空則直接使用裸 IP。
            - key: RELAY_SERVER_DOMAIN
              type: STRING
              name: 中繼伺服器網域
              description: 你自己的網域（例如 relay.example.com），指向 hbbr 的對外連線位址，讓 RustDesk 用戶端可以用網域 而非裸 IP 填寫中繼伺服器。部署後請在你的 DNS 服務商為此網域新增 A 記錄，指向 hbbr「網路」分頁 顯示的對外主機。留空則直接使用裸 IP。
        readme: |
            # RustDesk Server

            自架的 [RustDesk](https://rustdesk.com) 遠端桌面伺服器，部署內容包含：

            - **hbbs** / **hbbr** — 官方 RustDesk ID/中繼伺服器與轉發伺服器（[rustdesk-server](https://github.com/rustdesk/rustdesk-server)，GPL-3.0 授權）。
            - **api** — 自製 Rust API 伺服器，負責使用者/裝置管理，資料存於 MySQL。
            - **web** — 網頁管理後台（nginx + 靜態 SPA），可管理使用者、裝置與通訊錄。
            - **mysql** — API 伺服器使用的資料庫。

            ## 部署後設定

            1. 開啟 `https://<你的網域>` 進入 `web` 管理後台，使用 `api` 服務環境變數中的 `ADMIN_USER` /
               `ADMIN_PASS` 登入（預設帳號 `admin`，密碼為自動產生的 `${PASSWORD}`，請至 `api` 服務的變數頁查看）。
            2. 到 `hbbs` 與 `hbbr` 服務的「網路」分頁，查看對外轉發的主機與連接埠（`hbbs` 的 21115/21116，`hbbr` 的 21117）。
            3.（選填，建議設定）`hbbs`/`hbbr` 使用原始 TCP/UDP，Zeabur 無法直接為其綁定網域——對外主機是裸 IP，
               重新部署後可能變動。若你有填寫 `ID_SERVER_DOMAIN` / `RELAY_SERVER_DOMAIN`，請為這兩個網域各自新增
               DNS **A 記錄**，指向步驟 2 查到的對外主機，之後下方連接埠就能透過固定網域連線，不必用裸 IP。
            4. 在 RustDesk 用戶端「設定 → 網路」填入：
               - **ID 伺服器**：`<ID_SERVER_DOMAIN，或 hbbs 對外主機>:<hbbs 21116 對外連接埠>`
               - **中繼伺服器**：`<RELAY_SERVER_DOMAIN，或 hbbr 對外主機>:<hbbr 21117 對外連接埠>`
               - **API 伺服器**：`https://<你的網域>`（`web` 服務會將 `/api/` 反向代理到 `api`）
               - **Key**：`hbbs` 第一次啟動時會自動產生一組 Ed25519 金鑰對，並保存（`id_ed25519.pub` /
                 `id_ed25519`）在自己的資料 volume 中。到 `hbbs` 服務開啟 Shell（Zeabur 的 Shell / exec 功能），
                 執行 `cat id_ed25519.pub` 即可取得。必填——沒有對應金鑰的用戶端會被拒絕連線。

            ## 安全性提醒

            `hbbs` 首次啟動時會自動產生自己的 Ed25519 金鑰對，並保存在掛載的資料 volume 中，重啟或重新部署
            都不會遺失，也不需要任何手動設定。用戶端必須使用對應的公鑰（`id_ed25519.pub`，取得方式見上方）
            才能向 `hbbs` 註冊。

            `hbbr` 未設定金鑰即啟動，這是 RustDesk 官方預設行為：因為用戶端一開始就需要 `hbbs` 的金鑰才能
            註冊連線，所以 `hbbr` 端不驗證金鑰。若你想讓 `hbbr` 也驗證中繼金鑰，可以把 `hbbs` 的
            `id_ed25519` / `id_ed25519.pub` 複製到 `hbbr` 的資料 volume 中，並自行在 `hbbr` 的啟動指令加上
            `-k <該金鑰>`。

            若要更換金鑰，刪除 `hbbs` 服務資料 volume 中的 `id_ed25519` / `id_ed25519.pub`，重新啟動
            `hbbs` 即會自動產生新的金鑰對。

            ## 授權

            - `hbbs`/`hbbr` 為官方 RustDesk 伺服器執行檔，採 GPL-3.0 授權，原始碼：https://github.com/rustdesk/rustdesk-server
            - `api` 與 `web` 為此部署自製的元件。
