{ "title": "Channel tokens", "content": "fly secrets set DISCORD_BOT_TOKEN=MTQ...\nbash theme={null}\nfly deploy\nbash theme={null}\nfly status\nfly logs\n\n[gateway] listening on ws://0.0.0.0:3000 (PID xxx)\n[discord] logged in to discord as xxx\nbash theme={null}\nfly ssh console\nbash theme={null}\nmkdir -p /data\ncat > /data/openclaw.json << 'EOF'\n{\n \"agents\": {\n \"defaults\": {\n \"model\": {\n \"primary\": \"anthropic/claude-opus-4-5\",\n \"fallbacks\": [\"anthropic/claude-sonnet-4-5\", \"openai/gpt-4o\"]\n },\n \"maxConcurrent\": 4\n },\n \"list\": [\n {\n \"id\": \"main\",\n \"default\": true\n }\n ]\n },\n \"auth\": {\n \"profiles\": {\n \"anthropic:default\": { \"mode\": \"token\", \"provider\": \"anthropic\" },\n \"openai:default\": { \"mode\": \"token\", \"provider\": \"openai\" }\n }\n },\n \"bindings\": [\n {\n \"agentId\": \"main\",\n \"match\": { \"channel\": \"discord\" }\n }\n ],\n \"channels\": {\n \"discord\": {\n \"enabled\": true,\n \"groupPolicy\": \"allowlist\",\n \"guilds\": {\n \"YOUR_GUILD_ID\": {\n \"channels\": { \"general\": { \"allow\": true } },\n \"requireMention\": false\n }\n }\n }\n },\n \"gateway\": {\n \"mode\": \"local\",\n \"bind\": \"auto\"\n },\n \"meta\": {\n \"lastTouchedVersion\": \"2026.1.29\"\n }\n}\nEOF\nbash theme={null}\nexit\nfly machine restart \nbash theme={null}\nfly open\nbash theme={null}\nfly logs # Live logs\nfly logs --no-tail # Recent logs\nbash theme={null}\nfly ssh console\ntoml theme={null}\n[[vm]]\n memory = \"2048mb\"\nbash theme={null}\nfly machine update --vm-memory 2048 -y\nbash theme={null}\nfly ssh console --command \"rm -f /data/gateway.*.lock\"\nfly machine restart \nbash theme={null}\nfly ssh console --command \"cat /data/openclaw.json\"\nbash theme={null}", "code_samples": [ { "code": "**Notes:**\n\n* Non-loopback binds (`--bind lan`) require `OPENCLAW_GATEWAY_TOKEN` for security.\n* Treat these tokens like passwords.\n* **Prefer env vars over config file** for all API keys and tokens. This keeps secrets out of `openclaw.json` where they could be accidentally exposed or logged.\n\n## 4) Deploy", "language": "unknown" }, { "code": "First deploy builds the Docker image (\\~2-3 minutes). Subsequent deploys are faster.\n\nAfter deployment, verify:", "language": "unknown" }, { "code": "You should see:", "language": "unknown" }, { "code": "## 5) Create config file\n\nSSH into the machine to create a proper config:", "language": "unknown" }, { "code": "Create the config directory and file:", "language": "unknown" }, { "code": "**Note:** With `OPENCLAW_STATE_DIR=/data`, the config path is `/data/openclaw.json`.\n\n**Note:** The Discord token can come from either:\n\n* Environment variable: `DISCORD_BOT_TOKEN` (recommended for secrets)\n* Config file: `channels.discord.token`\n\nIf using env var, no need to add token to config. The gateway reads `DISCORD_BOT_TOKEN` automatically.\n\nRestart to apply:", "language": "unknown" }, { "code": "## 6) Access the Gateway\n\n### Control UI\n\nOpen in browser:", "language": "unknown" }, { "code": "Or visit `https://my-openclaw.fly.dev/`\n\nPaste your gateway token (the one from `OPENCLAW_GATEWAY_TOKEN`) to authenticate.\n\n### Logs", "language": "unknown" }, { "code": "### SSH Console", "language": "unknown" }, { "code": "## Troubleshooting\n\n### \"App is not listening on expected address\"\n\nThe gateway is binding to `127.0.0.1` instead of `0.0.0.0`.\n\n**Fix:** Add `--bind lan` to your process command in `fly.toml`.\n\n### Health checks failing / connection refused\n\nFly can't reach the gateway on the configured port.\n\n**Fix:** Ensure `internal_port` matches the gateway port (set `--port 3000` or `OPENCLAW_GATEWAY_PORT=3000`).\n\n### OOM / Memory Issues\n\nContainer keeps restarting or getting killed. Signs: `SIGABRT`, `v8::internal::Runtime_AllocateInYoungGeneration`, or silent restarts.\n\n**Fix:** Increase memory in `fly.toml`:", "language": "unknown" }, { "code": "Or update an existing machine:", "language": "unknown" }, { "code": "**Note:** 512MB is too small. 1GB may work but can OOM under load or with verbose logging. **2GB is recommended.**\n\n### Gateway Lock Issues\n\nGateway refuses to start with \"already running\" errors.\n\nThis happens when the container restarts but the PID lock file persists on the volume.\n\n**Fix:** Delete the lock file:", "language": "unknown" }, { "code": "The lock file is at `/data/gateway.*.lock` (not in a subdirectory).\n\n### Config Not Being Read\n\nIf using `--allow-unconfigured`, the gateway creates a minimal config. Your custom config at `/data/openclaw.json` should be read on restart.\n\nVerify the config exists:", "language": "unknown" }, { "code": "### Writing Config via SSH\n\nThe `fly ssh console -C` command doesn't support shell redirection. To write a config file:", "language": "unknown" } ], "headings": [ { "level": "h2", "text": "4) Deploy", "id": "4)-deploy" }, { "level": "h2", "text": "5) Create config file", "id": "5)-create-config-file" }, { "level": "h2", "text": "6) Access the Gateway", "id": "6)-access-the-gateway" }, { "level": "h3", "text": "Control UI", "id": "control-ui" }, { "level": "h3", "text": "Logs", "id": "logs" }, { "level": "h3", "text": "SSH Console", "id": "ssh-console" }, { "level": "h2", "text": "Troubleshooting", "id": "troubleshooting" }, { "level": "h3", "text": "\"App is not listening on expected address\"", "id": "\"app-is-not-listening-on-expected-address\"" }, { "level": "h3", "text": "Health checks failing / connection refused", "id": "health-checks-failing-/-connection-refused" }, { "level": "h3", "text": "OOM / Memory Issues", "id": "oom-/-memory-issues" }, { "level": "h3", "text": "Gateway Lock Issues", "id": "gateway-lock-issues" }, { "level": "h3", "text": "Config Not Being Read", "id": "config-not-being-read" }, { "level": "h3", "text": "Writing Config via SSH", "id": "writing-config-via-ssh" } ], "url": "llms-txt#channel-tokens", "links": [] }