# yaml-language-server: $schema=https://schema.zeabur.app/template.json
apiVersion: zeabur.com/v1
kind: Template
metadata:
    name: jitsi-meeting
spec:
    description: |
        Self-hosted Jitsi Meet stack for multi-party video conferencing with JWT
        authentication enabled: only users holding tokens issued by your own backend can
        create/join rooms. A collaborative Excalidraw whiteboard backend is included.
    coverImage: https://files.catbox.moe/oi0w46.png
    icon: https://raw.githubusercontent.com/jitsi/jitsi-meet/master/images/apple-touch-icon.png
    variables:
        - key: JITSI_DOMAIN
          type: DOMAIN
          name: Jitsi Meet 域名
          description: Jitsi Meet Web 服务的公开子域名（例如 my-jitsi）。
        - key: WHITEBOARD_DOMAIN
          type: DOMAIN
          name: 白板后端域名
          description: Excalidraw 白板后端的公开子域名（例如 my-jitsi-wb）。
    tags:
        - Communication
        - Video
        - Jitsi
    readme: |
        # Jitsi Meet

        This template deploys a complete, self-hosted **Jitsi Meet** stack plus a
        collaborative whiteboard backend:

        - **jitsi-prosody** — XMPP server (JWT auth enabled, guest domain on)
        - **jitsi-jicofo** — Conference focus for media routing
        - **jitsi-jvb** — Jitsi Videobridge (UDP media forwarding enabled)
        - **jitsi-web** — Jitsi Meet web UI (zh-CN default, prejoin page off)
        - **jitsi-whiteboard** — `@jitsi/excalidraw-backend` collaboration server

        Authentication is JWT-based: your own backend issues tokens for guests, who
        join via `<url>?jwt=<token>`. Set these env vars on your app service after
        deploying:

        - `JITSI_BASE_URL` = `https://<JITSI_DOMAIN>.zeabur.app`
        - `WHITEBOARD_URL` = `https://<WHITEBOARD_DOMAIN>.zeabur.app`
        - `JITSI_JWT_APP_ID` / `JITSI_JWT_APP_SECRET` = the auto-generated `JWT_APP_ID` / `JWT_APP_SECRET` values shown in the jitsi-web service env

        Guests open the Jitsi URL with `?jwt=<token>`; anonymous room creation is
        disabled (`JWT_ALLOW_EMPTY=0`).

        > Note: JVB has UDP port forwarding enabled — external participants send/receive
        > media over the forwarded UDP port.
    resourceRequirement:
        minConfig:
            cpu: 2
            ram: 2
        recommendedConfig:
            cpu: 4
            ram: 4
    services:
        - name: jitsi-prosody
          icon: https://raw.githubusercontent.com/jitsi/jitsi-meet/master/images/apple-touch-icon.png
          template: PREBUILT
          spec:
            id: jitsi-prosody
            source:
                image: ghcr.io/jitsi/prosody:stable-11146
                runAsUserID: 1000
            ports:
                - id: c2s
                  port: 5222
                  type: TCP
                - id: bosh
                  port: 5280
                  type: TCP
            volumes:
                - id: config
                  dir: /config
            instructions:
                - title: XMPP 端点（仅集群内部访问）
                  content: jitsi-prosody.zeabur.internal:5222 (c2s) / :5280 (bosh)
                - title: Jicofo XMPP 密码（内部组件认证用，无需手填）
                  content: ${JICOFO_AUTH_PASSWORD}
                - title: JVB XMPP 密码（内部组件认证用，无需手填）
                  content: ${JVB_AUTH_PASSWORD}
            env:
                AUTH_TYPE:
                    default: jwt
                    expose: false
                DISABLE_HTTPS:
                    default: "1"
                    expose: false
                ENABLE_AUTH:
                    default: "1"
                    expose: false
                ENABLE_GUESTS:
                    default: "1"
                    expose: false
                ENABLE_LETSENCRYPT:
                    default: "0"
                    expose: false
                JICOFO_AUTH_PASSWORD:
                    default: ${PASSWORD}
                    expose: true
                JICOFO_AUTH_USER:
                    default: focus
                    expose: false
                JVB_AUTH_PASSWORD:
                    default: ${PASSWORD}
                    expose: true
                JVB_AUTH_USER:
                    default: jvb
                    expose: false
                JWT_ALLOW_EMPTY:
                    default: "0"
                    expose: false
                JWT_APP_ID:
                    default: ${PASSWORD}
                    expose: true
                JWT_APP_SECRET:
                    default: ${PASSWORD}
                    expose: true
                TZ:
                    default: UTC
                    expose: false
                XMPP_AUTH_DOMAIN:
                    default: auth.meet.jitsi
                    expose: false
                XMPP_DOMAIN:
                    default: meet.jitsi
                    expose: false
                XMPP_INTERNAL_MUC_DOMAIN:
                    default: internal-muc.meet.jitsi
                    expose: false
                XMPP_MUC_DOMAIN:
                    default: muc.meet.jitsi
                    expose: false
                XMPP_PORT:
                    default: "5222"
                    expose: false
                XMPP_SERVER:
                    default: localhost
                    expose: false
        - name: jitsi-jicofo
          icon: https://raw.githubusercontent.com/jitsi/jitsi-meet/master/images/apple-touch-icon.png
          dependencies:
            - jitsi-prosody
          template: PREBUILT
          spec:
            id: jitsi-jicofo
            source:
                image: ghcr.io/jitsi/jicofo:stable-11146
                runAsUserID: 1000
            volumes:
                - id: config
                  dir: /config
            env:
                JICOFO_AUTH_PASSWORD:
                    default: ${JICOFO_AUTH_PASSWORD}
                    expose: false
                JICOFO_AUTH_USER:
                    default: focus
                    expose: false
                JICOFO_MAX_MEMORY:
                    default: 128m
                    expose: false
                JVB_AUTH_PASSWORD:
                    default: ${JVB_AUTH_PASSWORD}
                    expose: false
                TZ:
                    default: UTC
                    expose: false
                XMPP_AUTH_DOMAIN:
                    default: auth.meet.jitsi
                    expose: false
                XMPP_DOMAIN:
                    default: meet.jitsi
                    expose: false
                XMPP_INTERNAL_MUC_DOMAIN:
                    default: internal-muc.meet.jitsi
                    expose: false
                XMPP_MUC_DOMAIN:
                    default: muc.meet.jitsi
                    expose: false
                XMPP_PORT:
                    default: "5222"
                    expose: false
                XMPP_SERVER:
                    default: jitsi-prosody.zeabur.internal
                    expose: false
        - name: jitsi-jvb
          icon: https://raw.githubusercontent.com/jitsi/jitsi-meet/master/images/apple-touch-icon.png
          dependencies:
            - jitsi-prosody
          template: PREBUILT
          spec:
            id: jitsi-jvb
            source:
                image: ghcr.io/jitsi/jvb:stable-11146
                runAsUserID: 1000
            ports:
                - id: media
                  port: 10000
                  type: UDP
            volumes:
                - id: config
                  dir: /config
            instructions:
                - title: 对外媒体地址（UDP，防火墙需放行）
                  content: ${PORT_FORWARDED_HOSTNAME}:${MEDIA_PORT_FORWARDED_PORT}/udp
            env:
                DISABLE_HTTPS:
                    default: "1"
                    expose: false
                JVB_ADVERTISE_PRIVATE_CANDIDATES:
                    default: "false"
                    expose: false
                JVB_AUTH_PASSWORD:
                    default: ${JVB_AUTH_PASSWORD}
                    expose: false
                JVB_AUTH_USER:
                    default: jvb
                    expose: false
                JVB_PORT:
                    default: "10000"
                    expose: false
                TZ:
                    default: UTC
                    expose: false
                VIDEOBRIDGE_MAX_MEMORY:
                    default: 256m
                    expose: false
                XMPP_AUTH_DOMAIN:
                    default: auth.meet.jitsi
                    expose: false
                XMPP_DOMAIN:
                    default: meet.jitsi
                    expose: false
                XMPP_INTERNAL_MUC_DOMAIN:
                    default: internal-muc.meet.jitsi
                    expose: false
                XMPP_PORT:
                    default: "5222"
                    expose: false
                XMPP_SERVER:
                    default: jitsi-prosody.zeabur.internal
                    expose: false
            portForwarding:
                enabled: true
        - name: jitsi-web
          icon: https://raw.githubusercontent.com/jitsi/jitsi-meet/master/images/apple-touch-icon.png
          dependencies:
            - jitsi-prosody
            - jitsi-jicofo
            - jitsi-jvb
          template: PREBUILT
          spec:
            id: jitsi-web
            source:
                image: ghcr.io/jitsi/web:stable-11146
                runAsUserID: 1000
            ports:
                - id: web
                  port: 8000
                  type: HTTP
            volumes:
                - id: config
                  dir: /config
            instructions:
                - title: 打开 Jitsi Meet
                  content: https://${JITSI_DOMAIN}.zeabur.app
                - title: 访客入会链接格式
                  content: https://${JITSI_DOMAIN}.zeabur.app/<房间号>?jwt=<token>
                - title: Jitsi JWT App ID（填入你的应用）
                  content: ${JWT_APP_ID}
                - title: Jitsi JWT App Secret（填入你的应用）
                  content: ${JWT_APP_SECRET}
            env:
                AUTH_TYPE:
                    default: jwt
                    expose: false
                DEFAULT_LANGUAGE:
                    default: zhCN
                    expose: false
                DISABLE_HTTPS:
                    default: "1"
                    expose: false
                ENABLE_AUTH:
                    default: "1"
                    expose: false
                ENABLE_GUESTS:
                    default: "1"
                    expose: false
                ENABLE_LETSENCRYPT:
                    default: "0"
                    expose: false
                ENABLE_PREJOIN_PAGE:
                    default: "false"
                    expose: false
                JICOFO_AUTH_PASSWORD:
                    default: ${JICOFO_AUTH_PASSWORD}
                    expose: false
                JICOFO_AUTH_USER:
                    default: focus
                    expose: false
                JVB_AUTH_PASSWORD:
                    default: ${JVB_AUTH_PASSWORD}
                    expose: false
                JVB_AUTH_USER:
                    default: jvb
                    expose: false
                JWT_ALLOW_EMPTY:
                    default: "0"
                    expose: false
                JWT_APP_ID:
                    default: ${JWT_APP_ID}
                    expose: true
                JWT_APP_SECRET:
                    default: ${JWT_APP_SECRET}
                    expose: true
                LANG_DETECTION:
                    default: "false"
                    expose: false
                PUBLIC_URL:
                    default: https://${JITSI_DOMAIN}.zeabur.app
                    expose: true
                START_WITH_AUDIO_MUTED:
                    default: "true"
                    expose: false
                START_WITH_VIDEO_MUTED:
                    default: "true"
                    expose: false
                TZ:
                    default: UTC
                    expose: false
                XMPP_AUTH_DOMAIN:
                    default: auth.meet.jitsi
                    expose: false
                XMPP_BOSH_URL_BASE:
                    default: http://jitsi-prosody.zeabur.internal:5280
                    expose: false
                XMPP_DOMAIN:
                    default: meet.jitsi
                    expose: false
                XMPP_INTERNAL_MUC_DOMAIN:
                    default: internal-muc.meet.jitsi
                    expose: false
                XMPP_MUC_DOMAIN:
                    default: muc.meet.jitsi
                    expose: false
                XMPP_PORT:
                    default: "5222"
                    expose: false
                XMPP_SERVER:
                    default: jitsi-prosody.zeabur.internal
                    expose: false
          domainKey: JITSI_DOMAIN
        - name: jitsi-whiteboard
          icon: https://raw.githubusercontent.com/jitsi/jitsi-meet/master/images/apple-touch-icon.png
          template: PREBUILT
          spec:
            id: jitsi-whiteboard
            source:
                image: jitsi/excalidraw-backend:2026.3.0
            ports:
                - id: web
                  port: 80
                  type: HTTP
            instructions:
                - title: 白板后端地址
                  content: https://${WHITEBOARD_DOMAIN}.zeabur.app
                - title: 应用侧配置
                  content: 在你的应用服务上设置 WHITEBOARD_URL=https://${WHITEBOARD_DOMAIN}.zeabur.app
            env:
                CORS_ORIGIN:
                    default: https://${JITSI_DOMAIN}.zeabur.app
                    expose: false
                NODE_ENV:
                    default: production
                    expose: false
                PORT:
                    default: "80"
                    expose: false
          domainKey: WHITEBOARD_DOMAIN
localization:
    zh-CN:
        description: |
            自托管 Jitsi Meet 视频会议栈，已启用 JWT 认证：只有持有你自己的后端签发
            token 的用户才能创建/加入会议；附带 Excalidraw 协同白板后端。
        variables:
            - key: JITSI_DOMAIN
              type: DOMAIN
              name: Jitsi Meet 域名
              description: Jitsi Meet Web 服务的公开子域名（例如 my-jitsi）。
            - key: WHITEBOARD_DOMAIN
              type: DOMAIN
              name: 白板后端域名
              description: Excalidraw 白板后端的公开子域名（例如 my-jitsi-wb）。
        readme: |
            # Jitsi Meet

            本模板部署完整的自托管 **Jitsi Meet** 栈及协同白板后端：

            - **jitsi-prosody** — XMPP 服务器（已启用 JWT 认证与访客域）
            - **jitsi-jicofo** — 会议焦点，负责媒体路由
            - **jitsi-jvb** — Jitsi 视频桥（已启用 UDP 端口转发）
            - **jitsi-web** — Jitsi Meet Web 界面（默认中文、关闭预加入页）
            - **jitsi-whiteboard** — `@jitsi/excalidraw-backend` 协同白板服务

            认证方式为 JWT：由你自己的后端为访客签发 token，访客通过 `<链接>?jwt=<token>` 入会。
            部署完成后请在你的应用服务上设置：

            - `JITSI_BASE_URL` = `https://<JITSI_DOMAIN>.zeabur.app`
            - `WHITEBOARD_URL` = `https://<WHITEBOARD_DOMAIN>.zeabur.app`
            - `JITSI_JWT_APP_ID` / `JITSI_JWT_APP_SECRET` = jitsi-web 服务环境变量中自动生成的 `JWT_APP_ID` / `JWT_APP_SECRET`

            访客通过 `?jwt=<token>` 入会；已禁止匿名创建房间（`JWT_ALLOW_EMPTY=0`）。

            > 注意：JVB 已开启 UDP 端口转发，请确保外部参会者可达对应的转发 UDP 端口。
    zh-TW:
        description: |
            自架 Jitsi Meet 視訊會議堆疊，已啟用 JWT 認證：只有持有你自己的後端簽發
            token 的使用者才能建立/加入會議；附帶 Excalidraw 協同白板後端。
        variables:
            - key: JITSI_DOMAIN
              type: DOMAIN
              name: Jitsi Meet 網域
              description: Jitsi Meet Web 服務的公開子網域（例如 my-jitsi）。
            - key: WHITEBOARD_DOMAIN
              type: DOMAIN
              name: 白板後端網域
              description: Excalidraw 白板後端的公開子網域（例如 my-jitsi-wb）。
            - key: JITSI_APP_ID
              type: STRING
              name: Jitsi JWT App ID
              description: 簽發/校驗 Jitsi JWT 的應用 ID（需與你的應用簽發方一致）。
            - key: JITSI_APP_SECRET
              type: PASSWORD
              name: Jitsi JWT App Secret
              description: 簽發 Jitsi JWT 的金鑰（需與你的應用簽發方一致）。
            - key: JITSI_FOCUS_PASSWORD
              type: PASSWORD
              name: Jicofo XMPP 密碼
              description: Jicofo（會議焦點）使用者的共享 XMPP 密碼。
            - key: JITSI_JVB_PASSWORD
              type: PASSWORD
              name: JVB XMPP 密碼
              description: JVB（視訊橋）使用者的共享 XMPP 密碼。
        readme: |
            # Jitsi Meet

            本模板部署完整的自架 **Jitsi Meet** 堆疊及協同白板後端：

            - **jitsi-prosody** — XMPP 伺服器（已啟用 JWT 認證與訪客域）
            - **jitsi-jicofo** — 會議焦點，負責媒體路由
            - **jitsi-jvb** — Jitsi 視訊橋（已啟用 UDP 連接埠轉發）
            - **jitsi-web** — Jitsi Meet Web 介面（預設中文、關閉預加入頁）
            - **jitsi-whiteboard** — `@jitsi/excalidraw-backend` 協同白板服務

            認證方式為 JWT：由你自己的後端為訪客簽發 token，訪客透過 `<連結>?jwt=<token>` 入會。
            部署完成後請在你的應用服務上設定：

            - `JITSI_BASE_URL` = `https://<JITSI_DOMAIN>.zeabur.app`
            - `WHITEBOARD_URL` = `https://<WHITEBOARD_DOMAIN>.zeabur.app`
            - `JITSI_JWT_APP_ID` / `JITSI_JWT_APP_SECRET` = jitsi-web 服務環境變數中自動生成的 `JWT_APP_ID` / `JWT_APP_SECRET`

            訪客透過 `?jwt=<token>` 入會；已禁止匿名建立房間（`JWT_ALLOW_EMPTY=0`）。

            > 注意：JVB 已開啟 UDP 連接埠轉發，請確保外部參會者可達對應的轉發 UDP 連接埠。
