自架部署

試玩版適合體驗,正式用建議架在自己手上:逐字稿與白板資料都留在你的主機、不受 demo 限流、全 MIT 零授權成本 —— 可閉源、可賣、可改。這頁從單機跑到上 Render,一次講完。

選哪種部署?

先決定單人還是多人:桌面 App 是一個人在自己電腦上用(server 跑 loopback、不對外);要多人連進同一張板就走 server(Docker / install.sh / 源碼 / Render)。

你的情況用哪種單人 / 多人要裝什麼現在可用?
只想快速看看、給朋友玩線上試玩多人同房什麼都不用,點連結可用
一個人在自己電腦上用桌面 App 安裝檔(.msi/.exe/.dmg/.AppImage/.deb)單人下載安裝檔雙擊待發 release
團隊自架、最快Docker 一行(ghcr image)多人Docker待發 release
團隊自架、免 Rust/Nodeinstall.sh(Linux server binary)多人一行 curl | bash待發 release
任何平台、開發者從源碼 build多人Rust + Node可用
自己架一個線上版Render Blueprint多人GitHub 帳號可用
已經在用 AgentOS裝成 body-part整合AgentOS可用

「待發 release」= 程式碼與 CI 都備好了,但要等專案推一個 v* tag,CI 才會把 ghcr image / 預編譯 binary / 桌面安裝檔產出來掛上 Releases。在那之前,自架請走下面的「從源碼 build」或「Render」(這兩個不需要 release)。

架構一眼懂

Mori Canvas 是 client–server:所有重活(STT、AI 整理、白板狀態)都跑在「主機」那一台,其他人只是用瀏覽器連進來,零安裝。自架就是決定「主機」放哪 —— 兩種跑法,理解流程一樣,差在跑在哪、STT/AI 在本機還是雲端。

單機獨立執行 —— 自己的電腦跑

server 跑在你的電腦,同事連你的區網 IP。語音與 AI 可走雲端 Groq,也可以全留本機(whisper-server + Ollama),資料完全不出門。

單機架構圖:server 跑在自己的電腦,瀏覽器透過區網連入,STT 與 AI 可選本機或雲端

上傳 Render 雲端執行

server 跑在 Render 的容器,任何人開網址就能進(試玩站就是這樣架的)。AI 與 STT 走 Groq 雲端,用你後台填的 key;TLS 由 Render edge 終結,容器內只跑 HTTP。

Render 架構圖:GitHub repo 連 Render Blueprint 自動部署,瀏覽器經 HTTPS 連入,AI 走 Groq

單機跑

需要裝什麼

要件用途必要性
Rust(cargo)跑 server —— 一顆 binary,內嵌前端 + API + 即時同步必要(用預編譯包則免)
Node.js 18+ / npm只用來 build 前端;跑的時候不需要build 時必要
Groq API key「逐字稿 → 便利貼」的 AI;~/.mori/config.json 或環境變數 GROQ_API_KEYagent 必要(或走本機 Ollama / BYO)
ffmpeg「自訂」STT 模式送轉錄前的靜音剪要語音才需要
whisper(本機 whisper-server,或 mori-ear,或雲端 Groq Whisper)「錄音 → 文字」,三選一,設定頁切要語音才需要
Ollama + qwen3Groq 連不到時的本機 AI 後備;也是「全本機」的 AI 那條腿選用
openssl產自簽憑證給「公司區網版」HTTPS 用區網多人才需要

只想打字、貼逐字稿不用語音?那一把 Groq key 就夠了(用 Docker 或預編譯包連 Node / Rust 都免)。

最快:Docker 一行

v* tag 時 CI 會把 image 發佈到 ghcr.io/yazelin/mori-canvas,一行起服務、資料掛 volume 持久化:

docker run -p 1334:1334 -v "$PWD/data:/app/.data" -e GROQ_API_KEY=gsk_xxx ghcr.io/yazelin/mori-canvas

http://localhost:1334/ 就能用。白板資料在 ./data;沒掛 volume 的話容器一刪就沒。

Linux 一鍵安裝(install.sh)

不想用 Docker、也不想裝 Rust / Node?一行抓 GitHub Releases 的預編譯 binary:

curl -fsSL https://raw.githubusercontent.com/yazelin/mori-canvas/main/install.sh | bash
mori-canvas-server      # 預設 http://0.0.0.0:1334

裝到 ~/.local/share/mori-canvas/、指令 symlink 在 ~/.local/bin/,重跑同一行即升級;還沒有 release 或非 x86_64 機器時,腳本會印出「從源碼 build」的指引。

從原始碼 build(備案)

git clone https://github.com/yazelin/mori-canvas && cd mori-canvas
npm install && npm run build      # vite build(前端)→ cargo build --release(前端內嵌進 binary)
./server-rs/target/release/mori-canvas-server   # 預設 http://0.0.0.0:1334

http://localhost:1334/?room=meet 就能用。開發時用 npm run dev(編 + 跑 debug binary,同樣 :1334)。

公司區網版(手機也能錄音)

手機要用麥克風,瀏覽器規定必須 HTTPS。Rust server 自己 serve HTTPS,不需要額外的反向代理:

  1. npm run setup —— 偵測本機 IP、產含該 IP 的自簽憑證(放 certs/,已 gitignore);換網路 IP 變了就重跑。
  2. npm run build(第一次、或改過前端後)。
  3. npm run start:lan —— 等於 HTTPS=1 PORT=5174 BIND=0.0.0.0 跑 release binary。
  4. 大家連 https://你的區網IP:5174/?room=meet;每台第一次接受一次自簽憑證警告即可(一次涵蓋頁面 + 同步 + 錄音)。

注意:這個模式沒有鑑權,同 wifi 拿到網址的人就能進、會用到你的 Groq key。內網信任場合 OK,試完記得收(kill $(lsof -ti tcp:5174));長期擺著建議放 nginx 反向代理後面。

常駐(systemd)+ 正式 TLS(nginx)

長期擺著用 repo 的 deploy/mori-canvas.service + deploy/nginx.conf.example:unit 指向 install.sh 裝好的 binary、env(GROQ_API_KEY / PORT / BIND ...)集中在 /etc/mori-canvas.env(範本 deploy/mori-canvas.env.example);nginx 終結 TLS,把頁面、/api//sync/(websocket upgrade)全 proxy 給 loopback 的 1334。照檔頭註解把 USER 換成實際使用者就能 systemctl enable --now mori-canvas

懶得 build?GitHub Releases 預編譯包

v* tag 時 CI 會自動 build 兩種「下載即用」掛上 GitHub Releases:

server 包(tar.gz / zip)

mori-canvas-server-v0.1.x-linux-x86_64.tar.gz-macos-aarch64.tar.gz(Apple Silicon;第一次先 xattr -d com.apple.quarantine 解 Gatekeeper 隔離)與 -windows-x86_64.zip,內含單一 binary + 一頁 README.txt。解開、給一把 GROQ_API_KEY(環境變數或同資料夾 .env)、執行,開 http://localhost:1334/。多人開會用這個。

桌面 App(Tauri 安裝檔)

Windows .msi/.exe、Linux .AppImage/.deb,雙擊安裝開原生視窗。桌面版是 loopback 單機(:8731);要多人一起開會,請用 server 版。本機自己 build:npm run build && npm run tauri

部署到 Render

repo 帶了 render.yaml(Blueprint)+ Dockerfile,連上 GitHub 就是一鍵部署:

  1. render.com → 用 GitHub 登入 → New + → Blueprint → 選這個 repo,Render 自動讀 render.yaml(runtime 是 Docker,免費方案、新加坡區、health check 走 /api/health)。
  2. 服務 Environment → 填 GROQ_API_KEY —— 用一把專用 demo key,並在 Groq 後台設花費上限,這才是真正的錢包防線。填好按 Deploy。
  3. 之後每次 git push,Render 自動重部署(render.yaml 設了 autoDeploy)。

render.yaml 已預設好幾個 demo 防護,後台隨時可調:DEMO_RATE_PER_MIN(每 IP 每分鐘 AI/STT 請求上限,預設 60)、SPONSOR_URL / SPONSOR_LABEL(贊助按鈕)、DEMO_NOTICE(進站告示文字)。

免費方案的脾氣。閒置約 15 分鐘會休眠,下一個訪客要等 30–60 秒冷啟動;休眠 / 重部署會清掉房間資料(.data/ 不持久),想留成果請用「匯出 → 下載畫板檔」。另外不要在 Render 設 HTTPS —— TLS 由 Render edge 終結,容器內 serve HTTP 即可;PORT 也是 Render 自動注入,不用管。

環境變數總表

整理自 .env.example 與 README。本機可放 .env(已 gitignore);Render 在後台 Environment 填,別進 git。

變數作用備註
GROQ_API_KEY雲端 AI(畫卡)與 Groq Whisper 的 key雲端部署必填;本機通常直接讀 ~/.mori/config.json,可不設
ADMIN_TOKEN鎖住主機級設定:設定後 POST /api/settings 與「結束房間」需帶相符的 X-Admin-Token header,否則 401 —— 訪客改不動 whisperUrl / 處理模式 / 本機模式 / 主機 Groq key公開部署建議必設;未設時主機級欄位僅接受 loopback 來源修改(同主機反向代理會讓訪客看起來都是 loopback,這種部署一定要設)
PORT監聽 port本機預設 1334;Render 自動注入
BIND綁定位址0.0.0.0 對外開放(start:lan 已帶)
HTTPS=1自帶 TLS,讀 certs/ 的憑證只給自架區網用;Render 上不要設
DEMO_RATE_PER_MIN每 IP 每分鐘 AI/STT 請求上限demo 防護;真正的防線是 Groq 帳戶花費上限
SPONSOR_URL / SPONSOR_LABEL贊助按鈕的連結與文字選用
DEMO_NOTICE試玩版進站告示文字選用
MORI_CANVAS_REGISTER=1啟動時寫 ~/.mori/mori-canvas-server.json 服務描述,讓 AgentOS 能 dispatch 進來桌面版啟動會自動做;standalone 不受影響
MORI_CANVAS_PROMPTS提示詞覆寫目錄見下方「提示詞客製」
WHISPER_MODEL本機 whisper-server 用的模型預設 small;有顯卡可換 large-v3-turbo
LLM_LOCAL_ONLY=1開機鎖定本機模式:AI 只走本機 Ollama,雲端 STT 與訪客 BYO 端點一律封鎖,設定頁/API 關不掉資料不出網的部署用;詳見下節「本機模式」

AI 與 STT 選項

AI(把逐字稿整理成卡片)

預設走 Groq gpt-oss-120b,連不到時退本機 Ollama qwen3。key 與 model 讀 Mori 宇宙共用的 ~/.mori/config.json(providers.groq.api_key),跟其他 mori app 共用一份設定;沒有這個檔就用 GROQ_API_KEY 環境變數或 .env

Bring Your Own AI

訪客可在設定頁填任何 OpenAI 相容的 base / key / model(OpenAI、Gemini、Azure、Groq、本機 Ollama 都行),用自己的額度、不耗主機,key 只存瀏覽器。打 API 也行 —— 加 header X-LLM-Base / X-LLM-Key / X-LLM-Model 即可。

STT 三條路(設定頁切)

模式STT 怎麼來適合
Mori 處理委派 mori-ear(它自己決定本機 whisper / Groq);僅在偵測到 mori-ear 時可選已裝 Mori 的人
自訂 · 雲端Groq Whisper API,填自己的 Groq key零安裝,首選
自訂 · 本機打一台本機 whisper-server(/inference)不想資料出網

「自訂」模式送轉錄前會先用 ffmpeg 做靜音剪,避免 Whisper 對靜音產生幻覺。本機 whisper-server 用 repo 附的腳本裝:

# Linux:從源碼編,自動偵測 GPU/CPU
sudo apt install build-essential cmake ffmpeg   # GPU 另加 nvidia-cuda-toolkit
bash scripts/setup-whisper-linux.sh
bash whisper/run-whisper.sh                      # 啟動在 127.0.0.1:8089

# Windows:抓預編譯 zip(GPU 的 cuBLAS 版自帶 CUDA runtime)
powershell -ExecutionPolicy Bypass -File scripts\setup-whisper-windows.ps1
powershell -ExecutionPolicy Bypass -File whisper\run-whisper.ps1

然後設定 → 自訂 → 本機 whisper,網址填 http://127.0.0.1:8089/inference(留空會自動偵測 ~/.mori/whisper-server.json)。

本機模式(LLM_LOCAL_ONLY)

「完全不出網」的做法:啟動時設 LLM_LOCAL_ONLY=1(或 true),server 開機即進入本機模式且鎖死 —— AI 只走本機 Ollama(訪客自帶的 X-LLM-Base 端點一律忽略,不能繞道)、雲端 Groq Whisper 直接拒絕(回「本機模式已封鎖雲端 STT」),設定頁與 API 都關不掉(回「此部署鎖定本機模式」),重啟也不會退回雲端;/api/settings 會回 lockedLocalOnly: true。STT 請搭配「自訂 · 本機 whisper-server」。唯一例外是 mori-ear 模式:ear 自己決定走本機或雲端,不在本 repo 控制範圍,純內網場合請確認 ear 設定。沒設這個 env 時,設定頁的 local-only 切換照常可用,但存在 server 記憶體、重啟會還原。

提示詞客製

AI 的行為全部寫在 prompts/*.md,不用碰 Rust:board-agent.md(畫卡 agent)、transcript-cleanup.md(stage-1 清稿)、summary.md(白板摘要)、card-edit.mdcommon.md

搜尋順序:$MORI_CANVAS_PROMPTS → 執行目錄的 ./prompts~/.mori/mori-canvas/prompts,都沒有就用內嵌在 binary 裡的預設(所以單獨一顆 binary 也能跑)。覆寫目錄每次請求重讀 —— 改存 .md,下一個 request 就生效,不用重編、不用重啟。

提示詞可用 {{include:NAME}} 一行引入另一份 NAME.md(一層),<!-- --> 註解會在載入時剝掉,可以放編輯備註。想調 AI 的口味,從這裡下手最便宜。