Deploy Moltbot To Fly
Deploy Moltbot to Fly.io with persistent storage, secure token authentication, environment secrets, and approved device pairing for web UI access.
技能说明
Deploy Moltbot to Fly.io
Deploy Moltbot (Clawdbot) to Fly.io with proper configuration, persistent storage, and device pairing.
Overview
Deploying Moltbot to Fly.io requires:
- Setting up the Fly app with a persistent volume
- Configuring environment secrets (API keys, gateway token)
- Creating a proper config file with token authentication
- Approving device pairing for web UI access
Prerequisites
Before starting:
- Fly.io CLI installed (
brew install flyctlorcurl -L https://fly.io/install.sh | sh) - Fly.io account and logged in (
fly auth login) - Anthropic API key (and optionally OpenAI API key)
- Git installed
Phase 1: Clone and Setup
1.1 Clone the Moltbot Repository
git clone https://github.com/clawdbot/clawdbot.git moltbot-deploy
cd moltbot-deploy
1.2 Generate Gateway Token
Generate a secure token for authentication:
openssl rand -hex 32
IMPORTANT: Save this token - you'll need it for:
- Fly secrets
- Config file
- Web UI access URL
Phase 2: Fly.io Configuration
2.1 Create fly.toml
Create fly.toml with the correct configuration:
app = 'your-app-name'
primary_region = 'iad'
[build]
dockerfile = 'Dockerfile'
[env]
NODE_ENV = 'production'
CLAWDBOT_PREFER_PNPM = '1'
CLAWDBOT_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 = 'moltbot_data'
destination = '/data'
CRITICAL Settings:
CLAWDBOT_STATE_DIR = '/data'- Required for proper config persistence--bind lan- Allows Fly's proxy to reach the gatewayhttp_service- Newer Fly format (not[[services]])memory = '2048mb'- 512MB is too small; 2GB recommended
2.2 Create App and Volume
fly apps create your-app-name
fly volumes create moltbot_data --region iad --size 1 -a your-app-name -y
Choose a region close to you:
iad- Virginia (US East)lhr- Londonsjc- San Jose (US West)
2.3 Set Fly Secrets
# Set your generated token
fly secrets set CLAWDBOT_GATEWAY_TOKEN="YOUR-TOKEN-HERE" -a your-app-name
# Set API keys
fly secrets set ANTHROPIC_API_KEY="sk-ant-xxxxx" -a your-app-name
fly secrets set OPENAI_API_KEY="sk-xxxxx" -a your-app-name # Optional
Note: Secrets are deployed on first fly deploy, not immediately.
Phase 3: Deploy
Deploy the application:
fly deploy -a your-app-name
First deployment takes ~3-5 minutes (building Docker image).
Wait for gateway to start:
fly logs -a your-app-name --no-tail | grep "listening on"
You should see:
[gateway] listening on ws://0.0.0.0:3000 (PID xxx)
Phase 4: Create Config File
CRITICAL: The config file must include the same token as the env var for authentication to work.
4.1 SSH into the machine
fly ssh console -a your-app-name
4.2 Create the config file
cat > /data/moltbot.json << 'EOF'
{
"gateway": {
"mode": "local",
"bind": "lan",
"auth": {
"mode": "token",
"token": "YOUR-TOKEN-HERE"
}
},
"agents": {
"defaults": {
"model": {
"primary": "anthropic/claude-opus-4-5"
}
}
},
"auth": {
"profiles": {
"anthropic:default": { "mode": "token", "provider": "anthropic" }
}
}
}
EOF
Replace YOUR-TOKEN-HERE with your actual token!
4.3 Exit and restart
exit
fly machine restart <machine-id> -a your-app-name
Get machine ID with: fly machines list -a your-app-name
Phase 5: Access and Device Pairing
5.1 Wait for DNS propagation
DNS may take 2-5 minutes to propagate. Check status:
nslookup your-app-name.fly.dev 8.8.8.8
If DNS isn't resolving on your machine, flush your DNS cache:
macOS:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
Linux:
sudo systemd-resolve --flush-caches
5.2 Access Web UI
Open in browser with the tokenized URL:
https://your-app-name.fly.dev/?token=YOUR-TOKEN-HERE
You'll see "disconnected (1008): pairing required" - this is normal!
5.3 Approve Device Pairing
While the browser is open and attempting to connect, approve the pairing:
fly ssh console -a your-app-name
Then run:
node -e "
const fs = require('fs');
const pending = JSON.parse(fs.readFileSync('/data/devices/pending.json'));
const paired = JSON.parse(fs.readFileSync('/data/devices/paired.json') || '{}');
const requestId = Object.keys(pending)[0];
if (requestId) {
const device = pending[requestId];
paired[device.deviceId] = {
deviceId: device.deviceId,
publicKey: device.publicKey,
platform: device.platform,
clientId: device.clientId,
role: device.role,
roles: device.roles,
scopes: device.scopes,
approvedAt: Date.now(),
approvedBy: 'cli'
};
delete pending[requestId];
fs.writeFileSync('/data/devices/pending.json', JSON.stringify(pending, null, 2));
fs.writeFileSync('/data/devices/paired.json', JSON.stringify(paired, null, 2));
console.log('Approved device:', device.deviceId);
} else {
console.log('No pending devices');
}
"
5.4 Refresh Browser
After approval, refresh your browser. You should now be connected! 🎉
Troubleshooting
Gateway Token Mismatch
Symptoms: unauthorized: gateway token mismatch
Fix: Token in config file must match the env var:
# Check env var token
fly ssh console -a your-app-name -C "printenv CLAWDBOT_GATEWAY_TOKEN"
# Update config file to match
fly ssh console -a your-app-name
# Edit /data/moltbot.json and update gateway.auth.token
App Not Listening / Connection Refused
Symptoms: instance refused connection or not listening on expected address
Fix: Ensure --bind lan in fly.toml and gateway is fully started:
fly logs -a your-app-name --no-tail | tail -50
Wait 30-60 seconds after deploy for gateway to initialize.
DNS Not Resolving
Symptoms: Could not resolve host
Fix:
- Wait 2-5 minutes for DNS propagation
- Use Google DNS:
8.8.8.8or1.1.1.1 - Flush local DNS cache (see Phase 5.1)
Config Validation Errors
Symptoms: Gateway exits with "Invalid input" or validation errors
Fix: Check config syntax:
fly ssh console -a your-app-name -C "cat /data/moltbot.json"
Common issues:
- Invalid
auth.mode: Only"token"is valid (not"off") - Missing commas in JSON
- Mismatched quotes
State Not Persisting
Symptoms: Config/devices reset after restart
Fix: Ensure CLAWDBOT_STATE_DIR=/data is set in fly.toml [env] section.
Stuck Deployment
Symptoms: Machine keeps restarting or won't stabilize
Nuclear option (fastest):
fly apps destroy your-app-name -y
# Then re-run Phase 2 onwards with fresh setup
Advanced: Trusted Proxies (Optional)
If you see proxy warnings in logs, add trusted proxies:
fly ssh console -a your-app-name
node -e "
const fs = require('fs');
const config = JSON.parse(fs.readFileSync('/data/moltbot.json'));
config.gateway.trustedProxies = [
'172.16.0.0/12',
'10.0.0.0/8'
];
fs.writeFileSync('/data/moltbot.json', JSON.stringify(config, null, 2));
console.log('Trusted proxies configured');
"
Restart machine after changes.
Quick Reference
# Check status
fly status -a APP
# View logs
fly logs -a APP --no-tail | tail -50
# SSH into machine
fly ssh console -a APP
# Restart machine
fly machines list -a APP # Get machine ID
fly machine restart <machine-id> -a APP
# Check secrets
fly secrets list -a APP
# Get gateway token
fly ssh console -a APP -C "printenv CLAWDBOT_GATEWAY_TOKEN"
# Redeploy
fly deploy -a APP
Updates
To update Moltbot:
cd moltbot-deploy
git pull
fly deploy -a your-app-name
Config and paired devices persist on the volume across updates.
Key Lessons
CLAWDBOT_STATE_DIR=/datais critical - without it, config location is wrong- Token must be in BOTH env var AND config file
- Use
http_servicenot[[services]](newer Fly format) - Device pairing is required even with token auth
- DNS takes time - wait 2-5 minutes, flush cache if needed
- Fresh deploy is often faster than debugging corrupted state
- 2GB RAM minimum - 512MB will OOM, 1GB may work but 2GB is recommended
Resources
如何使用「Deploy Moltbot To Fly」?
- 打开小龙虾AI(Web 或 iOS App)
- 点击上方「立即使用」按钮,或在对话框中输入任务描述
- 小龙虾AI 会自动匹配并调用「Deploy Moltbot To Fly」技能完成任务
- 结果即时呈现,支持继续对话优化