Triển khai Fly.io¶
Mục tiêu: OpenClaw Gateway chạy trên một máy Fly.io với lưu trữ bền vững, HTTPS tự động và quyền truy cập Discord/kênh.
Những gì bạn cần¶
- flyctl CLI đã cài đặt
- Tài khoản Fly.io (gói miễn phí dùng được)
- Xác thực mô hình: khóa API Anthropic (hoặc khóa của nhà cung cấp khác)
- Thông tin xác thực kênh: token bot Discord, token Telegram, v.v.
Lộ trình nhanh cho người mới¶
- Clone repo → tùy chỉnh
fly.toml - Tạo app + volume → đặt secrets
- Triển khai bằng
fly deploy - SSH vào để tạo cấu hình hoặc dùng Control UI
1) Tạo app 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
Mẹo: Chọn khu vực gần bạn. Các tùy chọn phổ biến: lhr (London), iad (Virginia), sjc (San Jose).
2. Cấu hình fly.toml¶
Chỉnh sửa fly.toml để khớp với tên app và yêu cầu của bạn.
Lưu ý bảo mật: Cấu hình mặc định sẽ hiển thị một URL công khai. Để triển khai tăng cường bảo mật không có IP công khai, xem Triển khai Riêng tư hoặc sử dụng 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"
Thiết lập chính:
| Thiết lập | Lý do |
|---|---|
--bind lan |
Gắn vào 0.0.0.0 để proxy của Fly có thể truy cập gateway |
--allow-unconfigured |
Khởi động không cần file cấu hình (bạn sẽ tạo sau) |
internal_port = 3000 |
Phải khớp với --port 3000 (hoặc OPENCLAW_GATEWAY_PORT) cho health check của Fly |
memory = "2048mb" |
512MB là quá ít; khuyến nghị 2GB |
OPENCLAW_STATE_DIR = "/data" |
Lưu trạng thái trên volume |
3. Đặt 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...
Ghi chú:
- Bind không phải loopback (
--bind lan) yêu cầuOPENCLAW_GATEWAY_TOKENđể bảo mật. - Hãy coi các token này như mật khẩu.
- Ưu tiên sử dụng biến môi trường (env vars) thay cho file cấu hình cho tất cả các khóa và token API. Điều này giúp giữ bí mật ngoài
openclaw.json, nơi chúng có thể vô tình bị lộ hoặc bị ghi log.
4. Triển khai¶
fly deploy
Lần triển khai đầu tiên sẽ build Docker image (~2–3 phút). Subsequent deploys are faster.
Sau khi triển khai, xác minh:
fly status
fly logs
Bạn sẽ thấy:
[gateway] listening on ws://0.0.0.0:3000 (PID xxx)
[discord] logged in to discord as xxx
5. Tạo file cấu hình¶
SSH vào máy để tạo cấu hình phù hợp:
fly ssh console
Tạo thư mục và file cấu hình:
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
Lưu ý: Với OPENCLAW_STATE_DIR=/data, đường dẫn cấu hình là /data/openclaw.json.
Lưu ý: Token Discord có thể đến từ một trong hai nguồn:
- Biến môi trường:
DISCORD_BOT_TOKEN(khuyến nghị cho bí mật) - File cấu hình:
channels.discord.token
If using env var, no need to add token to config. Gateway tự động đọc DISCORD_BOT_TOKEN.
Khởi động lại để áp dụng:
exit
fly machine restart <machine-id>
6. Truy cập Gateway¶
Control UI¶
Mở trên trình duyệt:
fly open
Hoặc truy cập https://my-openclaw.fly.dev/
Dán token gateway của bạn (token từ OPENCLAW_GATEWAY_TOKEN) để xác thực.
Logs¶
fly logs # Live logs
fly logs --no-tail # Recent logs
SSH Console¶
fly ssh console
Xử lý sự cố¶
"Ứng dụng không lắng nghe trên địa chỉ mong đợi"¶
Gateway đang bind vào 127.0.0.1 thay vì 0.0.0.0.
Cách khắc phục: Thêm --bind lan vào lệnh process trong fly.toml.
Health check thất bại / connection refused¶
Fly không thể truy cập gateway trên cổng đã cấu hình.
Cách khắc phục: Đảm bảo internal_port khớp với cổng gateway (đặt --port 3000 hoặc OPENCLAW_GATEWAY_PORT=3000).
OOM / Vấn đề bộ nhớ¶
Container liên tục khởi động lại hoặc bị dừng. Dấu hiệu: SIGABRT, v8::internal::Runtime_AllocateInYoungGeneration, hoặc tự khởi động lại mà không có thông báo.
Cách khắc phục: Tăng bộ nhớ trong fly.toml:
[[vm]]
memory = "2048mb"
Hoặc cập nhật một máy hiện có:
fly machine update <machine-id> --vm-memory 2048 -y
Note: 512MB is too small. 1GB may work but can OOM under load or with verbose logging. Khuyến nghị 2GB.
Sự cố khóa Gateway¶
Gateway từ chối khởi động với lỗi "already running".
Điều này xảy ra khi container khởi động lại nhưng file khóa PID vẫn tồn tại trên volume.
Cách khắc phục: Xóa file khóa:
fly ssh console --command "rm -f /data/gateway.*.lock"
fly machine restart <machine-id>
File khóa nằm tại /data/gateway.*.lock (không nằm trong thư mục con).
Cấu hình không được đọc¶
Nếu dùng --allow-unconfigured, gateway sẽ tạo một cấu hình tối thiểu. Your custom config at /data/openclaw.json should be read on restart.
Xác minh cấu hình tồn tại:
fly ssh console --command "cat /data/openclaw.json"
Ghi cấu hình qua SSH¶
The fly ssh console -C command doesn't support shell redirection. Để ghi một file cấu hình:
# 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
Lưu ý: fly sftp có thể thất bại nếu file đã tồn tại. Delete first:
fly ssh console --command "rm /data/openclaw.json"
Trạng thái không được lưu¶
Nếu bạn mất thông tin xác thực hoặc phiên sau khi khởi động lại, thư mục trạng thái đang ghi vào filesystem của container.
Cách khắc phục: Đảm bảo OPENCLAW_STATE_DIR=/data được đặt trong fly.toml và triển khai lại.
Cập nhật¶
# Pull latest changes
git pull
# Redeploy
fly deploy
# Check health
fly status
fly logs
Cập nhật lệnh máy¶
Nếu bạn cần thay đổi lệnh khởi động mà không triển khai lại toàn bộ:
# 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
Lưu ý: Sau fly deploy, lệnh máy có thể reset về giá trị trong fly.toml. If you made manual changes, re-apply them after deploy.
Triển khai riêng tư (Gia cố)¶
By default, Fly allocates public IPs, making your gateway accessible at https://your-app.fly.dev. This is convenient but means your deployment is discoverable by internet scanners (Shodan, Censys, etc.).
Để triển khai được gia cố với không phơi bày công khai, hãy dùng mẫu riêng tư.
Khi nào nên dùng triển khai riêng tư¶
- Bạn chỉ thực hiện cuộc gọi/tin nhắn outbound (không có webhook inbound)
- Bạn dùng ngrok hoặc Tailscale cho mọi callback webhook
- Bạn truy cập gateway qua SSH, proxy, hoặc WireGuard thay vì trình duyệt
- Bạn muốn triển khai ẩn khỏi các trình quét internet
Thiết lập¶
Dùng fly.private.toml thay cho cấu hình tiêu chuẩn:
# Deploy with private config
fly deploy -c fly.private.toml
Hoặc chuyển đổi một triển khai hiện có:
# 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
Sau đó, fly ips list chỉ nên hiển thị IP kiểu private:
VERSION IP TYPE REGION
v6 fdaa:x:x:x:x::x private global
Truy cập triển khai riêng tư¶
Vì không có URL công khai, hãy dùng một trong các cách sau:
Tùy chọn 1: Proxy cục bộ (đơn giản nhất)
# Forward local port 3000 to the app
fly proxy 3000:3000 -a my-openclaw
# Then open http://localhost:3000 in browser
Tùy chọn 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
Tùy chọn 3: Chỉ SSH
fly ssh console -a my-openclaw
Webhook với triển khai riêng tư¶
If you need webhook callbacks (Twilio, Telnyx, etc.) without public exposure:
- Đường hầm ngrok – Chạy ngrok bên trong container hoặc như một sidecar
- Tailscale Funnel – Mở các đường dẫn cụ thể qua Tailscale
- Chỉ outbound – Một số nhà cung cấp (Twilio) hoạt động tốt cho outbound mà không cần webhook
Ví dụ cấu hình gọi thoại với 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. Set webhookSecurity.allowedHosts to the public tunnel hostname so forwarded host headers are accepted.
Lợi ích bảo mật¶
| Khía cạnh | Công khai | Riêng tư |
|---|---|---|
| Trình quét internet | Có thể phát hiện | Ẩn |
| Tấn công trực tiếp | Có thể | Bị chặn |
| Truy cập Control UI | Trình duyệt | Proxy/VPN |
| Giao webhook | Trực tiếp | Qua đường hầm |
Ghi chú¶
- Fly.io dùng kiến trúc x86 (không phải ARM)
- Dockerfile tương thích với cả hai kiến trúc
- Với onboarding WhatsApp/Telegram, dùng
fly ssh console - Dữ liệu bền vững nằm trên volume tại
/data - Signal yêu cầu Java + signal-cli; dùng image tùy chỉnh và giữ bộ nhớ ở mức 2GB+.
Chi phí¶
Với cấu hình khuyến nghị (shared-cpu-2x, RAM 2GB):
- ~$10–15/tháng tùy mức sử dụng
- Gói miễn phí có bao gồm một phần hạn mức
Xem bảng giá Fly.io để biết chi tiết.