你需要準備
- 已安裝 flyctl 命令列介面
- Fly.io 帳號(免費方案可用)
- 模型驗證:所選模型提供者的 API 金鑰
- 頻道憑證:Discord bot token、Telegram token 等
初學者快速路徑
- 複製儲存庫,自訂
fly.toml - 建立應用程式與 volume,設定 secrets
- 使用
fly deploy部署 - 透過 SSH 進入建立設定,或使用控制介面
設定 fly.toml
編輯 OpenClaw Docker 映像的進入點是
fly.toml 以符合你的應用程式名稱與需求。儲存庫追蹤的 fly.toml 是下方顯示的公開範本;deploy/fly.private.toml 是強化的無公開 IP 變體(請參閱私有部署)。tini,預設執行 node openclaw.mjs gateway。Fly [processes] 會取代 Docker CMD(此處直接執行 node dist/index.js gateway ...,也就是相同的已編譯進入點),但不會碰到 ENTRYPOINT,因此程序仍會在 tini 底下執行。關鍵設定:| 設定 | 原因 |
|---|---|
--bind lan | 綁定到 0.0.0.0,讓 Fly 的 proxy 可以連到閘道 |
--allow-unconfigured | 在沒有設定檔的情況下啟動(之後再建立) |
internal_port = 3000 | 必須符合 --port 3000(或 OPENCLAW_GATEWAY_PORT),供 Fly 健康檢查使用 |
memory = "2048mb" | 512MB 太小;建議 2GB |
OPENCLAW_STATE_DIR = "/data" | 將狀態持久化到 volume |
設定 secrets
--bind lan)需要有效的閘道驗證路徑。此範例使用 OPENCLAW_GATEWAY_TOKEN,但 gateway.auth.password 或正確設定的非 loopback trusted-proxy 部署也符合需求。請參閱 Secrets 管理了解 SecretRef 合約。將這些 token 視為密碼。API 金鑰與 token 建議使用環境變數/fly secrets,而不是設定檔,讓 secrets 不會進入 openclaw.json。部署
gateway ready。Fly 自己的健康檢查會依照 fly.toml 監看 internal_port = 3000;映像的 Docker HEALTHCHECK 指令也會額外輪詢其預設連接埠 18789 上的 /healthz,但此部署將閘道覆寫為 --port 3000,因此這裡不會使用該預設連接埠。建立設定檔
透過 SSH 進入機器以建立正確設定:使用
OPENCLAW_STATE_DIR=/data 時,設定路徑是 /data/openclaw.json。將 https://my-openclaw.fly.dev 替換為你的實際 Fly 應用程式 origin。閘道啟動會從執行階段 --bind 和 --port 值播種本機控制介面 origins,因此第一次開機可以在設定尚不存在時繼續;但透過 Fly 從瀏覽器存取仍需要在 gateway.controlUi.allowedOrigins 中列出精確的 HTTPS origin。Discord token 可以來自:- 環境變數
DISCORD_BOT_TOKEN(建議用於 secrets);不需要加入設定,閘道會自動讀取 - 設定檔
channels.discord.token
疑難排解
###「App is not listening on expected address」 閘道綁定到127.0.0.1,而不是 0.0.0.0。
修正: 在 fly.toml 的程序命令中加入 --bind lan。
健康檢查失敗/連線被拒
Fly 無法在設定的連接埠連到閘道。 修正: 確認internal_port 符合閘道連接埠(--port 3000 或 OPENCLAW_GATEWAY_PORT=3000)。
OOM/記憶體問題
容器持續重新啟動或被終止。跡象包括:SIGABRT、v8::internal::Runtime_AllocateInYoungGeneration,或無聲重新啟動。
修正: 在 fly.toml 中增加記憶體:
閘道鎖定問題
容器重新啟動後,閘道因「already running」錯誤而拒絕啟動。 單一執行個體鎖定檔位於<tmpdir>/openclaw-<uid>/gateway.<hash>.lock(Linux:/tmp/openclaw-<uid>/gateway.<hash>.lock),不在持久化 /data volume 上,因此完整容器重新啟動通常會連同其餘容器檔案系統一起清除它。如果鎖定仍存在(例如保留容器檔案系統的 fly machine restart)並阻擋啟動,請手動移除:
未讀取設定
--allow-unconfigured 只會略過啟動防護。它不會建立或修復 /data/openclaw.json,因此請確認你的實際設定存在,並包含 "gateway": { "mode": "local" },以便正常啟動本機閘道。
驗證設定存在:
透過 SSH 寫入設定
fly ssh console -C 不支援 shell 重新導向。若要寫入設定檔:
fly sftp 可能會失敗;請先刪除:
狀態未持久化
如果重新啟動後遺失驗證 profiles、頻道/提供者狀態或 sessions,表示狀態目錄正在寫入容器檔案系統,而不是 volume。 修正: 確認fly.toml 中已設定 OPENCLAW_STATE_DIR=/data,然後重新部署。
更新
git pull + fly deploy 是此處的受監督路徑:它會從 Dockerfile 重新建置映像,因此命令列介面/閘道版本、基礎 OS 映像,以及任何 Dockerfile 變更都會一起更新。在執行中的容器內使用 openclaw update 不是相同操作,因為映像是以 Docker 建置的 dist/ tree 交付,沒有 .git checkout,也沒有可供偵測的 npm 管理全域安裝;關於 VM 風格安裝的流程,請參閱更新。
更新機器命令
若要在不完整重新部署的情況下變更啟動命令:fly deploy 會將機器命令重設回 fly.toml 中的內容;重新部署後請重新套用手動變更。
私有部署(強化)
預設情況下,Fly 會配置公開 IP,因此你的閘道可透過https://your-app.fly.dev 存取,並且可被網際網路掃描器(Shodan、Censys 等)發現。
使用 deploy/fly.private.toml 進行強化部署,且沒有公開 IP:它省略 [http_service],因此不會配置公開 ingress。
何時使用私有部署
- 只有 outbound 呼叫/訊息(沒有 inbound 網路鉤子)
- ngrok 或 Tailscale tunnels 處理任何網路鉤子 callbacks
- 閘道存取透過 SSH、proxy 或 WireGuard,而不是瀏覽器
- 部署應該對網際網路掃描器隱藏
設定
fly ips list 應該只會顯示一個 private 類型的 IP:
存取私人部署
選項 1:本機代理(最簡單)私人部署的網路鉤子
若要在不公開暴露的情況下使用網路鉤子回呼(Twilio、Telnyx 等):- ngrok 通道:在容器內執行 ngrok,或作為 sidecar 執行
- Tailscale Funnel:透過 Tailscale 暴露特定路徑
- 僅限出站:部分提供者(Twilio)可在沒有網路鉤子的情況下處理出站通話
plugins.entries.voice-call.config 下:
webhookSecurity.allowedHosts 設為通道主機名稱,這樣轉送的主機標頭才會被接受。
安全性取捨
| 面向 | 公開 | 私人 |
|---|---|---|
| 網際網路掃描器 | 可被發現 | 隱藏 |
| 直接攻擊 | 可能 | 已封鎖 |
| 控制 UI 存取 | 瀏覽器 | 代理/VPN |
| 網路鉤子遞送 | 直接 | 透過通道 |
備註
- Fly.io 使用 x86 架構;Dockerfile 同時相容 x86 和 ARM。
- 若要進行 WhatsApp/Telegram onboarding,請使用
fly ssh console。 - 持久資料位於
/data的 volume 上。 - Signal 需要在映像檔中包含 signal-cli(一個以 Java 為基礎的命令列介面);請使用自訂映像檔,並將記憶體維持在 2GB 以上。
成本
使用建議設定(shared-cpu-2x、2GB RAM)時,視使用量而定,預期約為每月 $10-15;免費方案涵蓋部分基礎額度。請參閱 Fly.io pricing 了解目前費率。