-
Notifications
You must be signed in to change notification settings - Fork 16
initial guides on openclaw #136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
bd89da2
initial openclaw instructions
matthewlouisbrockman d7e3617
try/catch aroudn the js command polling
matthewlouisbrockman 44fb38d
add note about the bot token
matthewlouisbrockman b00dd71
missing await on openclaw js
matthewlouisbrockman 6940f58
dangerouslyDisableDeviceAuth insturctions
matthewlouisbrockman cce66f8
Merge branch 'main' into openclaw-instructions
matthewlouisbrockman 1e03a72
change from local testing to demo
matthewlouisbrockman 5b206e8
clean up wording on dangerouslyDisableDeviceAuth
matthewlouisbrockman e3f9e4c
move insecure flags instructions to bottom
matthewlouisbrockman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,277 @@ | ||
| --- | ||
| title: "Deploy OpenClaw" | ||
| description: "Start the OpenClaw gateway in an E2B sandbox and connect your browser." | ||
| icon: "globe" | ||
| --- | ||
|
|
||
| ## Quick start | ||
|
|
||
| This launches your OpenClaw [gateway](https://docs.openclaw.ai/gateway) site (web UI for chatting with agents). | ||
|
|
||
| <CodeGroup> | ||
| ```typescript JavaScript & TypeScript | ||
| import { Sandbox } from 'e2b' | ||
|
|
||
| const TOKEN = process.env.OPENCLAW_APP_TOKEN || 'my-gateway-token' | ||
| const PORT = 18789 | ||
|
|
||
| // 1. Create sandbox | ||
| const sandbox = await Sandbox.create('openclaw', { | ||
| envs: { OPENAI_API_KEY: process.env.OPENAI_API_KEY }, | ||
| timeoutMs: 3600_000, | ||
| }) | ||
|
|
||
| // 2. Set the default model | ||
| await sandbox.commands.run('openclaw config set agents.defaults.model.primary openai/gpt-5.2') | ||
|
|
||
| // 3. Set insecure control UI flags and start the gateway with token auth | ||
| await sandbox.commands.run( | ||
| `bash -lc 'openclaw config set gateway.controlUi.allowInsecureAuth true && ` + | ||
| `openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true && ` + | ||
| `openclaw gateway --allow-unconfigured --bind lan --auth token --token ${TOKEN} --port ${PORT}'`, | ||
| { background: true } | ||
| ) | ||
|
|
||
| // 4. Wait for the gateway to start listening | ||
| for (let i = 0; i < 45; i++) { | ||
| const probe = await sandbox.commands.run( | ||
| `bash -lc 'ss -ltn | grep -q ":${PORT} " && echo ready || echo waiting'` | ||
| ) | ||
| if (probe.stdout.trim() === 'ready') break | ||
| await new Promise((r) => setTimeout(r, 1000)) | ||
| } | ||
|
|
||
| const url = `https://${sandbox.getHost(PORT)}/?token=${TOKEN}` | ||
| console.log(`Gateway: ${url}`) | ||
| ``` | ||
| ```python Python | ||
| import os, time | ||
| from e2b import Sandbox | ||
|
|
||
| TOKEN = os.environ.get("OPENCLAW_APP_TOKEN", "my-gateway-token") | ||
| PORT = 18789 | ||
|
|
||
| # 1. Create sandbox | ||
| sandbox = Sandbox.create("openclaw", envs={ | ||
| "OPENAI_API_KEY": os.environ["OPENAI_API_KEY"], | ||
| }, timeout=3600) | ||
|
|
||
| # 2. Set the default model | ||
| sandbox.commands.run("openclaw config set agents.defaults.model.primary openai/gpt-5.2") | ||
|
|
||
| # 3. Set insecure control UI flags and start the gateway with token auth | ||
| sandbox.commands.run( | ||
| f"bash -lc 'openclaw config set gateway.controlUi.allowInsecureAuth true && " | ||
| f"openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true && " | ||
| f"openclaw gateway --allow-unconfigured --bind lan --auth token --token {TOKEN} --port {PORT}'", | ||
| background=True, | ||
| ) | ||
|
|
||
| # 4. Wait for the gateway to start listening | ||
| for _ in range(45): | ||
| probe = sandbox.commands.run( | ||
| f'bash -lc \'ss -ltn | grep -q ":{PORT} " && echo ready || echo waiting\'' | ||
| ) | ||
| if probe.stdout.strip() == "ready": | ||
| break | ||
| time.sleep(1) | ||
|
|
||
| url = f"https://{sandbox.get_host(PORT)}/?token={TOKEN}" | ||
| print(f"Gateway: {url}") | ||
| ``` | ||
| </CodeGroup> | ||
|
|
||
| Visit the printed `Gateway` URL in your browser. | ||
|
|
||
| If you run in secure mode (set `gateway.controlUi.dangerouslyDisableDeviceAuth false`), run this after opening the URL to poll pending pairing requests and approve the first one. | ||
|
|
||
| <CodeGroup> | ||
| ```typescript JavaScript & TypeScript | ||
| // 5. Poll for the browser's pending device request and approve it | ||
| for (let i = 0; i < 30; i++) { | ||
| try { | ||
| const res = await sandbox.commands.run( | ||
| `openclaw devices list --json --url ws://127.0.0.1:${PORT} --token ${TOKEN}` | ||
| ) | ||
| const data = JSON.parse(res.stdout) | ||
| if (data.pending?.length) { | ||
| const rid = data.pending[0].requestId | ||
| await sandbox.commands.run( | ||
| `openclaw devices approve ${rid} --token ${TOKEN} --url ws://127.0.0.1:${PORT}` | ||
| ) | ||
| console.log(`Device approved: ${rid}`) | ||
| break | ||
| } | ||
| } catch {} | ||
| await new Promise((r) => setTimeout(r, 2000)) | ||
| } | ||
cursor[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ``` | ||
| ```python Python | ||
| import json | ||
|
|
||
| # 5. Poll for the browser's pending device request and approve it | ||
| for _ in range(30): | ||
| try: | ||
| res = sandbox.commands.run( | ||
| f"openclaw devices list --json --url ws://127.0.0.1:{PORT} --token {TOKEN}" | ||
| ) | ||
| data = json.loads(res.stdout) | ||
| if data.get("pending"): | ||
| rid = data["pending"][0]["requestId"] | ||
| sandbox.commands.run( | ||
| f"openclaw devices approve {rid} --token {TOKEN} --url ws://127.0.0.1:{PORT}" | ||
| ) | ||
| print(f"Device approved: {rid}") | ||
| break | ||
| except Exception: | ||
| pass | ||
| time.sleep(2) | ||
matthewlouisbrockman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ``` | ||
| </CodeGroup> | ||
|
|
||
| Once approved, the browser connects and the gateway UI loads. | ||
|
|
||
| ## How it works | ||
|
|
||
| | Step | What happens | | ||
| |------|-------------| | ||
| | `--bind lan` | Gateway listens on `0.0.0.0` so E2B can proxy it | | ||
| | `--auth token` | Requires `?token=` on the URL for HTTP and WebSocket auth | | ||
| | Browser opens URL | Gateway serves the UI, browser opens a WebSocket | | ||
| | `code=1008 pairing required` | Gateway closes the WebSocket until the device is approved (secure mode only) | | ||
| | `devices approve` | Approves the browser's device fingerprint (secure mode only) | | ||
| | Browser reconnects | WebSocket connects successfully, UI is live | | ||
|
|
||
| ## Gateway flags reference | ||
|
|
||
| | Flag | Purpose | | ||
| |------|---------| | ||
| | `--allow-unconfigured` | Start without a full config file | | ||
| | `--bind lan` | Bind to `0.0.0.0` (required for E2B port proxying) | | ||
| | `--auth token` | Enable token-based authentication | | ||
| | `--token <value>` | The auth token (passed as `?token=` in the URL) | | ||
| | `--port <number>` | Gateway listen port (default: `18789`) | | ||
|
|
||
| ## How to restart the gateway | ||
|
|
||
| Use this when the gateway is already running and you want a clean restart (for example, after changing model or env settings). | ||
|
|
||
| <Info> | ||
| We can't use the `openclaw gateway restart` command here. Some SDK environments cannot target a specific Unix user in `commands.run`. The commands below use the default command user context. | ||
| </Info> | ||
|
|
||
| <CodeGroup> | ||
| ```typescript JavaScript & TypeScript | ||
| const TOKEN = process.env.OPENCLAW_APP_TOKEN || 'my-gateway-token' | ||
| const PORT = 18789 | ||
|
|
||
| // 1) Kill existing gateway processes if present | ||
| await sandbox.commands.run( | ||
| `bash -lc 'for p in "[o]penclaw gateway" "[o]penclaw-gateway"; do for pid in $(pgrep -f "$p" || true); do kill "$pid" >/dev/null 2>&1 || true; done; done'` | ||
| ) | ||
| await new Promise((r) => setTimeout(r, 1000)) | ||
|
|
||
| // 2) Start gateway again | ||
| await sandbox.commands.run( | ||
| `openclaw gateway --allow-unconfigured --bind lan --auth token --token ${TOKEN} --port ${PORT}`, | ||
| { background: true } | ||
| ) | ||
|
|
||
| // 3) Wait for listening socket | ||
| for (let i = 0; i < 45; i++) { | ||
| const probe = await sandbox.commands.run( | ||
| `bash -lc 'ss -ltn | grep -q ":${PORT} " && echo ready || echo waiting'` | ||
| ) | ||
| if (probe.stdout.trim() === 'ready') break | ||
| await new Promise((r) => setTimeout(r, 1000)) | ||
| } | ||
| ``` | ||
| ```python Python | ||
| import os, time | ||
|
|
||
| TOKEN = os.environ.get("OPENCLAW_APP_TOKEN", "my-gateway-token") | ||
| PORT = 18789 | ||
|
|
||
| # 1) Kill existing gateway processes if present | ||
| sandbox.commands.run( | ||
| """bash -lc 'for p in "[o]penclaw gateway" "[o]penclaw-gateway"; do | ||
| for pid in $(pgrep -f "$p" || true); do | ||
| kill "$pid" >/dev/null 2>&1 || true | ||
| done | ||
| done'""" | ||
| ) | ||
| time.sleep(1) | ||
|
|
||
| # 2) Start gateway again | ||
| sandbox.commands.run( | ||
| f"openclaw gateway --allow-unconfigured --bind lan --auth token --token {TOKEN} --port {PORT}", | ||
| background=True, | ||
| ) | ||
|
|
||
| # 3) Wait for listening socket | ||
| for _ in range(45): | ||
| probe = sandbox.commands.run( | ||
| f'bash -lc \'ss -ltn | grep -q ":{PORT} " && echo ready || echo waiting\'' | ||
| ) | ||
| if probe.stdout.strip() == "ready": | ||
| break | ||
| time.sleep(1) | ||
| ``` | ||
| </CodeGroup> | ||
|
|
||
| ## Turn insecure flags off (recommended after testing) | ||
|
|
||
| Use this to restore secure device authentication after initial testing. | ||
|
|
||
| <CodeGroup> | ||
| ```typescript JavaScript & TypeScript | ||
| const TOKEN = process.env.OPENCLAW_APP_TOKEN || 'my-gateway-token' | ||
| const PORT = 18789 | ||
|
|
||
| await sandbox.commands.run( | ||
| `bash -lc 'openclaw config set gateway.controlUi.allowInsecureAuth false && ` + | ||
| `openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth false'` | ||
| ) | ||
|
|
||
| await sandbox.commands.run( | ||
| `bash -lc 'for p in "[o]penclaw gateway" "[o]penclaw-gateway"; do for pid in $(pgrep -f "$p" || true); do kill "$pid" >/dev/null 2>&1 || true; done; done'` | ||
| ) | ||
|
|
||
| await sandbox.commands.run( | ||
| `openclaw gateway --allow-unconfigured --bind lan --auth token --token ${TOKEN} --port ${PORT}`, | ||
| { background: true } | ||
| ) | ||
| ``` | ||
| ```python Python | ||
| import os | ||
|
|
||
| TOKEN = os.environ.get("OPENCLAW_APP_TOKEN", "my-gateway-token") | ||
| PORT = 18789 | ||
|
|
||
| sandbox.commands.run( | ||
| "bash -lc 'openclaw config set gateway.controlUi.allowInsecureAuth false && " | ||
| "openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth false'" | ||
| ) | ||
|
|
||
| sandbox.commands.run( | ||
| """bash -lc 'for p in "[o]penclaw gateway" "[o]penclaw-gateway"; do | ||
| for pid in $(pgrep -f "$p" || true); do | ||
| kill "$pid" >/dev/null 2>&1 || true | ||
| done | ||
| done'""" | ||
| ) | ||
|
|
||
| sandbox.commands.run( | ||
| f"openclaw gateway --allow-unconfigured --bind lan --auth token --token {TOKEN} --port {PORT}", | ||
| background=True, | ||
| ) | ||
| ``` | ||
| </CodeGroup> | ||
|
|
||
| ## Related | ||
|
|
||
| <CardGroup cols={1}> | ||
| <Card title="OpenClaw Telegram" icon="message-circle" href="/docs/agents/openclaw/openclaw-telegram"> | ||
| Connect OpenClaw to Telegram and approve pairing | ||
| </Card> | ||
| </CardGroup> | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.