Skill: hollaugo/deploy-moltbot-to-fly (version 0.1.3)

# 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: 1. Setting up the Fly app with a persistent volume 2. Configuring environment secrets (API keys, gateway token) 3. Creating a proper config file with token authentication 4. Approving device pairing for web UI access ## Prerequisites Before starting: - Fly.io CLI installed (`brew install flyctl` or `curl -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 ```bash git clone https://github.com/clawdbot/clawdbot.git moltbot-deploy cd moltbot-deploy ``` ### 1.2 Generate Gateway Token Generate a secure token for authentication: ```bash 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: ```toml 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 gateway - `http_service` - Newer Fly format (not `[[services]]`) - `memory = '2048mb'` - 512MB is too small; 2GB recommended ### 2.2 Create App and Volume ```bash 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` - London - `sjc` - San Jose (US West) ### 2.3 Set Fly Secrets ```bash # 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: ```bash fly deploy -a your-app-name ``` First deployment takes ~3-5 minutes (building Docker image). **Wait for gateway to start:** ```bash 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 ```bash fly ssh console -a your-app-name ``` ### 4.2 Create the config file ```bash 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 ```bash 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: ```bash nslookup your-app-name.fly.dev 8.8.8.8 ``` If DNS isn't resolving on your machine, flush your DNS cache: **macOS:** ```bash sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder ``` **Linux:** ```bash sudo systemd-resolve --flush-caches ``` ### 5.2 Access Web UI Open in browser with the tokenized URL: ``` https://your-app-name.fly.dev/?[REDACTED_SECRET] ``` 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: ```bash fly ssh console -a your-app-name ``` Then run: ```bash 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: ```bash # 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: ```bash 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:** 1. Wait 2-5 minutes for DNS propagation 2. Use Google DNS: `8.8.8.8` or `1.1.1.1` 3. Flush local DNS cache (see Phase 5.1) ### Config Validation Errors **Symptoms:** Gateway exits with "Invalid input" or validation errors **Fix:** Check config syntax: ```bash 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):** ```bash 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: ```bash fly ssh console -a your-app-name ``` ```bash 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 ```bash # 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: ```bash cd moltbot-deploy git pull fly deploy -a your-app-name ``` Config and paired devices persist on the volume across updates. ## Key Lessons 1. **`CLAWDBOT_STATE_DIR=/data`** is critical - without it, config location is wrong 2. **Token must be in BOTH** env var AND config file 3. **Use `http_service`** not `[[services]]` (newer Fly format) 4. **Device pairing is required** even with token auth 5. **DNS takes time** - wait 2-5 minutes, flush cache if needed 6. **Fresh deploy is often faster** than debugging corrupted state 7. **2GB RAM minimum** - 512MB will OOM, 1GB may work but 2GB is recommended ## Resources - [Fly.io Documentation](https://fly.io/docs/) - [Moltbot Official Docs](https://docs.molt.bot/platforms/fly) - [Clawdbot GitHub](https://github.com/clawdbot/clawdbot)


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)