{
  "schemaVersion": "1.0",
  "item": {
    "slug": "deploy-moltbot-to-fly",
    "name": "Deploy Moltbot To Fly",
    "source": "tencent",
    "type": "skill",
    "category": "AI 智能",
    "sourceUrl": "https://clawhub.ai/hollaugo/deploy-moltbot-to-fly",
    "canonicalUrl": "https://clawhub.ai/hollaugo/deploy-moltbot-to-fly",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/deploy-moltbot-to-fly",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=deploy-moltbot-to-fly",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "skill.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/deploy-moltbot-to-fly"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/deploy-moltbot-to-fly",
    "agentPageUrl": "https://openagent3.xyz/skills/deploy-moltbot-to-fly/agent",
    "manifestUrl": "https://openagent3.xyz/skills/deploy-moltbot-to-fly/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/deploy-moltbot-to-fly/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Deploy Moltbot to Fly.io",
        "body": "Deploy Moltbot (Clawdbot) to Fly.io with proper configuration, persistent storage, and device pairing."
      },
      {
        "title": "Overview",
        "body": "Deploying Moltbot to Fly.io requires:\n\nSetting up the Fly app with a persistent volume\nConfiguring environment secrets (API keys, gateway token)\nCreating a proper config file with token authentication\nApproving device pairing for web UI access"
      },
      {
        "title": "Prerequisites",
        "body": "Before starting:\n\nFly.io CLI installed (brew install flyctl or curl -L https://fly.io/install.sh | sh)\nFly.io account and logged in (fly auth login)\nAnthropic API key (and optionally OpenAI API key)\nGit installed"
      },
      {
        "title": "1.1 Clone the Moltbot Repository",
        "body": "git clone https://github.com/clawdbot/clawdbot.git moltbot-deploy\ncd moltbot-deploy"
      },
      {
        "title": "1.2 Generate Gateway Token",
        "body": "Generate a secure token for authentication:\n\nopenssl rand -hex 32\n\nIMPORTANT: Save this token - you'll need it for:\n\nFly secrets\nConfig file\nWeb UI access URL"
      },
      {
        "title": "2.1 Create fly.toml",
        "body": "Create fly.toml with the correct configuration:\n\napp = 'your-app-name'\nprimary_region = 'iad'\n\n[build]\n  dockerfile = 'Dockerfile'\n\n[env]\n  NODE_ENV = 'production'\n  CLAWDBOT_PREFER_PNPM = '1'\n  CLAWDBOT_STATE_DIR = '/data'\n  NODE_OPTIONS = '--max-old-space-size=1536'\n\n[processes]\n  app = \"node dist/index.js gateway --allow-unconfigured --port 3000 --bind lan\"\n\n[http_service]\n  internal_port = 3000\n  force_https = true\n  auto_stop_machines = false\n  auto_start_machines = true\n  min_machines_running = 1\n  processes = [\"app\"]\n\n[[vm]]\n  size = 'shared-cpu-2x'\n  memory = '2048mb'\n\n[mounts]\n  source = 'moltbot_data'\n  destination = '/data'\n\nCRITICAL Settings:\n\nCLAWDBOT_STATE_DIR = '/data' - Required for proper config persistence\n--bind lan - Allows Fly's proxy to reach the gateway\nhttp_service - Newer Fly format (not [[services]])\nmemory = '2048mb' - 512MB is too small; 2GB recommended"
      },
      {
        "title": "2.2 Create App and Volume",
        "body": "fly apps create your-app-name\nfly volumes create moltbot_data --region iad --size 1 -a your-app-name -y\n\nChoose a region close to you:\n\niad - Virginia (US East)\nlhr - London\nsjc - San Jose (US West)"
      },
      {
        "title": "2.3 Set Fly Secrets",
        "body": "# Set your generated token\nfly secrets set CLAWDBOT_GATEWAY_TOKEN=\"YOUR-TOKEN-HERE\" -a your-app-name\n\n# Set API keys\nfly secrets set ANTHROPIC_API_KEY=\"sk-ant-xxxxx\" -a your-app-name\nfly secrets set OPENAI_API_KEY=\"sk-xxxxx\" -a your-app-name  # Optional\n\nNote: Secrets are deployed on first fly deploy, not immediately."
      },
      {
        "title": "Phase 3: Deploy",
        "body": "Deploy the application:\n\nfly deploy -a your-app-name\n\nFirst deployment takes ~3-5 minutes (building Docker image).\n\nWait for gateway to start:\n\nfly logs -a your-app-name --no-tail | grep \"listening on\"\n\nYou should see:\n\n[gateway] listening on ws://0.0.0.0:3000 (PID xxx)"
      },
      {
        "title": "Phase 4: Create Config File",
        "body": "CRITICAL: The config file must include the same token as the env var for authentication to work."
      },
      {
        "title": "4.1 SSH into the machine",
        "body": "fly ssh console -a your-app-name"
      },
      {
        "title": "4.2 Create the config file",
        "body": "cat > /data/moltbot.json << 'EOF'\n{\n  \"gateway\": {\n    \"mode\": \"local\",\n    \"bind\": \"lan\",\n    \"auth\": {\n      \"mode\": \"token\",\n      \"token\": \"YOUR-TOKEN-HERE\"\n    }\n  },\n  \"agents\": {\n    \"defaults\": {\n      \"model\": {\n        \"primary\": \"anthropic/claude-opus-4-5\"\n      }\n    }\n  },\n  \"auth\": {\n    \"profiles\": {\n      \"anthropic:default\": { \"mode\": \"token\", \"provider\": \"anthropic\" }\n    }\n  }\n}\nEOF\n\nReplace YOUR-TOKEN-HERE with your actual token!"
      },
      {
        "title": "4.3 Exit and restart",
        "body": "exit\nfly machine restart <machine-id> -a your-app-name\n\nGet machine ID with: fly machines list -a your-app-name"
      },
      {
        "title": "5.1 Wait for DNS propagation",
        "body": "DNS may take 2-5 minutes to propagate. Check status:\n\nnslookup your-app-name.fly.dev 8.8.8.8\n\nIf DNS isn't resolving on your machine, flush your DNS cache:\n\nmacOS:\n\nsudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder\n\nLinux:\n\nsudo systemd-resolve --flush-caches"
      },
      {
        "title": "5.2 Access Web UI",
        "body": "Open in browser with the tokenized URL:\n\nhttps://your-app-name.fly.dev/?token=YOUR-TOKEN-HERE\n\nYou'll see \"disconnected (1008): pairing required\" - this is normal!"
      },
      {
        "title": "5.3 Approve Device Pairing",
        "body": "While the browser is open and attempting to connect, approve the pairing:\n\nfly ssh console -a your-app-name\n\nThen run:\n\nnode -e \"\nconst fs = require('fs');\nconst pending = JSON.parse(fs.readFileSync('/data/devices/pending.json'));\nconst paired = JSON.parse(fs.readFileSync('/data/devices/paired.json') || '{}');\nconst requestId = Object.keys(pending)[0];\nif (requestId) {\n  const device = pending[requestId];\n  paired[device.deviceId] = {\n    deviceId: device.deviceId,\n    publicKey: device.publicKey,\n    platform: device.platform,\n    clientId: device.clientId,\n    role: device.role,\n    roles: device.roles,\n    scopes: device.scopes,\n    approvedAt: Date.now(),\n    approvedBy: 'cli'\n  };\n  delete pending[requestId];\n  fs.writeFileSync('/data/devices/pending.json', JSON.stringify(pending, null, 2));\n  fs.writeFileSync('/data/devices/paired.json', JSON.stringify(paired, null, 2));\n  console.log('Approved device:', device.deviceId);\n} else {\n  console.log('No pending devices');\n}\n\""
      },
      {
        "title": "5.4 Refresh Browser",
        "body": "After approval, refresh your browser. You should now be connected! 🎉"
      },
      {
        "title": "Gateway Token Mismatch",
        "body": "Symptoms: unauthorized: gateway token mismatch\n\nFix: Token in config file must match the env var:\n\n# Check env var token\nfly ssh console -a your-app-name -C \"printenv CLAWDBOT_GATEWAY_TOKEN\"\n\n# Update config file to match\nfly ssh console -a your-app-name\n# Edit /data/moltbot.json and update gateway.auth.token"
      },
      {
        "title": "App Not Listening / Connection Refused",
        "body": "Symptoms: instance refused connection or not listening on expected address\n\nFix: Ensure --bind lan in fly.toml and gateway is fully started:\n\nfly logs -a your-app-name --no-tail | tail -50\n\nWait 30-60 seconds after deploy for gateway to initialize."
      },
      {
        "title": "DNS Not Resolving",
        "body": "Symptoms: Could not resolve host\n\nFix:\n\nWait 2-5 minutes for DNS propagation\nUse Google DNS: 8.8.8.8 or 1.1.1.1\nFlush local DNS cache (see Phase 5.1)"
      },
      {
        "title": "Config Validation Errors",
        "body": "Symptoms: Gateway exits with \"Invalid input\" or validation errors\n\nFix: Check config syntax:\n\nfly ssh console -a your-app-name -C \"cat /data/moltbot.json\"\n\nCommon issues:\n\nInvalid auth.mode: Only \"token\" is valid (not \"off\")\nMissing commas in JSON\nMismatched quotes"
      },
      {
        "title": "State Not Persisting",
        "body": "Symptoms: Config/devices reset after restart\n\nFix: Ensure CLAWDBOT_STATE_DIR=/data is set in fly.toml [env] section."
      },
      {
        "title": "Stuck Deployment",
        "body": "Symptoms: Machine keeps restarting or won't stabilize\n\nNuclear option (fastest):\n\nfly apps destroy your-app-name -y\n# Then re-run Phase 2 onwards with fresh setup"
      },
      {
        "title": "Advanced: Trusted Proxies (Optional)",
        "body": "If you see proxy warnings in logs, add trusted proxies:\n\nfly ssh console -a your-app-name\n\nnode -e \"\nconst fs = require('fs');\nconst config = JSON.parse(fs.readFileSync('/data/moltbot.json'));\nconfig.gateway.trustedProxies = [\n  '172.16.0.0/12',\n  '10.0.0.0/8'\n];\nfs.writeFileSync('/data/moltbot.json', JSON.stringify(config, null, 2));\nconsole.log('Trusted proxies configured');\n\"\n\nRestart machine after changes."
      },
      {
        "title": "Quick Reference",
        "body": "# Check status\nfly status -a APP\n\n# View logs\nfly logs -a APP --no-tail | tail -50\n\n# SSH into machine\nfly ssh console -a APP\n\n# Restart machine\nfly machines list -a APP  # Get machine ID\nfly machine restart <machine-id> -a APP\n\n# Check secrets\nfly secrets list -a APP\n\n# Get gateway token\nfly ssh console -a APP -C \"printenv CLAWDBOT_GATEWAY_TOKEN\"\n\n# Redeploy\nfly deploy -a APP"
      },
      {
        "title": "Updates",
        "body": "To update Moltbot:\n\ncd moltbot-deploy\ngit pull\nfly deploy -a your-app-name\n\nConfig and paired devices persist on the volume across updates."
      },
      {
        "title": "Key Lessons",
        "body": "CLAWDBOT_STATE_DIR=/data is critical - without it, config location is wrong\nToken must be in BOTH env var AND config file\nUse http_service not [[services]] (newer Fly format)\nDevice pairing is required even with token auth\nDNS takes time - wait 2-5 minutes, flush cache if needed\nFresh deploy is often faster than debugging corrupted state\n2GB RAM minimum - 512MB will OOM, 1GB may work but 2GB is recommended"
      },
      {
        "title": "Resources",
        "body": "Fly.io Documentation\nMoltbot Official Docs\nClawdbot GitHub"
      }
    ],
    "body": "Deploy Moltbot to Fly.io\n\nDeploy Moltbot (Clawdbot) to Fly.io with proper configuration, persistent storage, and device pairing.\n\nOverview\n\nDeploying Moltbot to Fly.io requires:\n\nSetting up the Fly app with a persistent volume\nConfiguring environment secrets (API keys, gateway token)\nCreating a proper config file with token authentication\nApproving device pairing for web UI access\nPrerequisites\n\nBefore starting:\n\nFly.io CLI installed (brew install flyctl or curl -L https://fly.io/install.sh | sh)\nFly.io account and logged in (fly auth login)\nAnthropic API key (and optionally OpenAI API key)\nGit installed\nPhase 1: Clone and Setup\n1.1 Clone the Moltbot Repository\ngit clone https://github.com/clawdbot/clawdbot.git moltbot-deploy\ncd moltbot-deploy\n\n1.2 Generate Gateway Token\n\nGenerate a secure token for authentication:\n\nopenssl rand -hex 32\n\n\nIMPORTANT: Save this token - you'll need it for:\n\nFly secrets\nConfig file\nWeb UI access URL\nPhase 2: Fly.io Configuration\n2.1 Create fly.toml\n\nCreate fly.toml with the correct configuration:\n\napp = 'your-app-name'\nprimary_region = 'iad'\n\n[build]\n  dockerfile = 'Dockerfile'\n\n[env]\n  NODE_ENV = 'production'\n  CLAWDBOT_PREFER_PNPM = '1'\n  CLAWDBOT_STATE_DIR = '/data'\n  NODE_OPTIONS = '--max-old-space-size=1536'\n\n[processes]\n  app = \"node dist/index.js gateway --allow-unconfigured --port 3000 --bind lan\"\n\n[http_service]\n  internal_port = 3000\n  force_https = true\n  auto_stop_machines = false\n  auto_start_machines = true\n  min_machines_running = 1\n  processes = [\"app\"]\n\n[[vm]]\n  size = 'shared-cpu-2x'\n  memory = '2048mb'\n\n[mounts]\n  source = 'moltbot_data'\n  destination = '/data'\n\n\nCRITICAL Settings:\n\nCLAWDBOT_STATE_DIR = '/data' - Required for proper config persistence\n--bind lan - Allows Fly's proxy to reach the gateway\nhttp_service - Newer Fly format (not [[services]])\nmemory = '2048mb' - 512MB is too small; 2GB recommended\n2.2 Create App and Volume\nfly apps create your-app-name\nfly volumes create moltbot_data --region iad --size 1 -a your-app-name -y\n\n\nChoose a region close to you:\n\niad - Virginia (US East)\nlhr - London\nsjc - San Jose (US West)\n2.3 Set Fly Secrets\n# Set your generated token\nfly secrets set CLAWDBOT_GATEWAY_TOKEN=\"YOUR-TOKEN-HERE\" -a your-app-name\n\n# Set API keys\nfly secrets set ANTHROPIC_API_KEY=\"sk-ant-xxxxx\" -a your-app-name\nfly secrets set OPENAI_API_KEY=\"sk-xxxxx\" -a your-app-name  # Optional\n\n\nNote: Secrets are deployed on first fly deploy, not immediately.\n\nPhase 3: Deploy\n\nDeploy the application:\n\nfly deploy -a your-app-name\n\n\nFirst deployment takes ~3-5 minutes (building Docker image).\n\nWait for gateway to start:\n\nfly logs -a your-app-name --no-tail | grep \"listening on\"\n\n\nYou should see:\n\n[gateway] listening on ws://0.0.0.0:3000 (PID xxx)\n\nPhase 4: Create Config File\n\nCRITICAL: The config file must include the same token as the env var for authentication to work.\n\n4.1 SSH into the machine\nfly ssh console -a your-app-name\n\n4.2 Create the config file\ncat > /data/moltbot.json << 'EOF'\n{\n  \"gateway\": {\n    \"mode\": \"local\",\n    \"bind\": \"lan\",\n    \"auth\": {\n      \"mode\": \"token\",\n      \"token\": \"YOUR-TOKEN-HERE\"\n    }\n  },\n  \"agents\": {\n    \"defaults\": {\n      \"model\": {\n        \"primary\": \"anthropic/claude-opus-4-5\"\n      }\n    }\n  },\n  \"auth\": {\n    \"profiles\": {\n      \"anthropic:default\": { \"mode\": \"token\", \"provider\": \"anthropic\" }\n    }\n  }\n}\nEOF\n\n\nReplace YOUR-TOKEN-HERE with your actual token!\n\n4.3 Exit and restart\nexit\nfly machine restart <machine-id> -a your-app-name\n\n\nGet machine ID with: fly machines list -a your-app-name\n\nPhase 5: Access and Device Pairing\n5.1 Wait for DNS propagation\n\nDNS may take 2-5 minutes to propagate. Check status:\n\nnslookup your-app-name.fly.dev 8.8.8.8\n\n\nIf DNS isn't resolving on your machine, flush your DNS cache:\n\nmacOS:\n\nsudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder\n\n\nLinux:\n\nsudo systemd-resolve --flush-caches\n\n5.2 Access Web UI\n\nOpen in browser with the tokenized URL:\n\nhttps://your-app-name.fly.dev/?token=YOUR-TOKEN-HERE\n\n\nYou'll see \"disconnected (1008): pairing required\" - this is normal!\n\n5.3 Approve Device Pairing\n\nWhile the browser is open and attempting to connect, approve the pairing:\n\nfly ssh console -a your-app-name\n\n\nThen run:\n\nnode -e \"\nconst fs = require('fs');\nconst pending = JSON.parse(fs.readFileSync('/data/devices/pending.json'));\nconst paired = JSON.parse(fs.readFileSync('/data/devices/paired.json') || '{}');\nconst requestId = Object.keys(pending)[0];\nif (requestId) {\n  const device = pending[requestId];\n  paired[device.deviceId] = {\n    deviceId: device.deviceId,\n    publicKey: device.publicKey,\n    platform: device.platform,\n    clientId: device.clientId,\n    role: device.role,\n    roles: device.roles,\n    scopes: device.scopes,\n    approvedAt: Date.now(),\n    approvedBy: 'cli'\n  };\n  delete pending[requestId];\n  fs.writeFileSync('/data/devices/pending.json', JSON.stringify(pending, null, 2));\n  fs.writeFileSync('/data/devices/paired.json', JSON.stringify(paired, null, 2));\n  console.log('Approved device:', device.deviceId);\n} else {\n  console.log('No pending devices');\n}\n\"\n\n5.4 Refresh Browser\n\nAfter approval, refresh your browser. You should now be connected! 🎉\n\nTroubleshooting\nGateway Token Mismatch\n\nSymptoms: unauthorized: gateway token mismatch\n\nFix: Token in config file must match the env var:\n\n# Check env var token\nfly ssh console -a your-app-name -C \"printenv CLAWDBOT_GATEWAY_TOKEN\"\n\n# Update config file to match\nfly ssh console -a your-app-name\n# Edit /data/moltbot.json and update gateway.auth.token\n\nApp Not Listening / Connection Refused\n\nSymptoms: instance refused connection or not listening on expected address\n\nFix: Ensure --bind lan in fly.toml and gateway is fully started:\n\nfly logs -a your-app-name --no-tail | tail -50\n\n\nWait 30-60 seconds after deploy for gateway to initialize.\n\nDNS Not Resolving\n\nSymptoms: Could not resolve host\n\nFix:\n\nWait 2-5 minutes for DNS propagation\nUse Google DNS: 8.8.8.8 or 1.1.1.1\nFlush local DNS cache (see Phase 5.1)\nConfig Validation Errors\n\nSymptoms: Gateway exits with \"Invalid input\" or validation errors\n\nFix: Check config syntax:\n\nfly ssh console -a your-app-name -C \"cat /data/moltbot.json\"\n\n\nCommon issues:\n\nInvalid auth.mode: Only \"token\" is valid (not \"off\")\nMissing commas in JSON\nMismatched quotes\nState Not Persisting\n\nSymptoms: Config/devices reset after restart\n\nFix: Ensure CLAWDBOT_STATE_DIR=/data is set in fly.toml [env] section.\n\nStuck Deployment\n\nSymptoms: Machine keeps restarting or won't stabilize\n\nNuclear option (fastest):\n\nfly apps destroy your-app-name -y\n# Then re-run Phase 2 onwards with fresh setup\n\nAdvanced: Trusted Proxies (Optional)\n\nIf you see proxy warnings in logs, add trusted proxies:\n\nfly ssh console -a your-app-name\n\nnode -e \"\nconst fs = require('fs');\nconst config = JSON.parse(fs.readFileSync('/data/moltbot.json'));\nconfig.gateway.trustedProxies = [\n  '172.16.0.0/12',\n  '10.0.0.0/8'\n];\nfs.writeFileSync('/data/moltbot.json', JSON.stringify(config, null, 2));\nconsole.log('Trusted proxies configured');\n\"\n\n\nRestart machine after changes.\n\nQuick Reference\n# Check status\nfly status -a APP\n\n# View logs\nfly logs -a APP --no-tail | tail -50\n\n# SSH into machine\nfly ssh console -a APP\n\n# Restart machine\nfly machines list -a APP  # Get machine ID\nfly machine restart <machine-id> -a APP\n\n# Check secrets\nfly secrets list -a APP\n\n# Get gateway token\nfly ssh console -a APP -C \"printenv CLAWDBOT_GATEWAY_TOKEN\"\n\n# Redeploy\nfly deploy -a APP\n\nUpdates\n\nTo update Moltbot:\n\ncd moltbot-deploy\ngit pull\nfly deploy -a your-app-name\n\n\nConfig and paired devices persist on the volume across updates.\n\nKey Lessons\nCLAWDBOT_STATE_DIR=/data is critical - without it, config location is wrong\nToken must be in BOTH env var AND config file\nUse http_service not [[services]] (newer Fly format)\nDevice pairing is required even with token auth\nDNS takes time - wait 2-5 minutes, flush cache if needed\nFresh deploy is often faster than debugging corrupted state\n2GB RAM minimum - 512MB will OOM, 1GB may work but 2GB is recommended\nResources\nFly.io Documentation\nMoltbot Official Docs\nClawdbot GitHub"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/hollaugo/deploy-moltbot-to-fly",
    "publisherUrl": "https://clawhub.ai/hollaugo/deploy-moltbot-to-fly",
    "owner": "hollaugo",
    "version": "0.1.3",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/deploy-moltbot-to-fly",
    "downloadUrl": "https://openagent3.xyz/downloads/deploy-moltbot-to-fly",
    "agentUrl": "https://openagent3.xyz/skills/deploy-moltbot-to-fly/agent",
    "manifestUrl": "https://openagent3.xyz/skills/deploy-moltbot-to-fly/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/deploy-moltbot-to-fly/agent.md"
  }
}