Deploy Moltbot to Fly.io

Deploy Moltbot (Clawdbot) to Fly.io with proper configuration, persistent storage, and device pairing.

7 stars

Best use case

Deploy Moltbot to Fly.io is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Deploy Moltbot (Clawdbot) to Fly.io with proper configuration, persistent storage, and device pairing.

Teams using Deploy Moltbot to Fly.io should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/deploy-moltbot-to-fly/SKILL.md --create-dirs "https://raw.githubusercontent.com/Demerzels-lab/elsamultiskillagent/main/public/skills/hollaugo/deploy-moltbot-to-fly/skill.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/deploy-moltbot-to-fly/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How Deploy Moltbot to Fly.io Compares

Feature / AgentDeploy Moltbot to Fly.ioStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Deploy Moltbot (Clawdbot) to Fly.io with proper configuration, persistent storage, and device pairing.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# 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/?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:

```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)

Related Skills

ImageMagick Moltbot Skill

7
from Demerzels-lab/elsamultiskillagent

Comprehensive ImageMagick operations for image manipulation in Moltbot.

moltbot-ha

7
from Demerzels-lab/elsamultiskillagent

Control Home Assistant smart home devices, lights, scenes, and automations via moltbot-ha CLI with configurable safety confirmations.

Deploy Kit — Skill de Déploiement Web

7
from Demerzels-lab/elsamultiskillagent

Simplifie le déploiement d'apps web sur **Vercel**, **Railway** et **Supabase** via leurs CLIs.

deploy-pilot

7
from Demerzels-lab/elsamultiskillagent

Manages the full deploy cycle — build validation, GitHub push, Vercel deployment, and health checks.

moltbot-arena

7
from Demerzels-lab/elsamultiskillagent

AI agent skill for Moltbot Arena - a Screeps-like multiplayer programming game. Use when building game bots, interacting with Moltbot Arena API, controlling units (workers, soldiers, healers), managing structures (spawn, storage, tower, wall), harvesting energy, or competing against other AI agents. Triggers on requests involving Moltbot Arena, real-time strategy bot development, or game automation.

solo-deploy

7
from Demerzels-lab/elsamultiskillagent

Deploy project to hosting platform — read stack YAML for exact config, detect local CLI tools (vercel, wrangler.

sparkbtcbot-proxy-deploy

7
from Demerzels-lab/elsamultiskillagent

Deploy a serverless Spark Bitcoin L2 proxy on Vercel with spending limits, auth, and Redis logging.

railway-deploy

7
from Demerzels-lab/elsamultiskillagent

This skill should be used when the user wants to push code to Railway, says "railway up", "deploy", "deploy.

web-deploy

7
from Demerzels-lab/elsamultiskillagent

Build and deploy websites, web apps, and APIs to production.

moltbot-plugin-2do

7
from Demerzels-lab/elsamultiskillagent

Create tasks and send them to 2Do app via email. Use when the user wants to: (1) add, create, or record a task/todo/reminder in any form - e.g. '添加任务', '创建待办', '新建任务', '加个任务', '记录任务', 'add task', 'create todo'; (2) ask to be reminded of something - e.g. '提醒我', '别忘了', '记得', '帮我记一下', 'remind me', 'remember to'; (3) mention something they need to do and want it tracked - e.g. '明天要开会', '周五前交报告', '下午去买菜'; (4) want to add items to a todo list or task manager - e.g. '加到待办', '放到任务列表', '记到清单里'; (5) describe a task with list/tag organization - e.g. '添加到工作列表', '标签是紧急'; (6) mention urgency or importance - e.g. '紧急', '重要', 'urgent', 'important'. Parses natural language (Chinese and English) to extract task title, due date/time, priority, optional list name, and optional tags, then sends a formatted email to the user's configured 2Do inbox.

appdeploy

7
from Demerzels-lab/elsamultiskillagent

Deploy web apps with backend APIs, database, and file storage. Use when the user asks to deploy or publish a website or web app and wants a public URL. Uses HTTP API via curl.

paylock

7
from Demerzels-lab/elsamultiskillagent

Non-custodial SOL escrow for AI agent deals.