Hosting
Fly.io
เป้าหมาย: OpenClaw Gateway ทำงานบนเครื่อง Fly.io พร้อมพื้นที่จัดเก็บถาวร, HTTPS อัตโนมัติ และการเข้าถึง Discord/ช่องทาง
สิ่งที่ต้องมี
- ติดตั้ง flyctl CLI แล้ว
- บัญชี Fly.io (ใช้ระดับฟรีได้)
- การยืนยันตัวตนโมเดล: คีย์ API สำหรับผู้ให้บริการโมเดลที่คุณเลือก
- ข้อมูลรับรองช่องทาง: โทเค็นบอต Discord, โทเค็น Telegram ฯลฯ
เส้นทางด่วนสำหรับผู้เริ่มต้น
- โคลน repo → ปรับแต่ง
fly.toml - สร้างแอป + โวลุ่ม → ตั้งค่า secrets
- ดีพลอยด้วย
fly deploy - SSH เข้าไปเพื่อสร้าง config หรือใช้ Control UI
สร้างแอป Fly
# 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 ให้ตรงกับชื่อแอปและข้อกำหนดของคุณ
หมายเหตุด้านความปลอดภัย: config เริ่มต้นเปิดเผย URL สาธารณะ สำหรับการดีพลอยที่แข็งแกร่งขึ้นโดยไม่มี IP สาธารณะ โปรดดู การดีพลอยแบบส่วนตัว หรือใช้ deploy/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 = 3000 force_https = true auto_stop_machines = false auto_start_machines = true min_machines_running = 1 processes = ["app"] [[vm]] size = "shared-cpu-2x" memory = "2048mb" [mounts] source = "openclaw_data" destination = "/data"อิมเมจ Docker ของ OpenClaw ใช้ tini เป็น entrypoint คำสั่งโปรเซสของ Fly จะแทนที่ Docker CMD โดยไม่แทนที่ ENTRYPOINT ดังนั้นโปรเซสจึงยังคงทำงานภายใต้ tini
การตั้งค่าหลัก:
| การตั้งค่า | เหตุผล |
|---|---|
--bind lan |
ผูกกับ 0.0.0.0 เพื่อให้พร็อกซีของ Fly เข้าถึง Gateway ได้ |
--allow-unconfigured |
เริ่มทำงานโดยไม่มีไฟล์ config (คุณจะสร้างไฟล์ภายหลัง) |
internal_port = 3000 |
ต้องตรงกับ --port 3000 (หรือ OPENCLAW_GATEWAY_PORT) สำหรับ health checks ของ Fly |
memory = "2048mb" |
512MB น้อยเกินไป; แนะนำ 2GB |
OPENCLAW_STATE_DIR = "/data" |
เก็บสถานะถาวรบนโวลุ่ม |
ตั้งค่า secrets
# 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=example-anthropic-key-not-real # Optional: Other providersfly secrets set OPENAI_API_KEY=example-openai-key-not-realfly secrets set GOOGLE_API_KEY=... # Channel tokensfly secrets set DISCORD_BOT_TOKEN=example-discord-bot-tokenหมายเหตุ:
- การผูกแบบไม่ใช่ loopback (
--bind lan) ต้องมีเส้นทางยืนยันตัวตน Gateway ที่ถูกต้อง ตัวอย่าง Fly.io นี้ใช้OPENCLAW_GATEWAY_TOKENแต่gateway.auth.passwordหรือการดีพลอยtrusted-proxyแบบไม่ใช่ loopback ที่กำหนดค่าอย่างถูกต้องก็เป็นไปตามข้อกำหนดเช่นกัน - ปฏิบัติกับโทเค็นเหล่านี้เหมือนรหัสผ่าน
- ควรใช้ env vars แทนไฟล์ config สำหรับคีย์ API และโทเค็นทั้งหมด วิธีนี้จะกัน secrets ออกจาก
openclaw.jsonซึ่งอาจถูกเปิดเผยหรือบันทึกลง log โดยไม่ตั้งใจ
ดีพลอย
fly deployการดีพลอยครั้งแรกจะสร้างอิมเมจ Docker (ประมาณ 2-3 นาที) การดีพลอยครั้งถัดไปจะเร็วขึ้น
หลังดีพลอยแล้ว ให้ตรวจสอบ:
fly statusfly logsคุณควรเห็น:
[gateway] listening on ws://0.0.0.0:3000 (PID xxx)[discord] logged in to discord as xxxสร้างไฟล์ config
SSH เข้าเครื่องเพื่อสร้าง config ที่เหมาะสม:
fly ssh consoleสร้างไดเรกทอรีและไฟล์ config:
mkdir -p /datacat > /data/openclaw.json << 'EOF'{ "agents": { "defaults": { "model": { "primary": "anthropic/claude-opus-4-6", "fallbacks": ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4"] }, "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", "controlUi": { "allowedOrigins": [ "https://my-openclaw.fly.dev", "http://localhost:3000", "http://127.0.0.1:3000" ] } }, "meta": {}}EOFหมายเหตุ: เมื่อใช้ OPENCLAW_STATE_DIR=/data เส้นทาง config คือ /data/openclaw.json
หมายเหตุ: แทนที่ https://my-openclaw.fly.dev ด้วย origin ของแอป Fly จริงของคุณ การเริ่มทำงานของ Gateway จะ seed origin ของ Control UI ในเครื่องจากค่า runtime --bind และ --port เพื่อให้การบูตครั้งแรกดำเนินต่อได้ก่อนที่ config จะมีอยู่ แต่การเข้าถึงผ่านเบราว์เซอร์ผ่าน Fly ยังต้องมี origin HTTPS ที่ถูกต้องระบุไว้ใน gateway.controlUi.allowedOrigins
หมายเหตุ: โทเค็น Discord มาจากที่ใดที่หนึ่งต่อไปนี้ได้:
- ตัวแปรสภาพแวดล้อม:
DISCORD_BOT_TOKEN(แนะนำสำหรับ secrets) - ไฟล์ config:
channels.discord.token
หากใช้ env var ไม่จำเป็นต้องเพิ่มโทเค็นลงใน config Gateway จะอ่าน DISCORD_BOT_TOKEN โดยอัตโนมัติ
รีสตาร์ตเพื่อปรับใช้:
exitfly machine restart <machine-id>เข้าถึง Gateway
Control UI
เปิดในเบราว์เซอร์:
fly openหรือไปที่ https://my-openclaw.fly.dev/
ยืนยันตัวตนด้วย shared secret ที่กำหนดค่าไว้ คู่มือนี้ใช้โทเค็น Gateway จาก OPENCLAW_GATEWAY_TOKEN; หากคุณเปลี่ยนไปใช้การยืนยันตัวตนด้วยรหัสผ่าน ให้ใช้รหัสผ่านนั้นแทน
Logs
fly logs # Live logsfly logs --no-tail # Recent logsคอนโซล SSH
fly ssh consoleการแก้ไขปัญหา
"App is not listening on expected address"
Gateway กำลังผูกกับ 127.0.0.1 แทนที่จะเป็น 0.0.0.0
วิธีแก้: เพิ่ม --bind lan ไปยังคำสั่งโปรเซสใน fly.toml
Health checks ล้มเหลว / การเชื่อมต่อถูกปฏิเสธ
Fly เข้าถึง Gateway บนพอร์ตที่กำหนดค่าไว้ไม่ได้
วิธีแก้: ตรวจสอบให้แน่ใจว่า internal_port ตรงกับพอร์ต Gateway (ตั้งค่า --port 3000 หรือ OPENCLAW_GATEWAY_PORT=3000)
OOM / ปัญหาหน่วยความจำ
คอนเทนเนอร์รีสตาร์ตซ้ำหรือถูกยุติ สัญญาณที่พบ: SIGABRT, v8::internal::Runtime_AllocateInYoungGeneration หรือการรีสตาร์ตเงียบ
วิธีแก้: เพิ่มหน่วยความจำใน fly.toml:
[[vm]] memory = "2048mb"หรืออัปเดตเครื่องที่มีอยู่:
fly machine update <machine-id> --vm-memory 2048 -yหมายเหตุ: 512MB น้อยเกินไป 1GB อาจใช้งานได้ แต่อาจเกิด OOM เมื่อมีโหลดหรือเมื่อเปิด logging แบบละเอียด แนะนำ 2GB
ปัญหา lock ของ Gateway
Gateway ปฏิเสธการเริ่มทำงานพร้อมข้อผิดพลาด "already running"
สิ่งนี้เกิดขึ้นเมื่อคอนเทนเนอร์รีสตาร์ต แต่ไฟล์ PID lock ยังคงอยู่บนโวลุ่ม
วิธีแก้: ลบไฟล์ lock:
fly ssh console --command "rm -f /data/gateway.*.lock"fly machine restart <machine-id>ไฟล์ lock อยู่ที่ /data/gateway.*.lock (ไม่ได้อยู่ในไดเรกทอรีย่อย)
Config ไม่ถูกอ่าน
--allow-unconfigured เพียงข้าม startup guard เท่านั้น มันไม่ได้สร้างหรือซ่อมแซม /data/openclaw.json ดังนั้นตรวจสอบให้แน่ใจว่า config จริงของคุณมีอยู่และมี gateway.mode="local" เมื่อคุณต้องการเริ่ม Gateway แบบ local ปกติ
ตรวจสอบว่า config มีอยู่:
fly ssh console --command "cat /data/openclaw.json"เขียน config ผ่าน SSH
คำสั่ง fly ssh console -C ไม่รองรับการ redirect ของเชลล์ หากต้องการเขียนไฟล์ config:
# 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"สถานะไม่คงอยู่
หากคุณสูญเสียโปรไฟล์การยืนยันตัวตน, สถานะช่องทาง/ผู้ให้บริการ หรือเซสชันหลังรีสตาร์ต แสดงว่า state dir กำลังเขียนลง filesystem ของคอนเทนเนอร์
วิธีแก้: ตรวจสอบให้แน่ใจว่าตั้งค่า OPENCLAW_STATE_DIR=/data ใน fly.toml แล้วดีพลอยใหม่
การอัปเดต
# Pull latest changesgit pull # Redeployfly deploy # Check healthfly statusfly logsอัปเดตคำสั่งของเครื่อง
หากคุณต้องเปลี่ยนคำสั่งเริ่มต้นโดยไม่ดีพลอยเต็มรูปแบบ:
# 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 ฯลฯ)
สำหรับการดีพลอยที่แข็งแกร่งขึ้นโดย ไม่มีการเปิดเผยสาธารณะ ให้ใช้เทมเพลตส่วนตัว
เมื่อใดควรใช้การดีพลอยแบบส่วนตัว
- คุณเรียก/ส่งข้อความแบบ ขาออก เท่านั้น (ไม่มี Webhook ขาเข้า)
- คุณใช้ทันเนล ngrok หรือ Tailscale สำหรับ callback ของ Webhook ใดๆ
- คุณเข้าถึง Gateway ผ่าน SSH, พร็อกซี หรือ WireGuard แทนเบราว์เซอร์
- คุณต้องการให้การดีพลอย ซ่อนจากตัวสแกนอินเทอร์เน็ต
การตั้งค่า
ใช้ deploy/fly.private.toml แทน config มาตรฐาน:
# Deploy with private configfly deploy -c deploy/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 deploy/fly.private.toml # Allocate private-only IPv6fly ips allocate-v6 --private -a my-openclawหลังจากนี้ fly ips list ควรแสดงเฉพาะ IP ประเภท private:
VERSION IP TYPE REGIONv6 fdaa:x:x:x:x::x private globalการเข้าถึงการดีพลอยแบบส่วนตัว
เนื่องจากไม่มี URL สาธารณะ ให้ใช้หนึ่งในวิธีต่อไปนี้:
ตัวเลือก 1: พร็อกซี local (ง่ายที่สุด)
# 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-openclawWebhook กับการปรับใช้แบบส่วนตัว
หากคุณต้องการคอลแบ็ก Webhook (Twilio, Telnyx ฯลฯ) โดยไม่เปิดเผยต่อสาธารณะ:
- ngrok tunnel - รัน ngrok ภายในคอนเทนเนอร์หรือเป็น sidecar
- Tailscale Funnel - เปิดเผยพาธเฉพาะผ่าน Tailscale
- เฉพาะขาออก - ผู้ให้บริการบางราย (Twilio) ทำงานได้ดีสำหรับการโทรขาออกโดยไม่ต้องใช้ Webhook
ตัวอย่างการกำหนดค่าการโทรเสียงด้วย ngrok:
{ plugins: { entries: { "voice-call": { enabled: true, config: { provider: "twilio", tunnel: { provider: "ngrok" }, webhookSecurity: { allowedHosts: ["example.ngrok.app"], }, }, }, }, },}ngrok tunnel รันภายในคอนเทนเนอร์และให้ URL Webhook สาธารณะโดยไม่เปิดเผยแอป Fly เอง ตั้งค่า webhookSecurity.allowedHosts เป็นชื่อโฮสต์ tunnel สาธารณะเพื่อให้ยอมรับ forwarded host headers
ประโยชน์ด้านความปลอดภัย
| แง่มุม | สาธารณะ | ส่วนตัว |
|---|---|---|
| สแกนเนอร์อินเทอร์เน็ต | ค้นพบได้ | ซ่อนอยู่ |
| การโจมตีโดยตรง | เป็นไปได้ | ถูกบล็อก |
| การเข้าถึง Control UI | เบราว์เซอร์ | Proxy/VPN |
| การส่ง Webhook | โดยตรง | ผ่าน tunnel |
หมายเหตุ
- Fly.io ใช้ สถาปัตยกรรม x86 (ไม่ใช่ ARM)
- Dockerfile เข้ากันได้กับทั้งสองสถาปัตยกรรม
- สำหรับการเริ่มใช้งาน WhatsApp/Telegram ให้ใช้
fly ssh console - ข้อมูลถาวรอยู่บนโวลุ่มที่
/data - Signal ต้องใช้ Java + signal-cli; ใช้อิมเมจแบบกำหนดเองและคงหน่วยความจำไว้ที่ 2GB+
ค่าใช้จ่าย
ด้วยการกำหนดค่าที่แนะนำ (shared-cpu-2x, RAM 2GB):
- ประมาณ $10-15/เดือน ขึ้นอยู่กับการใช้งาน
- ระดับฟรีมีโควตาบางส่วนรวมอยู่ด้วย
ดูรายละเอียดที่ ราคาของ Fly.io
ขั้นตอนถัดไป
- ตั้งค่าช่องทางการส่งข้อความ: ช่องทาง
- กำหนดค่า Gateway: การกำหนดค่า Gateway
- ดูแลให้ OpenClaw เป็นเวอร์ชันล่าสุดเสมอ: การอัปเดต