Fly.io
Fly.io 部署
Section titled “Fly.io 部署”目標: 在具有持久化儲存、自動 HTTPS 以及 Discord/頻道存取權限的 Fly.io 機器上執行 OpenClaw Gateway。
- 已安裝 flyctl CLI
- Fly.io 帳戶(免費層級即可)
- 模型驗證:您選擇的模型供應商的 API 金鑰
- 頻道憑證:Discord 機器人權杖、Telegram 權杖等。
新手快速入門
Section titled “新手快速入門”- 複製儲存庫 → 自訂
fly.toml - 建立 App + 磁碟區 → 設定機密
- 使用
fly deploy進行部署 - 透過 SSH 建立設定或使用 Control UI
建立 Fly app
Terminal window # Clone the repogit clone https://github.com/openclaw/openclaw.gitcd openclaw# Create a new Fly app (pick your own name)fly apps create my-openclaw# Create a persistent volume (1GB is usually enough)fly volumes create openclaw_data --size 1 --region iad提示: 選擇一個靠近您的區域。常見選項:
lhr(倫敦)、iad(維吉尼亞州)、sjc(聖荷西)。設定 fly.toml
編輯
fly.toml以符合您的 App 名稱與需求。安全提示: 預設設定會公開 URL。若要進行沒有公開 IP 的強化部署,請參閱 私有部署 或使用
fly.private.toml。app = "my-openclaw" # Your app nameprimary_region = "iad"[build]dockerfile = "Dockerfile"[env]NODE_ENV = "production"OPENCLAW_PREFER_PNPM = "1"OPENCLAW_STATE_DIR = "/data"NODE_OPTIONS = "--max-old-space-size=1536"[processes]app = "node dist/index.js gateway --allow-unconfigured --port 3000 --bind lan"[http_service]internal_port = 3000force_https = trueauto_stop_machines = falseauto_start_machines = truemin_machines_running = 1processes = ["app"][[vm]]size = "shared-cpu-2x"memory = "2048mb"[mounts]source = "openclaw_data"destination = "/data"關鍵設定:
設定 原因 --bind lan繫結到 0.0.0.0,讓 Fly 的代理程式能夠連線到 Gateway--allow-unconfigured在沒有設定檔的情況下啟動(您之後會建立一個) internal_port = 3000必須符合 --port 3000(或OPENCLAW_GATEWAY_PORT) 才能通過 Fly 健康檢查memory = "2048mb"512MB 太小;建議使用 2GB OPENCLAW_STATE_DIR = "/data"將狀態保存在磁碟區上 設定密鑰
Terminal window # Required: Gateway token (for non-loopback binding)fly secrets set OPENCLAW_GATEWAY_TOKEN=$(openssl rand -hex 32)# Model provider API keysfly secrets set ANTHROPIC_API_KEY=sk-ant-...# Optional: Other providersfly secrets set OPENAI_API_KEY=sk-...fly secrets set GOOGLE_API_KEY=...# Channel tokensfly secrets set DISCORD_BOT_TOKEN=MTQ...備註:
- 非迴路綁定 (
--bind lan) 為了安全需要OPENCLAW_GATEWAY_TOKEN。 - 請將這些令牌視為密碼處理。
- 針對所有 API 金鑰和令牌,優先使用環境變數而非設定檔。這可以讓密鑰遠離
openclaw.json,避免被意外暴露或記錄。
- 非迴路綁定 (
部署
Terminal window fly deploy首次部署會建構 Docker 映像檔(約 2-3 分鐘)。後續的部署會更快。
部署後,請驗證:
Terminal window fly statusfly logs您應該會看到:
[gateway] listening on ws://0.0.0.0:3000 (PID xxx)[discord] logged in to discord as xxx建立設定檔
SSH 連線到機器以建立正確的設定:
Terminal window fly ssh console建立設定目錄和檔案:
Terminal window mkdir -p /datacat > /data/openclaw.json << 'EOF'{"agents": {"defaults": {"model": {"primary": "anthropic/claude-opus-4-6","fallbacks": ["anthropic/claude-sonnet-4-6", "openai/gpt-4o"]},"maxConcurrent": 4},"list": [{"id": "main","default": true}]},"auth": {"profiles": {"anthropic:default": { "mode": "token", "provider": "anthropic" },"openai:default": { "mode": "token", "provider": "openai" }}},"bindings": [{"agentId": "main","match": { "channel": "discord" }}],"channels": {"discord": {"enabled": true,"groupPolicy": "allowlist","guilds": {"YOUR_GUILD_ID": {"channels": { "general": { "allow": true } },"requireMention": false}}}},"gateway": {"mode": "local","bind": "auto"},"meta": {}}EOF備註: 使用
OPENCLAW_STATE_DIR=/data時,設定路徑是/data/openclaw.json。備註: Discord 令牌可以來自以下任一來源:
- 環境變數:
DISCORD_BOT_TOKEN(建議用於密鑰) - 設定檔:
channels.discord.token
如果使用環境變數,則無需將令牌加入設定檔。閘道會自動讀取
DISCORD_BOT_TOKEN。重啟以套用變更:
Terminal window exitfly machine restart- 環境變數:
存取閘道
在瀏覽器中開啟:
Terminal window fly open或是訪問
https://my-openclaw.fly.dev/貼上您的閘道令牌(來自
OPENCLAW_GATEWAY_TOKEN的那個)以進行驗證。Terminal window fly logs # Live logsfly logs --no-tail # Recent logsSSH 主控台
Section titled “SSH 主控台”Terminal window fly ssh console
”App is not listening on expected address”
Section titled “”App is not listening on expected address””閘道綁定到了 127.0.0.1 而不是 0.0.0.0。
解決方法: 在 fly.toml 的程序指令中加入 --bind lan。
健康檢查失敗 / 連線遭拒
Section titled “健康檢查失敗 / 連線遭拒”Fly 無法在設定的連接埠上連線到閘道。
解決方法: 確認 internal_port 符合 gateway port(設定 --port 3000 或 OPENCLAW_GATEWAY_PORT=3000)。
OOM / 記憶體問題
Section titled “OOM / 記憶體問題”容器持續重新啟動或被終止。徵兆:SIGABRT、v8::internal::Runtime_AllocateInYoungGeneration 或無聲重啟。
解決方法: 在 fly.toml 中增加記憶體:
[[vm]] memory = "2048mb"或更新現有機器:
fly machine update <machine-id> --vm-memory 2048 -y注意: 512MB 太小。1GB 可能可用,但在負載下或使用詳細記錄時可能會 OOM。建議使用 2GB。
Gateway 鎖定問題
Section titled “Gateway 鎖定問題”Gateway 拒絕啟動並顯示「already running」錯誤。
當容器重新啟動但 PID 鎖定檔案仍保留在儲存卷上時,會發生這種情況。
解決方法: 刪除鎖定檔案:
fly ssh console --command "rm -f /data/gateway.*.lock"fly machine restart <machine-id>鎖定檔案位於 /data/gateway.*.lock(不在子目錄中)。
如果使用 --allow-unconfigured,gateway 會建立一個最小設定。位於 /data/openclaw.json 的自訂設定應在重新啟動時讀取。
驗證設定是否存在:
fly ssh console --command "cat /data/openclaw.json"透過 SSH 寫入設定
Section titled “透過 SSH 寫入設定”fly ssh console -C 指令不支援 shell 重導向。若要寫入設定檔:
# Use echo + tee (pipe from local to remote)echo '{"your":"config"}' | fly ssh console -C "tee /data/openclaw.json"
# Or use sftpfly sftp shell> put /local/path/config.json /data/openclaw.json注意: 如果檔案已存在,fly sftp 可能會失敗。請先刪除:
fly ssh console --command "rm /data/openclaw.json"如果您在重新啟動後遺失憑證或工作階段,狀態目錄正在寫入至容器檔案系統。
解決方法: 確認在 fly.toml 中已設定 OPENCLAW_STATE_DIR=/data 並重新部署。
# Pull latest changesgit pull
# Redeployfly deploy
# Check healthfly statusfly logs更新機器指令
Section titled “更新機器指令”如果您需要在沒有完全重新部署的情況下變更啟動指令:
# Get machine IDfly machines list
# Update commandfly machine update <machine-id> --command "node dist/index.js gateway --port 3000 --bind lan" -y
# Or with memory increasefly machine update <machine-id> --vm-memory 2048 --command "node dist/index.js gateway --port 3000 --bind lan" -y注意: 在 fly deploy 之後,機器指令可能會重設為 fly.toml 中的內容。如果您進行了手動變更,請在部署後重新套用。
預設情況下,Fly 會分配公開 IP,讓您的 gateway 可透過 https://your-app.fly.dev 存取。這雖然方便,但也意味著您的部署可被網際網路掃描器(Shodan、Censys 等)發現。
若要進行無公開暴露的強化部署,請使用私人範本。
何時使用私人部署
Section titled “何時使用私人部署”- 您只進行傳出呼叫/訊息(無傳入 webhook)
- 您使用 ngrok 或 Tailscale 隧道進行任何 webhook 回呼
- 您透過 SSH、Proxy 或 WireGuard 而非瀏覽器來存取閘道
- 您希望部署對網路掃描器隱藏
使用 fly.private.toml 代替標準設定:
# Deploy with private configfly deploy -c fly.private.toml或是轉換現有部署:
# List current IPsfly ips list -a my-openclaw
# Release public IPsfly ips release <public-ipv4> -a my-openclawfly ips release <public-ipv6> -a my-openclaw
# Switch to private config so future deploys don't re-allocate public IPs# (remove [http_service] or deploy with the private template)fly deploy -c fly.private.toml
# Allocate private-only IPv6fly ips allocate-v6 --private -a my-openclaw在此之後,fly ips list 應僅顯示 private 類型的 IP:
VERSION IP TYPE REGIONv6 fdaa:x:x:x:x::x private global存取私有部署
Section titled “存取私有部署”由於沒有公開 URL,請使用以下方法之一:
選項 1:本地 Proxy(最簡單)
# Forward local port 3000 to the appfly proxy 3000:3000 -a my-openclaw
# Then open http://localhost:3000 in browser選項 2:WireGuard VPN
# Create WireGuard config (one-time)fly wireguard create
# Import to WireGuard client, then access via internal IPv6# Example: http://[fdaa:x:x:x:x::x]:3000選項 3:僅限 SSH
fly ssh console -a my-openclaw私有部署與 Webhooks
Section titled “私有部署與 Webhooks”如果您需要在不公開暴露的情況下使用 Webhook 回呼(Twilio、Telnyx 等):
- ngrok 隧道 - 在容器內或作為 sidecar 執行 ngrok
- Tailscale Funnel - 透過 Tailscale 暴露特定路徑
- 僅限輸出 - 某些提供商(如 Twilio)即使沒有 Webhooks 也能正常進行輸出通話
使用 ngrok 的語音通話設定範例:
{ plugins: { entries: { "voice-call": { enabled: true, config: { provider: "twilio", tunnel: { provider: "ngrok" }, webhookSecurity: { allowedHosts: ["example.ngrok.app"], }, }, }, }, },}ngrok 隧道在容器內執行,並提供公開的 Webhook URL,而無需暴露 Fly 應用程式本身。將 webhookSecurity.allowedHosts 設定為公開的隧道主機名稱,以便接受轉發的主機標頭。
| 面向 | 公開 | 私有 |
|---|---|---|
| 網路掃描器 | 可被發現 | 隱藏 |
| 直接攻擊 | 可能 | 已阻擋 |
| 控制 UI 存取 | 瀏覽器 | Proxy/VPN |
| Webhook 傳遞 | 直接 | 透過隧道 |
- Fly.io 使用 x86 架構(而非 ARM)
- Dockerfile 同時支援兩種架構
- 對於 WhatsApp/Telegram 註冊,請使用
fly ssh console - 持久資料存儲於
/data的磁碟區上 - Signal 需要 Java + signal-cli;請使用自訂映像檔並將記憶體保持在 2GB 以上。
使用推薦設定(shared-cpu-2x,2GB RAM):
- 依使用量約 $10-15/月
- 免費層級包含一定額度
詳情請參閱 Fly.io 價格。
- 設定訊息頻道:頻道
- 設定 Gateway:Gateway 設定
- 保持 OpenClaw 更新:更新