ワンクリックで
deploy-moltbot-to-fly
Deploy Moltbot (Clawdbot) to Fly.io with proper proxy configuration, trusted proxies setup, and device pairing
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Deploy Moltbot (Clawdbot) to Fly.io with proper proxy configuration, trusted proxies setup, and device pairing
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
| name | deploy-moltbot-to-fly |
| description | Deploy Moltbot (Clawdbot) to Fly.io with proper proxy configuration, trusted proxies setup, and device pairing |
You are helping the user deploy Moltbot (also known as Clawdbot) to Fly.io. This is a comprehensive guide that handles all the tricky configuration including trusted proxies for Fly's internal network and device pairing approval.
Deploying Moltbot to Fly.io requires:
trustedProxies to allow Fly's internal proxy networkBefore starting:
brew install flyctl or curl -L https://fly.io/install.sh | sh)fly auth login)git clone https://github.com/moltbot/moltbot.git
cd moltbot
Create a .env.example file in the project root with the required environment variables:
cat > .env.example << 'EOF'
# Required: Your Anthropic API key
ANTHROPIC_API_KEY=sk-ant-xxxxx
# Optional: OpenAI API key for fallback models
OPENAI_API_KEY=sk-xxxxx
# Required: Gateway token for authentication (generate with: openssl rand -hex 32)
CLAWDBOT_GATEWAY_TOKEN=your-64-char-hex-token
# Optional: Slack Bot Token (if using Slack)
SLACK_BOT_TOKEN=xoxb-xxxxx
# Optional: Discord Bot Token (if using Discord)
DISCORD_BOT_TOKEN=your-discord-bot-token
EOF
Tell the user:
"Please copy .env.example to .env and fill in your API keys. At minimum, you need:
ANTHROPIC_API_KEY: Your Anthropic API keyCLAWDBOT_GATEWAY_TOKEN: Generate with openssl rand -hex 32"openssl rand -hex 32
Save this token - you'll need it for Fly secrets and for web UI authentication.
Create or update fly.toml in the project root:
app = 'your-app-name'
primary_region = 'iad'
[build]
dockerfile = 'Dockerfile'
[env]
NODE_ENV = 'production'
TZ = 'UTC'
[processes]
app = "node dist/index.js gateway --allow-unconfigured --port 3000 --bind lan"
[[mounts]]
source = 'moltbot_data'
destination = '/data'
[[vm]]
size = 'shared-cpu-2x'
memory = '2gb'
[[services]]
internal_port = 3000
protocol = 'tcp'
[[services.ports]]
handlers = ['http']
port = 80
force_https = true
[[services.ports]]
handlers = ['tls', 'http']
port = 443
CRITICAL: The --bind lan flag is essential. It tells the gateway to bind to the LAN interface which maps to 0.0.0.0 inside the Fly VM.
fly apps create your-app-name
fly volumes create moltbot_data --region iad --size 1
# Required secrets
fly secrets set ANTHROPIC_API_KEY="sk-ant-xxxxx" -a your-app-name
fly secrets set CLAWDBOT_GATEWAY_TOKEN="$(openssl rand -hex 32)" -a your-app-name
# Optional secrets
fly secrets set OPENAI_API_KEY="sk-xxxxx" -a your-app-name
fly secrets set SLACK_BOT_TOKEN="xoxb-xxxxx" -a your-app-name
fly secrets set DISCORD_BOT_TOKEN="your-token" -a your-app-name
Important: Save the CLAWDBOT_GATEWAY_TOKEN value - you'll need it later for device pairing.
To retrieve the token later:
fly ssh console -a your-app-name -C "printenv CLAWDBOT_GATEWAY_TOKEN"
fly deploy -a your-app-name
The first deploy may take a few minutes. Watch for the "listening on ws://0.0.0.0:3000" message in the logs.
fly logs -a your-app-name --no-tail | tail -30
Look for:
[gateway] listening on ws://0.0.0.0:3000[slack] socket mode connected (if using Slack)CRITICAL STEP: Fly.io routes traffic through internal proxies (172.16.x.x). Without configuring trustedProxies, all connections will fail with "Proxy headers detected from untrusted address".
fly ssh console -a your-app-name
node -e "
const fs = require('fs');
const configPath = '/data/moltbot.json';
let config = {};
try { config = JSON.parse(fs.readFileSync(configPath)); } catch {}
// Ensure gateway config exists
config.gateway = config.gateway || {};
// Add trusted proxies - MUST include the exact Fly proxy IP
// Check your logs for the actual proxy IP (e.g., 172.16.3.162)
config.gateway.trustedProxies = [
'172.16.0.0/12',
'10.0.0.0/8',
'172.16.3.162' // Add the specific IP from your logs
];
config.gateway.mode = 'local';
config.gateway.bind = 'lan';
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
console.log('Config updated with trustedProxies');
"
cat /data/moltbot.json | grep -A5 trustedProxies
exit
fly machines restart -a your-app-name
Wait ~60 seconds for the gateway to fully start.
When you first access the web UI, you'll see "pairing required" errors. This is because Moltbot requires device authentication for security.
Open: https://your-app-name.fly.dev/
You'll see connection errors - this is expected before pairing.
fly ssh console -a your-app-name -C "cat /data/devices/pending.json"
You should see a pending pairing request with a requestId and deviceId.
fly ssh console -a your-app-name -C '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\");
}
"'
Refresh the browser. Check the logs:
fly logs -a your-app-name --no-tail | tail -10
Look for: webchat connected conn=... client=moltbot-control-ui
Run through this checklist to verify everything works:
## Deployment Verification
- [ ] Gateway listening: `fly logs -a APP | grep "listening on ws"`
- [ ] No proxy warnings: `fly logs -a APP | grep -v "untrusted address"`
- [ ] Web UI connected: `fly logs -a APP | grep "webchat connected"`
- [ ] Health check: `curl https://APP.fly.dev/__health`
Cause: trustedProxies not configured or doesn't include the Fly proxy IP.
Fix:
fly logs -a APP | grep "remote="trustedProxies in /data/moltbot.jsonfly machines restart -a APPCause: Device not paired.
Fix:
fly ssh console -a APP -C "cat /data/devices/pending.json"Cause: Gateway taking too long to start (~60 seconds is normal).
Fix:
fly logs -a APP --no-tail | grep "listening"fly ssh console -a APP -C "ps -e | grep moltbot"Cause: Using invalid bind value (e.g., 0.0.0.0).
Fix: Use --bind lan in fly.toml, not --bind 0.0.0.0.
Valid bind values: loopback, lan, tailnet, auto, custom
{
"meta": {
"lastTouchedVersion": "2026.1.27-beta.1"
},
"auth": {
"profiles": {
"anthropic:default": { "provider": "anthropic", "mode": "token" },
"openai:default": { "provider": "openai", "mode": "token" }
}
},
"agents": {
"defaults": {
"model": {
"primary": "anthropic/claude-sonnet-4-5",
"fallbacks": ["anthropic/claude-sonnet-4-5", "openai/gpt-4o"]
},
"maxConcurrent": 4
},
"list": [{ "id": "main", "default": true }]
},
"bindings": [{ "agentId": "main", "match": { "channel": "discord" } }],
"channels": {
"discord": {
"enabled": true,
"groupPolicy": "allowlist",
"guilds": {
"YOUR_GUILD_ID": {
"requireMention": false,
"channels": { "general": { "allow": true } }
}
}
}
},
"gateway": {
"mode": "local",
"bind": "lan",
"trustedProxies": ["172.16.0.0/12", "10.0.0.0/8", "172.16.3.162"]
},
"plugins": {
"entries": {
"discord": { "enabled": true },
"slack": { "enabled": true }
}
}
}
# Deploy
fly deploy -a APP
# Logs
fly logs -a APP --no-tail | tail -50
# SSH
fly ssh console -a APP
# Restart
fly machines restart -a APP
# List secrets
fly secrets list -a APP
# Get gateway token
fly ssh console -a APP -C "printenv CLAWDBOT_GATEWAY_TOKEN"
# Check pending devices
fly ssh console -a APP -C "cat /data/devices/pending.json"
# Check paired devices
fly ssh console -a APP -C "cat /data/devices/paired.json"
# Check config
fly ssh console -a APP -C "cat /data/moltbot.json"