การปรับใช้บน Fly.io¶
เป้าหมาย: ให้OpenClaw Gatewayทำงานบนเครื่องของFly.ioพร้อมพื้นที่เก็บข้อมูลถาวร, HTTPSอัตโนมัติ และการเข้าถึงDiscord/ช่องทางต่างๆ
สิ่งที่ต้องใช้¶
- ติดตั้งflyctl CLIแล้ว
- บัญชีFly.io(ระดับฟรีใช้งานได้)
- การยืนยันตัวตนของโมเดล: คีย์APIของAnthropic(หรือคีย์ของผู้ให้บริการอื่น)
- ข้อมูลรับรองของช่องทาง: โทเค็นบอท Discord, โทเค็น Telegram เป็นต้น
เส้นทางเริ่มต้นสำหรับผู้เริ่มต้น¶
- โคลนรีโป → ปรับแต่ง
fly.toml - สร้างแอป+โวลุ่ม → ตั้งค่าSecrets
- ดีพลอยด้วย
fly deploy - SSHเข้าไปเพื่อสร้างคอนฟิกหรือใช้Control UI
1) สร้างแอปFly¶
# Clone the repo
git clone https://github.com/openclaw/openclaw.git
cd 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(ซานโฮเซ) Common options: lhr (London), iad (Virginia), sjc (San Jose).
2. กำหนดค่าfly.toml¶
แก้ไขfly.tomlให้ตรงกับชื่อแอปและความต้องการของคุณ
Security note: The default config exposes a public URL. หมายเหตุด้านความปลอดภัย: คอนฟิกเริ่มต้นจะเปิดเผยURLสาธารณะ สำหรับการดีพลอยที่แข็งแกร่งโดยไม่มีIPสาธารณะ ดูการดีพลอยแบบส่วนตัวหรือใช้fly.private.toml.
app = "my-openclaw" # Your app name
primary_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"
การตั้งค่าหลัก:
| การตั้งค่า | เหตุผล |
|---|---|
--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" |
คงสถานะไว้บนวอลุ่ม |
3. ตั้งค่าSecrets¶
# Required: Gateway token (for non-loopback binding)
fly secrets set OPENCLAW_GATEWAY_TOKEN=$(openssl rand -hex 32)
# Model provider API keys
fly secrets set ANTHROPIC_API_KEY=sk-ant-...
# Optional: Other providers
fly secrets set OPENAI_API_KEY=sk-...
fly secrets set GOOGLE_API_KEY=...
# Channel tokens
fly secrets set DISCORD_BOT_TOKEN=MTQ...
หมายเหตุ:
- การผูกแบบไม่ใช่loopback(
--bind lan)ต้องใช้OPENCLAW_GATEWAY_TOKENเพื่อความปลอดภัย - ปฏิบัติกับโทเคนเหล่านี้เหมือนรหัสผ่าน
- ควรใช้ตัวแปรสภาพแวดล้อม (env vars) แทนไฟล์คอนฟิก สำหรับ API keys และโทเค็นทั้งหมด วิธีนี้จะช่วยป้องกันไม่ให้ข้อมูลลับอยู่ใน
openclaw.jsonซึ่งอาจถูกเปิดเผยหรือบันทึกล็อกโดยไม่ตั้งใจ
4. ดีพลอย¶
fly deploy
การดีพลอยครั้งแรกจะสร้างอิมเมจDocker(~2-3นาที) การดีพลอยครั้งถัดไปจะเร็วขึ้น Subsequent deploys are faster.
หลังดีพลอย ให้ตรวจสอบ:
fly status
fly logs
คุณควรเห็น:
[gateway] listening on ws://0.0.0.0:3000 (PID xxx)
[discord] logged in to discord as xxx
5. สร้างไฟล์คอนฟิก¶
SSHเข้าเครื่องเพื่อสร้างคอนฟิกที่เหมาะสม:
fly ssh console
สร้างไดเรกทอรีและไฟล์คอนฟิก:
mkdir -p /data
cat > /data/openclaw.json << 'EOF'
{
"agents": {
"defaults": {
"model": {
"primary": "anthropic/claude-opus-4-6",
"fallbacks": ["anthropic/claude-sonnet-4-5", "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": {
"lastTouchedVersion": "2026.1.29"
}
}
EOF
หมายเหตุ: เมื่อใช้OPENCLAW_STATE_DIR=/dataพาธของคอนฟิกคือ/data/openclaw.json.
หมายเหตุ: โทเคนDiscordสามารถมาจากอย่างใดอย่างหนึ่ง:
- ตัวแปรสภาพแวดล้อม:
DISCORD_BOT_TOKEN(แนะนำสำหรับSecrets) - ไฟล์คอนฟิก:
channels.discord.token
หากใช้ตัวแปรสภาพแวดล้อม (env var) ไม่จำเป็นต้องเพิ่มโทเค็นลงในคอนฟิก Gateway จะอ่านค่า DISCORD_BOT_TOKEN โดยอัตโนมัติ
รีสตาร์ตเพื่อให้มีผล:
exit
fly machine restart <machine-id>
6. เข้าถึงGateway¶
UI ควบคุม¶
เปิดในเบราว์เซอร์:
fly open
หรือไปที่https://my-openclaw.fly.dev/
วางโทเคนGatewayของคุณ(อันที่ได้จากOPENCLAW_GATEWAY_TOKEN)เพื่อยืนยันตัวตน
บันทึกเหตุการณ์ (Logs)¶
fly logs # Live logs
fly logs --no-tail # Recent logs
คอนโซลSSH¶
fly ssh console
การแก้ไขปัญหา¶
"แอปไม่ได้รับฟังบนที่อยู่ที่คาดไว้"¶
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/ปัญหาหน่วยความจำ¶
Container keeps restarting or getting killed. คอนเทนเนอร์รีสตาร์ตซ้ำหรือถูกฆ่า สัญญาณ: SIGABRT, v8::internal::Runtime_AllocateInYoungGenerationหรือรีสตาร์ตแบบเงียบ
วิธีแก้ไข: เพิ่มหน่วยความจำในfly.toml:
[[vm]]
memory = "2048mb"
หรืออัปเดตเครื่องที่มีอยู่:
fly machine update <machine-id> --vm-memory 2048 -y
หมายเหตุ: 512MBเล็กเกินไป 1GBอาจใช้ได้แต่มีโอกาสOOMเมื่อมีโหลดหรือบันทึกแบบละเอียด แนะนำ2GB 1GB may work but can OOM under load or with verbose logging. 2GB is recommended.
ปัญหาGateway Lock¶
Gatewayปฏิเสธการเริ่มต้นพร้อมข้อผิดพลาด"already running"
เกิดขึ้นเมื่อคอนเทนเนอร์รีสตาร์ตแต่ไฟล์ล็อกPIDคงอยู่บนโวลุ่ม
วิธีแก้ไข: ลบไฟล์ล็อก:
fly ssh console --command "rm -f /data/gateway.*.lock"
fly machine restart <machine-id>
ไฟล์ล็อกอยู่ที่/data/gateway.*.lock(ไม่อยู่ในไดเรกทอรีย่อย)
ไม่อ่านคอนฟิก¶
If using --allow-unconfigured, the gateway creates a minimal config. หากใช้--allow-unconfiguredGatewayจะสร้างคอนฟิกขั้นต่ำ คอนฟิกที่กำหนดเองของคุณที่/data/openclaw.jsonควรถูกอ่านหลังรีสตาร์ต
ตรวจสอบว่ามีคอนฟิกอยู่จริง:
fly ssh console --command "cat /data/openclaw.json"
การเขียนคอนฟิกผ่านSSH¶
คำสั่งfly ssh console -Cไม่รองรับการเปลี่ยนเส้นทางเชลล์ เพื่อเขียนไฟล์คอนฟิก: To write a config file:
# Use echo + tee (pipe from local to remote)
echo '{"your":"config"}' | fly ssh console -C "tee /data/openclaw.json"
# Or use sftp
fly sftp shell
> put /local/path/config.json /data/openclaw.json
หมายเหตุ: fly sftpอาจล้มเหลวหากไฟล์มีอยู่แล้ว ให้ลบก่อน: ลบก่อน:
fly ssh console --command "rm /data/openclaw.json"
สถานะไม่คงอยู่¶
หากคุณสูญเสียข้อมูลประจำตัวหรือเซสชันหลังรีสตาร์ต แสดงว่าไดเรกทอรีสถานะกำลังเขียนไปยังไฟล์ระบบของคอนเทนเนอร์
วิธีแก้ไข: ตรวจสอบให้แน่ใจว่าตั้งค่าOPENCLAW_STATE_DIR=/dataในfly.tomlแล้วดีพลอยใหม่
อัปเดต¶
# Pull latest changes
git pull
# Redeploy
fly deploy
# Check health
fly status
fly logs
อัปเดตคำสั่งเครื่อง¶
หากต้องการเปลี่ยนคำสั่งเริ่มต้นโดยไม่ดีพลอยใหม่ทั้งหมด:
# Get machine ID
fly machines list
# Update command
fly machine update <machine-id> --command "node dist/index.js gateway --port 3000 --bind lan" -y
# Or with memory increase
fly machine update <machine-id> --vm-memory 2048 --command "node dist/index.js gateway --port 3000 --bind lan" -y
หมายเหตุ: หลังจากfly deployคำสั่งของเครื่องอาจรีเซ็ตกลับเป็นค่าที่อยู่ในfly.toml หากคุณแก้ไขด้วยตนเอง ให้ปรับใช้ซ้ำหลังดีพลอย If you made manual changes, re-apply them after deploy.
การดีพลอยแบบส่วนตัว(Hardened)¶
โดยค่าเริ่มต้น FlyจะจัดสรรIPสาธารณะ ทำให้Gatewayของคุณเข้าถึงได้ที่https://your-app.fly.dev ซึ่งสะดวกแต่ทำให้การดีพลอยของคุณถูกค้นพบโดยสแกนเนอร์อินเทอร์เน็ต(Shodan, Censys ฯลฯ) This is convenient but means your deployment is discoverable by internet scanners (Shodan, Censys, etc.).
สำหรับการดีพลอยที่แข็งแกร่งโดยไม่มีการเปิดเผยสาธารณะให้ใช้เทมเพลตแบบส่วนตัว
เมื่อใดควรใช้การดีพลอยแบบส่วนตัว¶
- คุณทำเฉพาะการเรียก/ส่งข้อความแบบขาออก(ไม่มีเว็บฮุคขาเข้า)
- คุณใช้ท่อทางngrokหรือTailscaleสำหรับการเรียกกลับของเว็บฮุค
- คุณเข้าถึงGatewayผ่านSSH, พร็อกซีหรือWireGuardแทนเบราว์เซอร์
- คุณต้องการให้การดีพลอยซ่อนจากสแกนเนอร์อินเทอร์เน็ต
การตั้งค่า¶
ใช้fly.private.tomlแทนคอนฟิกมาตรฐาน:
# Deploy with private config
fly deploy -c fly.private.toml
หรือแปลงการดีพลอยที่มีอยู่:
# List current IPs
fly ips list -a my-openclaw
# Release public IPs
fly ips release <public-ipv4> -a my-openclaw
fly 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 IPv6
fly ips allocate-v6 --private -a my-openclaw
หลังจากนี้fly ips listควรแสดงเฉพาะIPชนิดprivate:
VERSION IP TYPE REGION
v6 fdaa:x:x:x:x::x private global
การเข้าถึงการดีพลอยแบบส่วนตัว¶
เนื่องจากไม่มีURLสาธารณะ ให้ใช้หนึ่งในวิธีต่อไปนี้:
ตัวเลือกที่1: พร็อกซีภายในเครื่อง(ง่ายที่สุด)
# Forward local port 3000 to the app
fly 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
เว็บฮุคกับการดีพลอยแบบส่วนตัว¶
หากคุณต้องการ webhook callbacks (Twilio, Telnyx เป็นต้น) โดยไม่ต้องเปิดเผยสู่สาธารณะ:
- ngrok tunnel - รันngrokภายในคอนเทนเนอร์หรือเป็นไซด์คาร์
- Tailscale Funnel - เปิดเผยพาธเฉพาะผ่านTailscale
- ขาออกเท่านั้น - ผู้ให้บริการบางราย(Twilio)ทำงานได้ดีสำหรับการโทรขาออกโดยไม่ต้องมีเว็บฮุค
ตัวอย่างคอนฟิกการโทรด้วยเสียงโดยใช้ngrok:
{
"plugins": {
"entries": {
"voice-call": {
"enabled": true,
"config": {
"provider": "twilio",
"tunnel": { "provider": "ngrok" },
"webhookSecurity": {
"allowedHosts": ["example.ngrok.app"]
}
}
}
}
}
}
The ngrok tunnel runs inside the container and provides a public webhook URL without exposing the Fly app itself. ngrok tunnelทำงานภายในคอนเทนเนอร์และให้URLเว็บฮุคสาธารณะโดยไม่เปิดเผยแอปFlyเอง ตั้งค่าwebhookSecurity.allowedHostsเป็นชื่อโฮสต์ของท่อทางสาธารณะเพื่อยอมรับส่วนหัวโฮสต์ที่ถูกส่งต่อ
ประโยชน์ด้านความปลอดภัย¶
| Aspect | สาธารณะ | ส่วนตัว |
|---|---|---|
| สแกนเนอร์อินเทอร์เน็ต | ค้นพบได้ | ซ่อนอยู่ |
| การโจมตีโดยตรง | เป็นไปได้ | ถูกบล็อก |
| การเข้าถึงControl UI | เบราว์เซอร์ | พร็อกซี/VPN |
| การส่งเว็บฮุค | โดยตรง | ผ่านท่อทาง |
หมายเหตุ¶
- Fly.ioใช้สถาปัตยกรรมx86(ไม่ใช่ARM)
- Dockerfileรองรับทั้งสองสถาปัตยกรรม
- สำหรับการเริ่มต้นใช้งานWhatsApp/Telegramให้ใช้
fly ssh console - ข้อมูลถาวรอยู่บนโวลุ่มที่
/data - Signalต้องใช้Java+signal-cli; ใช้อิมเมจแบบกำหนดเองและคงหน่วยความจำไว้ที่2GBขึ้นไป
ค่าใช้จ่าย¶
ด้วยคอนฟิกที่แนะนำ(shared-cpu-2x, RAM2GB):
- ประมาณ$10-15/เดือนขึ้นอยู่กับการใช้งาน
- ระดับฟรีมีโควตาบางส่วน
ดูรายละเอียดที่ราคาFly.io