検索

記事と日記を検索…

自架開源視訊會議:La Suite Meet + VoidAuth 完整部署教學

2026-07-19 に記す・小暑

この記事はまだ日本語に翻訳されていません。原文を表示しています。

他の言語: 繁體中文

公司不想繼續付 Microsoft Teams 或 Webex 的帳號訂閱費?其實只要有一台能跑 Docker 的主機和一個網域,就可以自架一套功能對標 Google Meet 的開源視訊會議系統。這篇文章記錄從零到上線的完整過程,包含踩過的坑和解法。

為什麼選這套

這次用到兩個開源專案的組合:

  • La Suite Meet:法國政府(DINUM)官方開源的視訊會議系統,底層用 LiveKit 做 WebRTC,前後端是 React + Django,MIT 授權,法國公務體系正式在用。
  • VoidAuth:輕量的自架 SSO / OIDC 身分驗證服務。Meet 本身不管帳號密碼,把登入委派給 OIDC 提供者,VoidAuth 就是扮演這個角色。

成本上,除了電費跟網域費,其他都是免費的。

這篇適合誰

  • 有一台能跑 Docker 的主機(實體機或 VPS 都行)
  • 有自己的網域,可以設定 DNS
  • 對 Linux 指令不陌生,但不需要是專家

架構概覽

這篇用的架構:

  • 一台 Docker 主機(192.168.1.102):跑 Meet、LiveKit、VoidAuth、資料庫等所有容器
  • 一台 Caddy 反向代理主機:對外提供 HTTPS,自動申請 Let's Encrypt 憑證
  • 三個對外網域(以 sao-x.com 為例,換成你自己的)
HTTPS 443 內網 8083 內網 7880 內網 3000 代理 /api WebRTC 媒體直連 7881/7882 使用者瀏覽器 Caddy Meet Frontendnginx:8083 LiveKit信令 7880 VoidAuthOIDC 3000 Meet BackendDjango:8000 PostgreSQL Redis

Caddy 在另一台機器

如果你的 Caddy 跟 Docker 是同一台主機,把所有「另一台主機 IP」改成 127.0.0.1 即可,架構會更簡單。

前置作業:DNS 設定

先把這三個子網域指到你的公網 IP:

テキスト
meet.sao-x.com      A    你的公網IP
auth.sao-x.com      A    你的公網IP
livekit.sao-x.com   A    你的公網IP

不要掛 Cloudflare 代理

這幾個子網域不要開啟 Cloudflare 的橘色雲朵(Proxy)。免費方案會把閒置超過 100 秒的 WebSocket 直接斷掉,導致視訊會議連線不穩定。使用 DNS only(灰色雲朵)即可。

安裝流程

為什麼要分兩階段

有個先天的「雞生蛋」問題:Meet 需要 VoidAuth 給的 OIDC Client ID/Secret,但這組 ID/Secret 必須先把 VoidAuth 跑起來、登入後台手動建立才能拿到。所以拆成兩個階段。

Stage 1:先跑起 VoidAuth

下載安裝腳本後執行:

Bash
chmod +x install-meet-voidauth.sh
./install-meet-voidauth.sh stage1

腳本會問你幾個問題,有預設值的直接 Enter 就好:

全 2 項目

  • 根網域(預設 sao-x.com)
  • Meet / LiveKit / VoidAuth 各自的子網域
  • Caddy 主機的內網 IP(用來設定防火牆,只允許這台連進來)
  • VoidAuth 資料庫密碼(留空自動產生)

其他密鑰(Storage Key 等)全部自動產生,不需要你記憶。

在 VoidAuth 建立 OIDC Client

登入後台後,建立一個給 Meet 用的 OIDC Client:

欄位值
名稱任意,例如 meet
Redirect URIhttps://meet.sao-x.com/api/v1.0/callback/
Grant TypeAuthorization Code

建立後拿到 Client ID 和 Client Secret,記下來備用。


Stage 2:部署 Meet 全家桶

Bash
./install-meet-voidauth.sh stage2

這次會問你 OIDC Client ID/Secret(貼上 Stage 1 拿到的)、資料庫密碼、SMTP(沒有就全 Enter 跳過)、管理員帳密。

腳本會自動:啟動所有容器 → 跑 DB migrate → 建立管理員帳號。

完成後把 Meet 和 LiveKit 加到 Caddy:

テキスト
meet.sao-x.com {
    reverse_proxy 192.168.1.102:8083
}

livekit.sao-x.com {
    reverse_proxy 192.168.1.102:7880
}

最關鍵的最後一步

路由器 Port Forwarding — 最常被漏掉

視訊/音訊的媒體流走 WebRTC,使用者瀏覽器必須能直接連到 LiveKit 容器的 7881/7882,不能走 Caddy 反代。

登入你的路由器後台,新增 Port Forwarding 規則:

  • 外部 7881/TCP → 192.168.1.102:7881
  • 外部 7882/UDP → 192.168.1.102:7882

沒做這步的症狀:網頁能開、能登入、能進會議室,但畫面一直轉圈、看不到對方、console 噴 ping timeout。

用 canyouseeme.org 測試 7881 有沒有真的對外開放,確認沒問題就完成了。


踩過的坑(排錯速查)

這是整個過程踩過的坑,整理成一個速查表:

全 6 項目


開放 API 給 Bot / 第三方整合

Meet 有自己的 Application JWT 系統,讓外部程式能以特定使用者身分呼叫 API,不需要走瀏覽器登入。

啟用 External API

Bash
echo "EXTERNAL_API_ENABLED=true" >> env.d/common
echo "APPLICATION_JWT_SECRET_KEY=$(openssl rand -hex 32)" >> env.d/common

每行必須獨立

用 echo 一次寫一行,不要把兩個變數寫在同一行。Django 沒辦法解析 TrueAPPLICATION_JWT_SECRET_KEY=xxx 這種粘在一起的值,會直接掛掉。

重啟 backend 後,去 Admin 後台 → Applications → 新增,填入名稱、選擇允許的 scopes 和使用者網域。

用 Application 換 JWT Token

Bash
curl -X POST https://meet.sao-x.com/api/v1.0/resource-server/token/ \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "你的ClientID",
    "client_secret": "你的ClientSecret",
    "email": "代理的使用者email",
    "scope": "rooms:create rooms:list"
  }'

拿到 token 後,用 Authorization: Bearer <token> header 呼叫 /api/v1.0/resource-server/rooms/ 等端點。


對外 Port 總整理

Port協定在哪台開放對象用途
80TCPCaddy 主機全網HTTP(Let's Encrypt 簽證 + 轉址)
443TCPCaddy 主機全網HTTPS(所有網域對外入口)
3000TCPDocker 主機僅 Caddy IPVoidAuth 反代
8083TCPDocker 主機僅 Caddy IPMeet 反代
7880TCPDocker 主機僅 Caddy IPLiveKit 信令反代
7881TCPDocker 主機全網+路由器轉發WebRTC 媒體(ICE over TCP)
7882UDPDocker 主機全網+路由器轉發WebRTC 媒體(主要影音傳輸)

真正暴露在公網的只有 Caddy 的 80/443,以及 Docker 主機的 7881/7882(需路由器 Port Forwarding)。其餘 port 用 ufw 限制只對 Caddy 主機的內網 IP 開放。


維護

升級到新版本:

Bash
cd ~/meet-stack
# 先看官方 CHANGELOG 有無特殊步驟
docker compose -f docker-compose.meet.yaml -f docker-compose.meet.override.yaml pull
docker compose -f docker-compose.meet.yaml -f docker-compose.meet.override.yaml up -d
docker compose -f docker-compose.meet.yaml -f docker-compose.meet.override.yaml \
  run --rm backend python manage.py migrate

建議釘版本

範例 compose 檔預設用 latest tag,建議正式上線後把 image 版本號釘死(例如 lasuite/meet-backend:1.17.0),避免自動升級到不相容的新版。

新增使用者:在 VoidAuth 後台的 Invitations 頁面建立邀請連結,發給對方自助註冊。管理員則從 https://meet.sao-x.com/admin 直接操作。

丙午年 小暑

唯一 書

コメント欄を読み込み中...