mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 04:40:43 +00:00
docs: consolidate moved docs pages
Consolidate moved docs pages, add redirects, and update glossary labels.
This commit is contained in:
committed by
GitHub
parent
c37871e77b
commit
b31774749c
@@ -215,6 +215,50 @@
|
||||
"source": "Capability Cookbook",
|
||||
"target": "能力扩展手册"
|
||||
},
|
||||
{
|
||||
"source": "WhatsApp group messages",
|
||||
"target": "WhatsApp 群组消息"
|
||||
},
|
||||
{
|
||||
"source": "Oracle Cloud",
|
||||
"target": "Oracle Cloud"
|
||||
},
|
||||
{
|
||||
"source": "Install overview",
|
||||
"target": "安装概览"
|
||||
},
|
||||
{
|
||||
"source": "VPS hosting",
|
||||
"target": "VPS 托管"
|
||||
},
|
||||
{
|
||||
"source": "Linux server",
|
||||
"target": "Linux 服务器"
|
||||
},
|
||||
{
|
||||
"source": "Platforms",
|
||||
"target": "平台"
|
||||
},
|
||||
{
|
||||
"source": "Adding capabilities (redirect)",
|
||||
"target": "添加能力(重定向)"
|
||||
},
|
||||
{
|
||||
"source": "Adding capabilities (contributor guide)",
|
||||
"target": "添加能力(贡献者指南)"
|
||||
},
|
||||
{
|
||||
"source": "Plugin internals",
|
||||
"target": "插件内部机制"
|
||||
},
|
||||
{
|
||||
"source": "SDK overview",
|
||||
"target": "SDK 概览"
|
||||
},
|
||||
{
|
||||
"source": "Creating skills",
|
||||
"target": "创建技能"
|
||||
},
|
||||
{
|
||||
"source": "Setup Wizard Reference",
|
||||
"target": "设置向导参考"
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
---
|
||||
summary: "Behavior and config for WhatsApp group message handling (mentionPatterns are shared across surfaces)"
|
||||
summary: "WhatsApp group message handling — activation, allowlists, sessions, and context injection"
|
||||
read_when:
|
||||
- Changing group message rules or mentions
|
||||
title: "Group messages"
|
||||
- Configuring WhatsApp groups specifically
|
||||
- Changing WhatsApp activation modes (`mention` vs `always`)
|
||||
- Tuning WhatsApp group session keys or pending-message context
|
||||
title: "WhatsApp group messages"
|
||||
sidebarTitle: "WhatsApp groups"
|
||||
---
|
||||
|
||||
Goal: let Clawd sit in WhatsApp groups, wake up only when pinged, and keep that thread separate from the personal DM session.
|
||||
For the cross-channel groups model (Discord, iMessage, Matrix, Microsoft Teams, Signal, Slack, Telegram, WhatsApp, Zalo), see [Groups](/channels/groups). This page covers the WhatsApp-specific behavior on top of that model: activation, group allowlists, per-group session keys, and pending-message context injection.
|
||||
|
||||
Goal: let OpenClaw sit in WhatsApp groups, wake up only when pinged, and keep that thread separate from the personal DM session.
|
||||
|
||||
<Note>
|
||||
`agents.list[].groupChat.mentionPatterns` is also used by Telegram, Discord, Slack, and iMessage. This doc focuses on WhatsApp-specific behavior. For multi-agent setups, set `agents.list[].groupChat.mentionPatterns` per agent, or use `messages.groupChat.mentionPatterns` as a global fallback.
|
||||
`agents.list[].groupChat.mentionPatterns` is also used by Telegram, Discord, Slack, and iMessage. For multi-agent setups, set it per agent, or use `messages.groupChat.mentionPatterns` as a global fallback.
|
||||
</Note>
|
||||
|
||||
## Current implementation (2025-12-03)
|
||||
## Behavior
|
||||
|
||||
- Activation modes: `mention` (default) or `always`. `mention` requires a ping (real WhatsApp @-mentions via `mentionedJids`, safe regex patterns, or the bot’s E.164 anywhere in the text). `always` wakes the agent on every message but it should reply only when it can add meaningful value; otherwise it returns the exact silent token `NO_REPLY` / `no_reply`. Defaults can be set in config (`channels.whatsapp.groups`) and overridden per group via `/activation`. When `channels.whatsapp.groups` is set, it also acts as a group allowlist (include `"*"` to allow all).
|
||||
- Group policy: `channels.whatsapp.groupPolicy` controls whether group messages are accepted (`open|disabled|allowlist`). `allowlist` uses `channels.whatsapp.groupAllowFrom` (fallback: explicit `channels.whatsapp.allowFrom`). Default is `allowlist` (blocked until you add senders).
|
||||
|
||||
@@ -63,7 +63,7 @@ tests and embedded app runtimes.
|
||||
import { OpenClaw } from "@openclaw/sdk";
|
||||
|
||||
const oc = new OpenClaw({
|
||||
url: "ws://127.0.0.1:14565",
|
||||
url: "ws://127.0.0.1:18789",
|
||||
token: process.env.OPENCLAW_GATEWAY_TOKEN,
|
||||
requestTimeoutMs: 30_000,
|
||||
});
|
||||
|
||||
@@ -47,7 +47,7 @@ The prompt is intentionally compact and uses fixed sections:
|
||||
- **Documentation**: local path to OpenClaw docs (repo or npm package) and when to read them.
|
||||
- **Workspace Files (injected)**: indicates bootstrap files are included below.
|
||||
- **Sandbox** (when enabled): indicates sandboxed runtime, sandbox paths, and whether elevated exec is available.
|
||||
- **Current Date & Time**: user-local time, timezone, and time format.
|
||||
- **Current Date & Time**: time zone only (cache-stable; the live clock comes from `session_status`).
|
||||
- **Reply Tags**: optional reply tag syntax for supported providers.
|
||||
- **Heartbeats**: heartbeat prompt and ack behavior, when heartbeats are enabled for the default agent.
|
||||
- **Runtime**: host, OS, node, model, repo root (when detected), thinking level (one line).
|
||||
|
||||
@@ -1,95 +1,47 @@
|
||||
---
|
||||
summary: "Timezone handling for agents, envelopes, and prompts"
|
||||
summary: "Where timezones show up in OpenClaw — envelopes, tool payloads, system prompt"
|
||||
read_when:
|
||||
- You need to understand how timestamps are normalized for the model
|
||||
- Configuring the user timezone for system prompts
|
||||
- You want a quick mental model for timezone handling
|
||||
- You are deciding where to set or override a timezone
|
||||
title: "Timezones"
|
||||
---
|
||||
|
||||
OpenClaw standardizes timestamps so the model sees a **single reference time**.
|
||||
OpenClaw standardizes timestamps so the model sees a **single reference time** instead of a mix of provider-local clocks. There are three surfaces where timezones show up, each with its own purpose:
|
||||
|
||||
## Message envelopes (local by default)
|
||||
## Three timezone surfaces
|
||||
|
||||
Inbound messages are wrapped in an envelope like:
|
||||
| Surface | What it shows | Default | Configured via |
|
||||
| ----------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------- | ------------------------------------------------------- |
|
||||
| Message envelopes | Wraps inbound channel messages: `[Signal +1555 2026-01-18 00:19 PST] hello` | Host-local | `agents.defaults.envelopeTimezone` |
|
||||
| Tool payloads | Channel `readMessages`-style tools return raw provider time + normalized `timestampMs` / `timestampUtc` | UTC fields always present | Not configurable — preserves provider-native timestamps |
|
||||
| System prompt | A small `Current Date & Time` block with the **time zone only** (no clock value, for cache stability) | Host timezone if `userTimezone` unset | `agents.defaults.userTimezone` |
|
||||
|
||||
```
|
||||
[Provider ... 2026-01-05 16:26 PST] message text
|
||||
```
|
||||
The system prompt deliberately omits the live clock to keep prompt caching stable across turns. When the agent needs the current time, it calls `session_status`.
|
||||
|
||||
The timestamp in the envelope is **host-local by default**, with minutes precision.
|
||||
|
||||
You can override this with:
|
||||
## Setting the user timezone
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
envelopeTimezone: "local", // "utc" | "local" | "user" | IANA timezone
|
||||
envelopeTimestamp: "on", // "on" | "off"
|
||||
envelopeElapsed: "on", // "on" | "off"
|
||||
userTimezone: "America/Chicago",
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
- `envelopeTimezone: "utc"` uses UTC.
|
||||
- `envelopeTimezone: "user"` uses `agents.defaults.userTimezone` (falls back to host timezone).
|
||||
- Use an explicit IANA timezone (e.g., `"Europe/Vienna"`) for a fixed offset.
|
||||
- `envelopeTimestamp: "off"` removes absolute timestamps from envelope headers.
|
||||
- `envelopeElapsed: "off"` removes elapsed time suffixes (the `+2m` style).
|
||||
If `userTimezone` is unset, OpenClaw resolves the host timezone at runtime (no config write). `agents.defaults.timeFormat` (`auto` | `12` | `24`) controls 12h/24h rendering in envelopes and downstream surfaces, not in the system prompt section.
|
||||
|
||||
### Examples
|
||||
## When to override
|
||||
|
||||
**Local (default):**
|
||||
- **Use UTC envelopes** (`envelopeTimezone: "utc"`) when you want stable timestamps across hosts in different regions, or when you want UTC-aligned logs to match diagnostics output.
|
||||
- **Use a fixed IANA zone** (e.g. `"Europe/Vienna"`) when the gateway host is in one zone but the user is in another and you want envelopes to read in the user's zone regardless of host migration.
|
||||
- **Set `envelopeTimestamp: "off"`** for low-token envelopes when timestamp context is not useful for the conversation.
|
||||
|
||||
```
|
||||
[Signal Alice +1555 2026-01-18 00:19 PST] hello
|
||||
```
|
||||
|
||||
**Fixed timezone:**
|
||||
|
||||
```
|
||||
[Signal Alice +1555 2026-01-18 06:19 GMT+1] hello
|
||||
```
|
||||
|
||||
**Elapsed time:**
|
||||
|
||||
```
|
||||
[Signal Alice +1555 +2m 2026-01-18T05:19Z] follow-up
|
||||
```
|
||||
|
||||
## Tool payloads (raw provider data + normalized fields)
|
||||
|
||||
Tool calls (`channels.discord.readMessages`, `channels.slack.readMessages`, etc.) return **raw provider timestamps**.
|
||||
We also attach normalized fields for consistency:
|
||||
|
||||
- `timestampMs` (UTC epoch milliseconds)
|
||||
- `timestampUtc` (ISO 8601 UTC string)
|
||||
|
||||
Raw provider fields are preserved.
|
||||
|
||||
## User timezone for the system prompt
|
||||
|
||||
Set `agents.defaults.userTimezone` to tell the model the user's local time zone. If it is
|
||||
unset, OpenClaw resolves the **host timezone at runtime** (no config write).
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: { defaults: { userTimezone: "America/Chicago" } },
|
||||
}
|
||||
```
|
||||
|
||||
The system prompt includes:
|
||||
|
||||
- `Current Date & Time` section with local time and timezone
|
||||
- `Time format: 12-hour` or `24-hour`
|
||||
|
||||
You can control the prompt format with `agents.defaults.timeFormat` (`auto` | `12` | `24`).
|
||||
|
||||
See [Date & Time](/date-time) for the full behavior and examples.
|
||||
For the full behavior reference, examples per provider, and elapsed-time formatting, see [Date & Time](/date-time).
|
||||
|
||||
## Related
|
||||
|
||||
- [Heartbeat](/gateway/heartbeat) — active hours use timezone for scheduling
|
||||
- [Cron Jobs](/automation/cron-jobs) — cron expressions use timezone for scheduling
|
||||
- [Date & Time](/date-time) — full date/time behavior and examples
|
||||
- [Date & Time](/date-time) — full envelope/tool/prompt behavior and examples.
|
||||
- [Heartbeat](/gateway/heartbeat) — active hours use timezone for scheduling.
|
||||
- [Cron Jobs](/automation/cron-jobs) — cron expressions use timezone for scheduling.
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
},
|
||||
{
|
||||
"source": "/tools/capability-cookbook",
|
||||
"destination": "/plugins/architecture"
|
||||
"destination": "/plugins/adding-capabilities"
|
||||
},
|
||||
{
|
||||
"source": "/brave-search",
|
||||
@@ -1206,6 +1206,7 @@
|
||||
"plugins/hooks",
|
||||
"plugins/sdk-channel-plugins",
|
||||
"plugins/sdk-provider-plugins",
|
||||
"plugins/adding-capabilities",
|
||||
"plugins/compatibility",
|
||||
"plugins/sdk-migration"
|
||||
]
|
||||
@@ -1519,13 +1520,7 @@
|
||||
},
|
||||
{
|
||||
"group": "Networking and discovery",
|
||||
"pages": [
|
||||
"network",
|
||||
"gateway/network-model",
|
||||
"gateway/pairing",
|
||||
"gateway/discovery",
|
||||
"gateway/bonjour"
|
||||
]
|
||||
"pages": ["network", "gateway/pairing", "gateway/discovery", "gateway/bonjour"]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -37,11 +37,11 @@ Local onboarding defaults new local configs to `tools.profile: "coding"` when un
|
||||
| `group:memory` | `memory_search`, `memory_get` |
|
||||
| `group:web` | `web_search`, `x_search`, `web_fetch` |
|
||||
| `group:ui` | `browser`, `canvas` |
|
||||
| `group:automation` | `cron`, `gateway` |
|
||||
| `group:automation` | `heartbeat_respond`, `cron`, `gateway` |
|
||||
| `group:messaging` | `message` |
|
||||
| `group:nodes` | `nodes` |
|
||||
| `group:agents` | `agents_list` |
|
||||
| `group:media` | `image`, `image_generate`, `video_generate`, `tts` |
|
||||
| `group:agents` | `agents_list`, `update_plan` |
|
||||
| `group:media` | `image`, `image_generate`, `music_generate`, `video_generate`, `tts` |
|
||||
| `group:openclaw` | All built-in tools (excludes provider plugins) |
|
||||
|
||||
### `tools.allow` / `tools.deny`
|
||||
|
||||
@@ -1,26 +1,12 @@
|
||||
---
|
||||
summary: "How the Gateway, nodes, and canvas host connect."
|
||||
summary: "Redirect to /network#core-model"
|
||||
read_when:
|
||||
- You want a concise view of the Gateway networking model
|
||||
title: "Network model"
|
||||
redirect: /network#core-model
|
||||
---
|
||||
|
||||
> This content has been merged into [Network](/network#core-model). See that page for the current guide.
|
||||
|
||||
Most operations flow through the Gateway (`openclaw gateway`), a single long-running
|
||||
process that owns channel connections and the WebSocket control plane.
|
||||
|
||||
## Core rules
|
||||
|
||||
- One Gateway per host is recommended. It is the only process allowed to own the WhatsApp Web session. For rescue bots or strict isolation, run multiple gateways with isolated profiles and ports. See [Multiple gateways](/gateway/multiple-gateways).
|
||||
- Loopback first: the Gateway WS defaults to `ws://127.0.0.1:18789`. The wizard creates shared-secret auth by default and usually generates a token, even for loopback. For non-loopback access, use a valid gateway auth path: shared-secret token/password auth, or a correctly configured non-loopback `trusted-proxy` deployment. Tailnet/mobile setups usually work best through Tailscale Serve or another `wss://` endpoint instead of raw tailnet `ws://`.
|
||||
- Nodes connect to the Gateway WS over LAN, tailnet, or SSH as needed. The
|
||||
legacy TCP bridge has been removed.
|
||||
- Canvas host is served by the Gateway HTTP server on the **same port** as the Gateway (default `18789`):
|
||||
- `/__openclaw__/canvas/`
|
||||
- `/__openclaw__/a2ui/`
|
||||
When `gateway.auth` is configured and the Gateway binds beyond loopback, these routes are protected by Gateway auth. Node clients use node-scoped capability URLs tied to their active WS session. See [Gateway configuration](/gateway/configuration) (`canvasHost`, `gateway`).
|
||||
- Remote use is typically SSH tunnel or tailnet VPN. See [Remote access](/gateway/remote) and [Discovery](/gateway/discovery).
|
||||
This content has been merged into [Network — Core model](/network#core-model).
|
||||
|
||||
## Related
|
||||
|
||||
|
||||
@@ -92,11 +92,11 @@ Available groups:
|
||||
- `group:memory`: `memory_search`, `memory_get`
|
||||
- `group:web`: `web_search`, `x_search`, `web_fetch`
|
||||
- `group:ui`: `browser`, `canvas`
|
||||
- `group:automation`: `cron`, `gateway`
|
||||
- `group:automation`: `heartbeat_respond`, `cron`, `gateway`
|
||||
- `group:messaging`: `message`
|
||||
- `group:nodes`: `nodes`
|
||||
- `group:agents`: `agents_list`
|
||||
- `group:media`: `image`, `image_generate`, `video_generate`, `tts`
|
||||
- `group:agents`: `agents_list`, `update_plan`
|
||||
- `group:media`: `image`, `image_generate`, `music_generate`, `video_generate`, `tts`
|
||||
- `group:openclaw`: all built-in OpenClaw tools (excludes provider plugins)
|
||||
|
||||
## Elevated: exec-only "run on host"
|
||||
|
||||
@@ -6,7 +6,12 @@ read_when:
|
||||
title: "DigitalOcean"
|
||||
---
|
||||
|
||||
Run a persistent OpenClaw Gateway on a DigitalOcean Droplet.
|
||||
Run a persistent OpenClaw Gateway on a DigitalOcean Droplet (~$6/month for the 1 GB Basic plan).
|
||||
|
||||
DigitalOcean is the simplest paid VPS path. If you prefer cheaper or free options:
|
||||
|
||||
- [Hetzner](/install/hetzner) — €3.79/mo, more cores/RAM per dollar.
|
||||
- [Oracle Cloud](/install/oracle) — Always Free ARM (up to 4 OCPU, 24 GB RAM), but signup can be finicky and ARM-only.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@@ -100,6 +105,8 @@ Run a persistent OpenClaw Gateway on a DigitalOcean Droplet.
|
||||
|
||||
Then open `https://<magicdns>/` from any device on your tailnet.
|
||||
|
||||
Tailscale Serve authenticates Control UI and WebSocket traffic via tailnet identity headers, which assumes the gateway host itself is trusted. HTTP API endpoints follow the gateway's normal auth mode (token/password) regardless. To require explicit shared-secret credentials over Serve, set `gateway.auth.allowTailscale: false` and use `gateway.auth.mode: "token"` or `"password"`.
|
||||
|
||||
**Option C: Tailnet bind (no Serve)**
|
||||
|
||||
```bash
|
||||
@@ -112,6 +119,30 @@ Run a persistent OpenClaw Gateway on a DigitalOcean Droplet.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Persistence and backups
|
||||
|
||||
OpenClaw state lives under:
|
||||
|
||||
- `~/.openclaw/` — `openclaw.json`, per-agent `auth-profiles.json`, channel/provider state, and session data.
|
||||
- `~/.openclaw/workspace/` — the agent workspace (SOUL.md, memory, artifacts).
|
||||
|
||||
These survive Droplet reboots. To take a portable snapshot:
|
||||
|
||||
```bash
|
||||
openclaw backup create
|
||||
```
|
||||
|
||||
DigitalOcean snapshots back the whole Droplet up; `openclaw backup create` is portable across hosts.
|
||||
|
||||
## 1 GB RAM tips
|
||||
|
||||
The $6 Droplet only has 1 GB RAM. To keep things smooth:
|
||||
|
||||
- Make sure the swap step above is in `/etc/fstab` so it survives reboots.
|
||||
- Prefer API-based models (Claude, GPT) over local ones — local LLM inference does not fit in 1 GB.
|
||||
- Set `agents.defaults.model.primary` to a smaller model if you hit OOMs on large prompts.
|
||||
- Monitor with `free -h` and `htop`.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Gateway will not start** -- Run `openclaw doctor --non-interactive` and check logs with `journalctl --user -u openclaw-gateway.service -n 50`.
|
||||
|
||||
@@ -129,6 +129,62 @@ Run a persistent OpenClaw Gateway on Oracle Cloud's **Always Free** ARM tier (up
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Verify the security posture
|
||||
|
||||
With the VCN locked down (only UDP 41641 open) and the Gateway bound to loopback, public traffic is blocked at the network edge and admin access is tailnet-only. That removes the need for several traditional VPS hardening steps:
|
||||
|
||||
| Traditional step | Needed? | Why |
|
||||
| ------------------ | ----------- | ------------------------------------------------------------------------- |
|
||||
| UFW firewall | No | The VCN blocks traffic before it reaches the instance. |
|
||||
| fail2ban | No | Port 22 is blocked at the VCN; no brute-force surface. |
|
||||
| sshd hardening | No | Tailscale SSH does not use sshd. |
|
||||
| Disable root login | No | Tailscale authenticates by tailnet identity, not system users. |
|
||||
| SSH key-only auth | No | Same — tailnet identity replaces system SSH keys. |
|
||||
| IPv6 hardening | Usually not | Depends on VCN/subnet settings; verify what is actually assigned/exposed. |
|
||||
|
||||
Still recommended:
|
||||
|
||||
- `chmod 700 ~/.openclaw` to restrict credential file permissions.
|
||||
- `openclaw security audit` for an OpenClaw-specific posture check.
|
||||
- Regular `sudo apt update && sudo apt upgrade` for OS patches.
|
||||
- Review devices in the [Tailscale admin console](https://login.tailscale.com/admin) periodically.
|
||||
|
||||
Quick verification commands:
|
||||
|
||||
```bash
|
||||
# Confirm no public ports are listening
|
||||
sudo ss -tlnp | grep -v '127.0.0.1\|::1'
|
||||
|
||||
# Verify Tailscale SSH is active
|
||||
tailscale status | grep -q 'offers: ssh' && echo "Tailscale SSH active"
|
||||
|
||||
# Optional: disable sshd entirely once Tailscale SSH is confirmed working
|
||||
sudo systemctl disable --now ssh
|
||||
```
|
||||
|
||||
## ARM notes
|
||||
|
||||
The Always Free tier is ARM (`aarch64`). Most OpenClaw features work fine; a small number of native binaries need ARM builds:
|
||||
|
||||
- Node.js, Telegram, WhatsApp (Baileys): pure JavaScript, no issues.
|
||||
- Most npm packages with native code: pre-built `linux-arm64` artifacts available.
|
||||
- Optional CLI helpers (e.g. Go/Rust binaries shipped by skills): check for an `aarch64` / `linux-arm64` release before installing.
|
||||
|
||||
Verify the architecture with `uname -m` (should print `aarch64`). For binaries without an ARM build, install from source or skip them.
|
||||
|
||||
## Persistence and backups
|
||||
|
||||
OpenClaw state lives under:
|
||||
|
||||
- `~/.openclaw/` — `openclaw.json`, per-agent `auth-profiles.json`, channel/provider state, and session data.
|
||||
- `~/.openclaw/workspace/` — the agent workspace (SOUL.md, memory, artifacts).
|
||||
|
||||
These survive reboots. To take a portable snapshot:
|
||||
|
||||
```bash
|
||||
openclaw backup create
|
||||
```
|
||||
|
||||
## Fallback: SSH tunnel
|
||||
|
||||
If Tailscale Serve is not working, use an SSH tunnel from your local machine:
|
||||
|
||||
@@ -7,7 +7,21 @@ read_when:
|
||||
title: "Raspberry Pi"
|
||||
---
|
||||
|
||||
Run a persistent, always-on OpenClaw Gateway on a Raspberry Pi. Since the Pi is just the gateway (models run in the cloud via API), even a modest Pi handles the workload well.
|
||||
Run a persistent, always-on OpenClaw Gateway on a Raspberry Pi. Since the Pi is just the gateway (models run in the cloud via API), even a modest Pi handles the workload well — typical hardware cost is **$35–80 one-time**, no monthly fees.
|
||||
|
||||
## Hardware compatibility
|
||||
|
||||
| Pi model | RAM | Works? | Notes |
|
||||
| ----------- | ------ | ------ | ----------------------------------- |
|
||||
| Pi 5 | 4/8 GB | Best | Fastest, recommended. |
|
||||
| Pi 4 | 4 GB | Good | Sweet spot for most users. |
|
||||
| Pi 4 | 2 GB | OK | Add swap. |
|
||||
| Pi 4 | 1 GB | Tight | Possible with swap, minimal config. |
|
||||
| Pi 3B+ | 1 GB | Slow | Works but sluggish. |
|
||||
| Pi Zero 2 W | 512 MB | No | Not recommended. |
|
||||
|
||||
**Minimum:** 1 GB RAM, 1 core, 500 MB free disk, 64-bit OS.
|
||||
**Recommended:** 2 GB+ RAM, 16 GB+ SD card (or USB SSD), Ethernet.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@@ -138,6 +152,61 @@ echo 'gpu_mem=16' | sudo tee -a /boot/config.txt
|
||||
sudo systemctl disable bluetooth
|
||||
```
|
||||
|
||||
**systemd drop-in for stable restarts** -- If this Pi is mostly running OpenClaw, add a service drop-in:
|
||||
|
||||
```bash
|
||||
systemctl --user edit openclaw-gateway.service
|
||||
```
|
||||
|
||||
```ini
|
||||
[Service]
|
||||
Environment=OPENCLAW_NO_RESPAWN=1
|
||||
Environment=NODE_COMPILE_CACHE=/var/tmp/openclaw-compile-cache
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
TimeoutStartSec=90
|
||||
```
|
||||
|
||||
Then `systemctl --user daemon-reload && systemctl --user restart openclaw-gateway.service`. On a headless Pi, also enable lingering once so the user service survives logout: `sudo loginctl enable-linger "$(whoami)"`.
|
||||
|
||||
## Recommended model setup
|
||||
|
||||
Since the Pi only runs the gateway, use cloud-hosted API models:
|
||||
|
||||
```json
|
||||
{
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": {
|
||||
"primary": "anthropic/claude-sonnet-4-6",
|
||||
"fallbacks": ["openai/gpt-5.4-mini"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Do not run local LLMs on a Pi — even small models are too slow to be useful. Let Claude or GPT do the model work.
|
||||
|
||||
## ARM binary notes
|
||||
|
||||
Most OpenClaw features work on ARM64 without changes (Node.js, Telegram, WhatsApp/Baileys, Chromium). The binaries that occasionally lack ARM builds are typically optional Go/Rust CLI tools shipped by skills. Verify a missing binary's release page for `linux-arm64` / `aarch64` artifacts before falling back to building from source.
|
||||
|
||||
## Persistence and backups
|
||||
|
||||
OpenClaw state lives under:
|
||||
|
||||
- `~/.openclaw/` — `openclaw.json`, per-agent `auth-profiles.json`, channel/provider state, sessions.
|
||||
- `~/.openclaw/workspace/` — agent workspace (SOUL.md, memory, artifacts).
|
||||
|
||||
These survive reboots. Take a portable snapshot with:
|
||||
|
||||
```bash
|
||||
openclaw backup create
|
||||
```
|
||||
|
||||
If you keep these on an SSD, both performance and longevity improve over the SD card.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Out of memory** -- Verify swap is active with `free -h`. Disable unused services (`sudo systemctl disable cups bluetooth avahi-daemon`). Use API-based models only.
|
||||
|
||||
@@ -70,5 +70,5 @@ Local trust:
|
||||
|
||||
## Related
|
||||
|
||||
- [Gateway network model](/gateway/network-model)
|
||||
- [Gateway network model](/network#core-model)
|
||||
- [Remote access](/gateway/remote)
|
||||
|
||||
@@ -1,186 +1,11 @@
|
||||
---
|
||||
summary: "Perplexity Search API and Sonar/OpenRouter compatibility for web_search"
|
||||
read_when:
|
||||
- You want to use Perplexity Search for web search
|
||||
- You need PERPLEXITY_API_KEY or OPENROUTER_API_KEY setup
|
||||
title: "Perplexity search (legacy path)"
|
||||
summary: "Redirect to /tools/perplexity-search"
|
||||
title: "Perplexity search"
|
||||
redirect: /tools/perplexity-search
|
||||
---
|
||||
|
||||
# Perplexity Search API
|
||||
|
||||
OpenClaw supports Perplexity Search API as a `web_search` provider.
|
||||
It returns structured results with `title`, `url`, and `snippet` fields.
|
||||
|
||||
For compatibility, OpenClaw also supports legacy Perplexity Sonar/OpenRouter setups.
|
||||
If you use `OPENROUTER_API_KEY`, an `sk-or-...` key in `plugins.entries.perplexity.config.webSearch.apiKey`, or set `plugins.entries.perplexity.config.webSearch.baseUrl` / `model`, the provider switches to the chat-completions path and returns AI-synthesized answers with citations instead of structured Search API results.
|
||||
|
||||
## Getting a Perplexity API key
|
||||
|
||||
1. Create a Perplexity account at [perplexity.ai/settings/api](https://www.perplexity.ai/settings/api)
|
||||
2. Generate an API key in the dashboard
|
||||
3. Store the key in config or set `PERPLEXITY_API_KEY` in the Gateway environment.
|
||||
|
||||
## OpenRouter compatibility
|
||||
|
||||
If you were already using OpenRouter for Perplexity Sonar, keep `provider: "perplexity"` and set `OPENROUTER_API_KEY` in the Gateway environment, or store an `sk-or-...` key in `plugins.entries.perplexity.config.webSearch.apiKey`.
|
||||
|
||||
Optional compatibility controls:
|
||||
|
||||
- `plugins.entries.perplexity.config.webSearch.baseUrl`
|
||||
- `plugins.entries.perplexity.config.webSearch.model`
|
||||
|
||||
## Config examples
|
||||
|
||||
### Native Perplexity Search API
|
||||
|
||||
```json5
|
||||
{
|
||||
plugins: {
|
||||
entries: {
|
||||
perplexity: {
|
||||
config: {
|
||||
webSearch: {
|
||||
apiKey: "pplx-...",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
tools: {
|
||||
web: {
|
||||
search: {
|
||||
provider: "perplexity",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### OpenRouter / Sonar compatibility
|
||||
|
||||
```json5
|
||||
{
|
||||
plugins: {
|
||||
entries: {
|
||||
perplexity: {
|
||||
config: {
|
||||
webSearch: {
|
||||
apiKey: "<openrouter-api-key>",
|
||||
baseUrl: "https://openrouter.ai/api/v1",
|
||||
model: "perplexity/sonar-pro",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
tools: {
|
||||
web: {
|
||||
search: {
|
||||
provider: "perplexity",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Where to set the key
|
||||
|
||||
**Via config:** run `openclaw configure --section web`. It stores the key in
|
||||
`~/.openclaw/openclaw.json` under `plugins.entries.perplexity.config.webSearch.apiKey`.
|
||||
That field also accepts SecretRef objects.
|
||||
|
||||
**Via environment:** set `PERPLEXITY_API_KEY` or `OPENROUTER_API_KEY`
|
||||
in the Gateway process environment. For a gateway install, put it in
|
||||
`~/.openclaw/.env` (or your service environment). See [Env vars](/help/faq#env-vars-and-env-loading).
|
||||
|
||||
If `provider: "perplexity"` is configured and the Perplexity key SecretRef is unresolved with no env fallback, startup/reload fails fast.
|
||||
|
||||
## Tool parameters
|
||||
|
||||
These parameters apply to the native Perplexity Search API path.
|
||||
|
||||
| Parameter | Description |
|
||||
| --------------------- | ---------------------------------------------------- |
|
||||
| `query` | Search query (required) |
|
||||
| `count` | Number of results to return (1-10, default: 5) |
|
||||
| `country` | 2-letter ISO country code (e.g., "US", "DE") |
|
||||
| `language` | ISO 639-1 language code (e.g., "en", "de", "fr") |
|
||||
| `freshness` | Time filter: `day` (24h), `week`, `month`, or `year` |
|
||||
| `date_after` | Only results published after this date (YYYY-MM-DD) |
|
||||
| `date_before` | Only results published before this date (YYYY-MM-DD) |
|
||||
| `domain_filter` | Domain allowlist/denylist array (max 20) |
|
||||
| `max_tokens` | Total content budget (default: 25000, max: 1000000) |
|
||||
| `max_tokens_per_page` | Per-page token limit (default: 2048) |
|
||||
|
||||
For the legacy Sonar/OpenRouter compatibility path:
|
||||
|
||||
- `query`, `count`, and `freshness` are accepted
|
||||
- `count` is compatibility-only there; the response is still one synthesized
|
||||
answer with citations rather than an N-result list
|
||||
- Search API-only filters such as `country`, `language`, `date_after`,
|
||||
`date_before`, `domain_filter`, `max_tokens`, and `max_tokens_per_page`
|
||||
return explicit errors
|
||||
|
||||
**Examples:**
|
||||
|
||||
```javascript
|
||||
// Country and language-specific search
|
||||
await web_search({
|
||||
query: "renewable energy",
|
||||
country: "DE",
|
||||
language: "de",
|
||||
});
|
||||
|
||||
// Recent results (past week)
|
||||
await web_search({
|
||||
query: "AI news",
|
||||
freshness: "week",
|
||||
});
|
||||
|
||||
// Date range search
|
||||
await web_search({
|
||||
query: "AI developments",
|
||||
date_after: "2024-01-01",
|
||||
date_before: "2024-06-30",
|
||||
});
|
||||
|
||||
// Domain filtering (allowlist)
|
||||
await web_search({
|
||||
query: "climate research",
|
||||
domain_filter: ["nature.com", "science.org", ".edu"],
|
||||
});
|
||||
|
||||
// Domain filtering (denylist - prefix with -)
|
||||
await web_search({
|
||||
query: "product reviews",
|
||||
domain_filter: ["-reddit.com", "-pinterest.com"],
|
||||
});
|
||||
|
||||
// More content extraction
|
||||
await web_search({
|
||||
query: "detailed AI research",
|
||||
max_tokens: 50000,
|
||||
max_tokens_per_page: 4096,
|
||||
});
|
||||
```
|
||||
|
||||
### Domain filter rules
|
||||
|
||||
- Maximum 20 domains per filter
|
||||
- Cannot mix allowlist and denylist in the same request
|
||||
- Use `-` prefix for denylist entries (e.g., `["-reddit.com"]`)
|
||||
|
||||
## Notes
|
||||
|
||||
- Perplexity Search API returns structured web search results (`title`, `url`, `snippet`)
|
||||
- OpenRouter or explicit `plugins.entries.perplexity.config.webSearch.baseUrl` / `model` switches Perplexity back to Sonar chat completions for compatibility
|
||||
- Sonar/OpenRouter compatibility returns one synthesized answer with citations, not structured result rows
|
||||
- Results are cached for 15 minutes by default (configurable via `cacheTtlMinutes`)
|
||||
|
||||
See [Web tools](/tools/web) for the full web_search configuration.
|
||||
See [Perplexity Search API docs](https://docs.perplexity.ai/docs/search/quickstart) for more details.
|
||||
This page has moved to [Perplexity search](/tools/perplexity-search).
|
||||
|
||||
## Related
|
||||
|
||||
- [Perplexity search](/tools/perplexity-search)
|
||||
- [Web search](/tools/web)
|
||||
- [Web tools](/tools/web)
|
||||
|
||||
@@ -1,266 +1,12 @@
|
||||
---
|
||||
summary: "OpenClaw on DigitalOcean (simple paid VPS option)"
|
||||
read_when:
|
||||
- Setting up OpenClaw on DigitalOcean
|
||||
- Looking for cheap VPS hosting for OpenClaw
|
||||
summary: "Redirect to /install/digitalocean"
|
||||
title: "DigitalOcean (platform)"
|
||||
redirect: /install/digitalocean
|
||||
---
|
||||
|
||||
# OpenClaw on DigitalOcean
|
||||
|
||||
## Goal
|
||||
|
||||
Run a persistent OpenClaw Gateway on DigitalOcean for **$6/month** (or $4/mo with reserved pricing).
|
||||
|
||||
If you want a $0/month option and don’t mind ARM + provider-specific setup, see the [Oracle Cloud guide](/platforms/oracle).
|
||||
|
||||
## Cost comparison (2026)
|
||||
|
||||
| Provider | Plan | Specs | Price/mo | Notes |
|
||||
| ------------ | --------------- | ---------------------- | ----------- | ------------------------------------- |
|
||||
| Oracle Cloud | Always Free ARM | up to 4 OCPU, 24GB RAM | $0 | ARM, limited capacity / signup quirks |
|
||||
| Hetzner | CX22 | 2 vCPU, 4GB RAM | €3.79 (~$4) | Cheapest paid option |
|
||||
| DigitalOcean | Basic | 1 vCPU, 1GB RAM | $6 | Easy UI, good docs |
|
||||
| Vultr | Cloud Compute | 1 vCPU, 1GB RAM | $6 | Many locations |
|
||||
| Linode | Nanode | 1 vCPU, 1GB RAM | $5 | Now part of Akamai |
|
||||
|
||||
**Picking a provider:**
|
||||
|
||||
- DigitalOcean: simplest UX + predictable setup (this guide)
|
||||
- Hetzner: good price/perf (see [Hetzner guide](/install/hetzner))
|
||||
- Oracle Cloud: can be $0/month, but is more finicky and ARM-only (see [Oracle guide](/platforms/oracle))
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- DigitalOcean account ([signup with $200 free credit](https://m.do.co/c/signup))
|
||||
- SSH key pair (or willingness to use password auth)
|
||||
- ~20 minutes
|
||||
|
||||
## 1) Create a Droplet
|
||||
|
||||
<Warning>
|
||||
Use a clean base image (Ubuntu 24.04 LTS). Avoid third-party Marketplace 1-click images unless you have reviewed their startup scripts and firewall defaults.
|
||||
</Warning>
|
||||
|
||||
1. Log into [DigitalOcean](https://cloud.digitalocean.com/)
|
||||
2. Click **Create → Droplets**
|
||||
3. Choose:
|
||||
- **Region:** Closest to you (or your users)
|
||||
- **Image:** Ubuntu 24.04 LTS
|
||||
- **Size:** Basic → Regular → **$6/mo** (1 vCPU, 1GB RAM, 25GB SSD)
|
||||
- **Authentication:** SSH key (recommended) or password
|
||||
4. Click **Create Droplet**
|
||||
5. Note the IP address
|
||||
|
||||
## 2) Connect via SSH
|
||||
|
||||
```bash
|
||||
ssh root@YOUR_DROPLET_IP
|
||||
```
|
||||
|
||||
## 3) Install OpenClaw
|
||||
|
||||
```bash
|
||||
# Update system
|
||||
apt update && apt upgrade -y
|
||||
|
||||
# Install Node.js 24
|
||||
curl -fsSL https://deb.nodesource.com/setup_24.x | bash -
|
||||
apt install -y nodejs
|
||||
|
||||
# Install OpenClaw
|
||||
curl -fsSL https://openclaw.ai/install.sh | bash
|
||||
|
||||
# Verify
|
||||
openclaw --version
|
||||
```
|
||||
|
||||
## 4) Run Onboarding
|
||||
|
||||
```bash
|
||||
openclaw onboard --install-daemon
|
||||
```
|
||||
|
||||
The wizard will walk you through:
|
||||
|
||||
- Model auth (API keys or OAuth)
|
||||
- Channel setup (Telegram, WhatsApp, Discord, etc.)
|
||||
- Gateway token (auto-generated)
|
||||
- Daemon installation (systemd)
|
||||
|
||||
## 5) Verify the Gateway
|
||||
|
||||
```bash
|
||||
# Check status
|
||||
openclaw status
|
||||
|
||||
# Check service
|
||||
systemctl --user status openclaw-gateway.service
|
||||
|
||||
# View logs
|
||||
journalctl --user -u openclaw-gateway.service -f
|
||||
```
|
||||
|
||||
## 6) Access the Dashboard
|
||||
|
||||
The gateway binds to loopback by default. To access the Control UI:
|
||||
|
||||
**Option A: SSH Tunnel (recommended)**
|
||||
|
||||
```bash
|
||||
# From your local machine
|
||||
ssh -L 18789:localhost:18789 root@YOUR_DROPLET_IP
|
||||
|
||||
# Then open: http://localhost:18789
|
||||
```
|
||||
|
||||
**Option B: Tailscale Serve (HTTPS, loopback-only)**
|
||||
|
||||
```bash
|
||||
# On the droplet
|
||||
curl -fsSL https://tailscale.com/install.sh | sh
|
||||
tailscale up
|
||||
|
||||
# Configure Gateway to use Tailscale Serve
|
||||
openclaw config set gateway.tailscale.mode serve
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
Open: `https://<magicdns>/`
|
||||
|
||||
Notes:
|
||||
|
||||
- Serve keeps the Gateway loopback-only and authenticates Control UI/WebSocket traffic via Tailscale identity headers (tokenless auth assumes trusted gateway host; HTTP APIs do not use those Tailscale headers and instead follow the gateway's normal HTTP auth mode).
|
||||
- To require explicit shared-secret credentials instead, set `gateway.auth.allowTailscale: false` and use `gateway.auth.mode: "token"` or `"password"`.
|
||||
|
||||
**Option C: Tailnet bind (no Serve)**
|
||||
|
||||
```bash
|
||||
openclaw config set gateway.bind tailnet
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
Open: `http://<tailscale-ip>:18789` (token required).
|
||||
|
||||
## 7) Connect Your Channels
|
||||
|
||||
### Telegram
|
||||
|
||||
```bash
|
||||
openclaw pairing list telegram
|
||||
openclaw pairing approve telegram <CODE>
|
||||
```
|
||||
|
||||
### WhatsApp
|
||||
|
||||
```bash
|
||||
openclaw channels login whatsapp
|
||||
# Scan QR code
|
||||
```
|
||||
|
||||
See [Channels](/channels) for other providers.
|
||||
|
||||
---
|
||||
|
||||
## Optimizations for 1GB RAM
|
||||
|
||||
The $6 droplet only has 1GB RAM. To keep things running smoothly:
|
||||
|
||||
### Add swap (recommended)
|
||||
|
||||
```bash
|
||||
fallocate -l 2G /swapfile
|
||||
chmod 600 /swapfile
|
||||
mkswap /swapfile
|
||||
swapon /swapfile
|
||||
echo '/swapfile none swap sw 0 0' >> /etc/fstab
|
||||
```
|
||||
|
||||
### Use a lighter model
|
||||
|
||||
If you're hitting OOMs, consider:
|
||||
|
||||
- Using API-based models (Claude, GPT) instead of local models
|
||||
- Setting `agents.defaults.model.primary` to a smaller model
|
||||
|
||||
### Monitor memory
|
||||
|
||||
```bash
|
||||
free -h
|
||||
htop
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Persistence
|
||||
|
||||
All state lives in:
|
||||
|
||||
- `~/.openclaw/` — `openclaw.json`, per-agent `auth-profiles.json`, channel/provider state, and session data
|
||||
- `~/.openclaw/workspace/` — workspace (SOUL.md, memory, etc.)
|
||||
|
||||
These survive reboots. Back them up periodically:
|
||||
|
||||
```bash
|
||||
openclaw backup create
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Oracle Cloud free alternative
|
||||
|
||||
Oracle Cloud offers **Always Free** ARM instances that are significantly more powerful than any paid option here — for $0/month.
|
||||
|
||||
| What you get | Specs |
|
||||
| ----------------- | ---------------------- |
|
||||
| **4 OCPUs** | ARM Ampere A1 |
|
||||
| **24GB RAM** | More than enough |
|
||||
| **200GB storage** | Block volume |
|
||||
| **Forever free** | No credit card charges |
|
||||
|
||||
**Caveats:**
|
||||
|
||||
- Signup can be finicky (retry if it fails)
|
||||
- ARM architecture — most things work, but some binaries need ARM builds
|
||||
|
||||
For the full setup guide, see [Oracle Cloud](/platforms/oracle). For signup tips and troubleshooting the enrollment process, see this [community guide](https://gist.github.com/rssnyder/51e3cfedd730e7dd5f4a816143b25dbd).
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Gateway will not start
|
||||
|
||||
```bash
|
||||
openclaw gateway status
|
||||
openclaw doctor --non-interactive
|
||||
journalctl --user -u openclaw-gateway.service --no-pager -n 50
|
||||
```
|
||||
|
||||
### Port already in use
|
||||
|
||||
```bash
|
||||
lsof -i :18789
|
||||
kill <PID>
|
||||
```
|
||||
|
||||
### Out of memory
|
||||
|
||||
```bash
|
||||
# Check memory
|
||||
free -h
|
||||
|
||||
# Add more swap
|
||||
# Or upgrade to $12/mo droplet (2GB RAM)
|
||||
```
|
||||
|
||||
---
|
||||
This page has moved to [DigitalOcean](/install/digitalocean).
|
||||
|
||||
## Related
|
||||
|
||||
- [Hetzner guide](/install/hetzner) — cheaper, more powerful
|
||||
- [Docker install](/install/docker) — containerized setup
|
||||
- [Tailscale](/gateway/tailscale) — secure remote access
|
||||
- [Configuration](/gateway/configuration) — full config reference
|
||||
- [Install overview](/install)
|
||||
- [VPS hosting](/vps)
|
||||
|
||||
@@ -1,305 +1,12 @@
|
||||
---
|
||||
summary: "OpenClaw on Oracle Cloud (Always Free ARM)"
|
||||
read_when:
|
||||
- Setting up OpenClaw on Oracle Cloud
|
||||
- Looking for low-cost VPS hosting for OpenClaw
|
||||
- Want 24/7 OpenClaw on a small server
|
||||
summary: "Redirect to /install/oracle"
|
||||
title: "Oracle Cloud (platform)"
|
||||
redirect: /install/oracle
|
||||
---
|
||||
|
||||
# OpenClaw on Oracle Cloud (OCI)
|
||||
|
||||
## Goal
|
||||
|
||||
Run a persistent OpenClaw Gateway on Oracle Cloud's **Always Free** ARM tier.
|
||||
|
||||
Oracle’s free tier can be a great fit for OpenClaw (especially if you already have an OCI account), but it comes with tradeoffs:
|
||||
|
||||
- ARM architecture (most things work, but some binaries may be x86-only)
|
||||
- Capacity and signup can be finicky
|
||||
|
||||
## Cost comparison (2026)
|
||||
|
||||
| Provider | Plan | Specs | Price/mo | Notes |
|
||||
| ------------ | --------------- | ---------------------- | -------- | --------------------- |
|
||||
| Oracle Cloud | Always Free ARM | up to 4 OCPU, 24GB RAM | $0 | ARM, limited capacity |
|
||||
| Hetzner | CX22 | 2 vCPU, 4GB RAM | ~ $4 | Cheapest paid option |
|
||||
| DigitalOcean | Basic | 1 vCPU, 1GB RAM | $6 | Easy UI, good docs |
|
||||
| Vultr | Cloud Compute | 1 vCPU, 1GB RAM | $6 | Many locations |
|
||||
| Linode | Nanode | 1 vCPU, 1GB RAM | $5 | Now part of Akamai |
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Oracle Cloud account ([signup](https://www.oracle.com/cloud/free/)) — see [community signup guide](https://gist.github.com/rssnyder/51e3cfedd730e7dd5f4a816143b25dbd) if you hit issues
|
||||
- Tailscale account (free at [tailscale.com](https://tailscale.com))
|
||||
- ~30 minutes
|
||||
|
||||
## 1) Create an OCI Instance
|
||||
|
||||
1. Log into [Oracle Cloud Console](https://cloud.oracle.com/)
|
||||
2. Navigate to **Compute → Instances → Create Instance**
|
||||
3. Configure:
|
||||
- **Name:** `openclaw`
|
||||
- **Image:** Ubuntu 24.04 (aarch64)
|
||||
- **Shape:** `VM.Standard.A1.Flex` (Ampere ARM)
|
||||
- **OCPUs:** 2 (or up to 4)
|
||||
- **Memory:** 12 GB (or up to 24 GB)
|
||||
- **Boot volume:** 50 GB (up to 200 GB free)
|
||||
- **SSH key:** Add your public key
|
||||
4. Click **Create**
|
||||
5. Note the public IP address
|
||||
|
||||
**Tip:** If instance creation fails with "Out of capacity", try a different availability domain or retry later. Free tier capacity is limited.
|
||||
|
||||
## 2) Connect and Update
|
||||
|
||||
```bash
|
||||
# Connect via public IP
|
||||
ssh ubuntu@YOUR_PUBLIC_IP
|
||||
|
||||
# Update system
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
sudo apt install -y build-essential
|
||||
```
|
||||
|
||||
**Note:** `build-essential` is required for ARM compilation of some dependencies.
|
||||
|
||||
## 3) Configure User and Hostname
|
||||
|
||||
```bash
|
||||
# Set hostname
|
||||
sudo hostnamectl set-hostname openclaw
|
||||
|
||||
# Set password for ubuntu user
|
||||
sudo passwd ubuntu
|
||||
|
||||
# Enable lingering (keeps user services running after logout)
|
||||
sudo loginctl enable-linger ubuntu
|
||||
```
|
||||
|
||||
## 4) Install Tailscale
|
||||
|
||||
```bash
|
||||
curl -fsSL https://tailscale.com/install.sh | sh
|
||||
sudo tailscale up --ssh --hostname=openclaw
|
||||
```
|
||||
|
||||
This enables Tailscale SSH, so you can connect via `ssh openclaw` from any device on your tailnet — no public IP needed.
|
||||
|
||||
Verify:
|
||||
|
||||
```bash
|
||||
tailscale status
|
||||
```
|
||||
|
||||
**From now on, connect via Tailscale:** `ssh ubuntu@openclaw` (or use the Tailscale IP).
|
||||
|
||||
## 5) Install OpenClaw
|
||||
|
||||
```bash
|
||||
curl -fsSL https://openclaw.ai/install.sh | bash
|
||||
source ~/.bashrc
|
||||
```
|
||||
|
||||
When prompted "How do you want to hatch your bot?", select **"Do this later"**.
|
||||
|
||||
> Note: If you hit ARM-native build issues, start with system packages (e.g. `sudo apt install -y build-essential`) before reaching for Homebrew.
|
||||
|
||||
## 6) Configure Gateway (loopback + token auth) and enable Tailscale Serve
|
||||
|
||||
Use token auth as the default. It’s predictable and avoids needing any “insecure auth” Control UI flags.
|
||||
|
||||
```bash
|
||||
# Keep the Gateway private on the VM
|
||||
openclaw config set gateway.bind loopback
|
||||
|
||||
# Require auth for the Gateway + Control UI
|
||||
openclaw config set gateway.auth.mode token
|
||||
openclaw doctor --generate-gateway-token
|
||||
|
||||
# Expose over Tailscale Serve (HTTPS + tailnet access)
|
||||
openclaw config set gateway.tailscale.mode serve
|
||||
openclaw config set gateway.trustedProxies '["127.0.0.1"]'
|
||||
|
||||
systemctl --user restart openclaw-gateway.service
|
||||
```
|
||||
|
||||
`gateway.trustedProxies=["127.0.0.1"]` here is only for the local Tailscale Serve proxy's forwarded-IP/local-client handling. It is **not** `gateway.auth.mode: "trusted-proxy"`. Diff viewer routes keep fail-closed behavior in this setup: raw `127.0.0.1` viewer requests without forwarded proxy headers can return `Diff not found`. Use `mode=file` / `mode=both` for attachments, or intentionally enable remote viewers and set `plugins.entries.diffs.config.viewerBaseUrl` (or pass a proxy `baseUrl`) if you need shareable viewer links.
|
||||
|
||||
## 7) Verify
|
||||
|
||||
```bash
|
||||
# Check version
|
||||
openclaw --version
|
||||
|
||||
# Check daemon status
|
||||
systemctl --user status openclaw-gateway.service
|
||||
|
||||
# Check Tailscale Serve
|
||||
tailscale serve status
|
||||
|
||||
# Test local response
|
||||
curl http://localhost:18789
|
||||
```
|
||||
|
||||
## 8) Lock Down VCN Security
|
||||
|
||||
Now that everything is working, lock down the VCN to block all traffic except Tailscale. OCI's Virtual Cloud Network acts as a firewall at the network edge — traffic is blocked before it reaches your instance.
|
||||
|
||||
1. Go to **Networking → Virtual Cloud Networks** in the OCI Console
|
||||
2. Click your VCN → **Security Lists** → Default Security List
|
||||
3. **Remove** all ingress rules except:
|
||||
- `0.0.0.0/0 UDP 41641` (Tailscale)
|
||||
4. Keep default egress rules (allow all outbound)
|
||||
|
||||
This blocks SSH on port 22, HTTP, HTTPS, and everything else at the network edge. From now on, you can only connect via Tailscale.
|
||||
|
||||
---
|
||||
|
||||
## Access the Control UI
|
||||
|
||||
From any device on your Tailscale network:
|
||||
|
||||
```
|
||||
https://openclaw.<tailnet-name>.ts.net/
|
||||
```
|
||||
|
||||
Replace `<tailnet-name>` with your tailnet name (visible in `tailscale status`).
|
||||
|
||||
No SSH tunnel needed. Tailscale provides:
|
||||
|
||||
- HTTPS encryption (automatic certs)
|
||||
- Authentication via Tailscale identity
|
||||
- Access from any device on your tailnet (laptop, phone, etc.)
|
||||
|
||||
---
|
||||
|
||||
## Security: VCN + Tailscale (recommended baseline)
|
||||
|
||||
With the VCN locked down (only UDP 41641 open) and the Gateway bound to loopback, you get strong defense-in-depth: public traffic is blocked at the network edge, and admin access happens over your tailnet.
|
||||
|
||||
This setup often removes the _need_ for extra host-based firewall rules purely to stop Internet-wide SSH brute force — but you should still keep the OS updated, run `openclaw security audit`, and verify you aren’t accidentally listening on public interfaces.
|
||||
|
||||
### Already protected
|
||||
|
||||
| Traditional Step | Needed? | Why |
|
||||
| ------------------ | ----------- | ---------------------------------------------------------------------------- |
|
||||
| UFW firewall | No | VCN blocks before traffic reaches instance |
|
||||
| fail2ban | No | No brute force if port 22 blocked at VCN |
|
||||
| sshd hardening | No | Tailscale SSH doesn't use sshd |
|
||||
| Disable root login | No | Tailscale uses Tailscale identity, not system users |
|
||||
| SSH key-only auth | No | Tailscale authenticates via your tailnet |
|
||||
| IPv6 hardening | Usually not | Depends on your VCN/subnet settings; verify what’s actually assigned/exposed |
|
||||
|
||||
### Still recommended
|
||||
|
||||
- **Credential permissions:** `chmod 700 ~/.openclaw`
|
||||
- **Security audit:** `openclaw security audit`
|
||||
- **System updates:** `sudo apt update && sudo apt upgrade` regularly
|
||||
- **Monitor Tailscale:** Review devices in [Tailscale admin console](https://login.tailscale.com/admin)
|
||||
|
||||
### Verify security posture
|
||||
|
||||
```bash
|
||||
# Confirm no public ports listening
|
||||
sudo ss -tlnp | grep -v '127.0.0.1\|::1'
|
||||
|
||||
# Verify Tailscale SSH is active
|
||||
tailscale status | grep -q 'offers: ssh' && echo "Tailscale SSH active"
|
||||
|
||||
# Optional: disable sshd entirely
|
||||
sudo systemctl disable --now ssh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Fallback: SSH Tunnel
|
||||
|
||||
If Tailscale Serve isn't working, use an SSH tunnel:
|
||||
|
||||
```bash
|
||||
# From your local machine (via Tailscale)
|
||||
ssh -L 18789:127.0.0.1:18789 ubuntu@openclaw
|
||||
```
|
||||
|
||||
Then open `http://localhost:18789`.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Instance creation fails ("Out of capacity")
|
||||
|
||||
Free tier ARM instances are popular. Try:
|
||||
|
||||
- Different availability domain
|
||||
- Retry during off-peak hours (early morning)
|
||||
- Use the "Always Free" filter when selecting shape
|
||||
|
||||
### Tailscale will not connect
|
||||
|
||||
```bash
|
||||
# Check status
|
||||
sudo tailscale status
|
||||
|
||||
# Re-authenticate
|
||||
sudo tailscale up --ssh --hostname=openclaw --reset
|
||||
```
|
||||
|
||||
### Gateway will not start
|
||||
|
||||
```bash
|
||||
openclaw gateway status
|
||||
openclaw doctor --non-interactive
|
||||
journalctl --user -u openclaw-gateway.service -n 50
|
||||
```
|
||||
|
||||
### Cannot reach Control UI
|
||||
|
||||
```bash
|
||||
# Verify Tailscale Serve is running
|
||||
tailscale serve status
|
||||
|
||||
# Check gateway is listening
|
||||
curl http://localhost:18789
|
||||
|
||||
# Restart if needed
|
||||
systemctl --user restart openclaw-gateway.service
|
||||
```
|
||||
|
||||
### ARM binary issues
|
||||
|
||||
Some tools may not have ARM builds. Check:
|
||||
|
||||
```bash
|
||||
uname -m # Should show aarch64
|
||||
```
|
||||
|
||||
Most npm packages work fine. For binaries, look for `linux-arm64` or `aarch64` releases.
|
||||
|
||||
---
|
||||
|
||||
## Persistence
|
||||
|
||||
All state lives in:
|
||||
|
||||
- `~/.openclaw/` — `openclaw.json`, per-agent `auth-profiles.json`, channel/provider state, and session data
|
||||
- `~/.openclaw/workspace/` — workspace (SOUL.md, memory, artifacts)
|
||||
|
||||
Back up periodically:
|
||||
|
||||
```bash
|
||||
openclaw backup create
|
||||
```
|
||||
|
||||
---
|
||||
This page has moved to [Oracle Cloud](/install/oracle).
|
||||
|
||||
## Related
|
||||
|
||||
- [Gateway remote access](/gateway/remote) — other remote access patterns
|
||||
- [Tailscale integration](/gateway/tailscale) — full Tailscale docs
|
||||
- [Gateway configuration](/gateway/configuration) — all config options
|
||||
- [DigitalOcean guide](/platforms/digitalocean) — if you want paid + easier signup
|
||||
- [Hetzner guide](/install/hetzner) — Docker-based alternative
|
||||
- [Install overview](/install)
|
||||
- [VPS hosting](/vps)
|
||||
|
||||
@@ -1,420 +1,13 @@
|
||||
---
|
||||
summary: "OpenClaw on Raspberry Pi (budget self-hosted setup)"
|
||||
read_when:
|
||||
- Setting up OpenClaw on a Raspberry Pi
|
||||
- Running OpenClaw on ARM devices
|
||||
- Building a cheap always-on personal AI
|
||||
summary: "Redirect to /install/raspberry-pi"
|
||||
title: "Raspberry Pi (platform)"
|
||||
redirect: /install/raspberry-pi
|
||||
---
|
||||
|
||||
# OpenClaw on Raspberry Pi
|
||||
|
||||
## Goal
|
||||
|
||||
Run a persistent, always-on OpenClaw Gateway on a Raspberry Pi for **~$35-80** one-time cost (no monthly fees).
|
||||
|
||||
Perfect for:
|
||||
|
||||
- 24/7 personal AI assistant
|
||||
- Home automation hub
|
||||
- Low-power, always-available Telegram/WhatsApp bot
|
||||
|
||||
## Hardware requirements
|
||||
|
||||
| Pi Model | RAM | Works? | Notes |
|
||||
| --------------- | ------- | -------- | ---------------------------------- |
|
||||
| **Pi 5** | 4GB/8GB | ✅ Best | Fastest, recommended |
|
||||
| **Pi 4** | 4GB | ✅ Good | Sweet spot for most users |
|
||||
| **Pi 4** | 2GB | ✅ OK | Works, add swap |
|
||||
| **Pi 4** | 1GB | ⚠️ Tight | Possible with swap, minimal config |
|
||||
| **Pi 3B+** | 1GB | ⚠️ Slow | Works but sluggish |
|
||||
| **Pi Zero 2 W** | 512MB | ❌ | Not recommended |
|
||||
|
||||
**Minimum specs:** 1GB RAM, 1 core, 500MB disk
|
||||
**Recommended:** 2GB+ RAM, 64-bit OS, 16GB+ SD card (or USB SSD)
|
||||
|
||||
## What you need
|
||||
|
||||
- Raspberry Pi 4 or 5 (2GB+ recommended)
|
||||
- MicroSD card (16GB+) or USB SSD (better performance)
|
||||
- Power supply (official Pi PSU recommended)
|
||||
- Network connection (Ethernet or WiFi)
|
||||
- ~30 minutes
|
||||
|
||||
## 1) Flash the OS
|
||||
|
||||
Use **Raspberry Pi OS Lite (64-bit)** — no desktop needed for a headless server.
|
||||
|
||||
1. Download [Raspberry Pi Imager](https://www.raspberrypi.com/software/)
|
||||
2. Choose OS: **Raspberry Pi OS Lite (64-bit)**
|
||||
3. Click the gear icon (⚙️) to pre-configure:
|
||||
- Set hostname: `gateway-host`
|
||||
- Enable SSH
|
||||
- Set username/password
|
||||
- Configure WiFi (if not using Ethernet)
|
||||
4. Flash to your SD card / USB drive
|
||||
5. Insert and boot the Pi
|
||||
|
||||
## 2) Connect via SSH
|
||||
|
||||
```bash
|
||||
ssh user@gateway-host
|
||||
# or use the IP address
|
||||
ssh user@192.168.x.x
|
||||
```
|
||||
|
||||
## 3) System Setup
|
||||
|
||||
```bash
|
||||
# Update system
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
|
||||
# Install essential packages
|
||||
sudo apt install -y git curl build-essential
|
||||
|
||||
# Set timezone (important for cron/reminders)
|
||||
sudo timedatectl set-timezone America/Chicago # Change to your timezone
|
||||
```
|
||||
|
||||
## 4) Install Node.js 24 (ARM64)
|
||||
|
||||
```bash
|
||||
# Install Node.js via NodeSource
|
||||
curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
|
||||
sudo apt install -y nodejs
|
||||
|
||||
# Verify
|
||||
node --version # Should show v24.x.x
|
||||
npm --version
|
||||
```
|
||||
|
||||
## 5) Add Swap (Important for 2GB or less)
|
||||
|
||||
Swap prevents out-of-memory crashes:
|
||||
|
||||
```bash
|
||||
# Create 2GB swap file
|
||||
sudo fallocate -l 2G /swapfile
|
||||
sudo chmod 600 /swapfile
|
||||
sudo mkswap /swapfile
|
||||
sudo swapon /swapfile
|
||||
|
||||
# Make permanent
|
||||
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
|
||||
|
||||
# Optimize for low RAM (reduce swappiness)
|
||||
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
|
||||
sudo sysctl -p
|
||||
```
|
||||
|
||||
## 6) Install OpenClaw
|
||||
|
||||
### Option A: standard install (recommended)
|
||||
|
||||
```bash
|
||||
curl -fsSL https://openclaw.ai/install.sh | bash
|
||||
```
|
||||
|
||||
### Option B: hackable install (for tinkering)
|
||||
|
||||
```bash
|
||||
git clone https://github.com/openclaw/openclaw.git
|
||||
cd openclaw
|
||||
npm install
|
||||
npm run build
|
||||
npm link
|
||||
```
|
||||
|
||||
The hackable install gives you direct access to logs and code — useful for debugging ARM-specific issues.
|
||||
|
||||
## 7) Run Onboarding
|
||||
|
||||
```bash
|
||||
openclaw onboard --install-daemon
|
||||
```
|
||||
|
||||
Follow the wizard:
|
||||
|
||||
1. **Gateway mode:** Local
|
||||
2. **Auth:** API keys recommended (OAuth can be finicky on headless Pi)
|
||||
3. **Channels:** Telegram is easiest to start with
|
||||
4. **Daemon:** Yes (systemd)
|
||||
|
||||
## 8) Verify Installation
|
||||
|
||||
```bash
|
||||
# Check status
|
||||
openclaw status
|
||||
|
||||
# Check service (standard install = systemd user unit)
|
||||
systemctl --user status openclaw-gateway.service
|
||||
|
||||
# View logs
|
||||
journalctl --user -u openclaw-gateway.service -f
|
||||
```
|
||||
|
||||
## 9) Access the OpenClaw Dashboard
|
||||
|
||||
Replace `user@gateway-host` with your Pi username and hostname or IP address.
|
||||
|
||||
On your computer, ask the Pi to print a fresh dashboard URL:
|
||||
|
||||
```bash
|
||||
ssh user@gateway-host 'openclaw dashboard --no-open'
|
||||
```
|
||||
|
||||
The command prints `Dashboard URL:`. Depending on how `gateway.auth.token`
|
||||
is configured, the URL may be a plain `http://127.0.0.1:18789/` link or one
|
||||
that includes `#token=...`.
|
||||
|
||||
In another terminal on your computer, create the SSH tunnel:
|
||||
|
||||
```bash
|
||||
ssh -N -L 18789:127.0.0.1:18789 user@gateway-host
|
||||
```
|
||||
|
||||
Then open the printed Dashboard URL in your local browser.
|
||||
|
||||
If the UI asks for shared-secret auth, paste the configured token or password
|
||||
into Control UI settings. For token auth, use `gateway.auth.token` (or
|
||||
`OPENCLAW_GATEWAY_TOKEN`).
|
||||
|
||||
For always-on remote access, see [Tailscale](/gateway/tailscale).
|
||||
|
||||
---
|
||||
|
||||
## Performance optimizations
|
||||
|
||||
### Use a USB SSD (Huge Improvement)
|
||||
|
||||
SD cards are slow and wear out. A USB SSD dramatically improves performance:
|
||||
|
||||
```bash
|
||||
# Check if booting from USB
|
||||
lsblk
|
||||
```
|
||||
|
||||
See [Pi USB boot guide](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#usb-mass-storage-boot) for setup.
|
||||
|
||||
### Speed up CLI startup (module compile cache)
|
||||
|
||||
On lower-power Pi hosts, enable Node's module compile cache so repeated CLI runs are faster:
|
||||
|
||||
```bash
|
||||
grep -q 'NODE_COMPILE_CACHE=/var/tmp/openclaw-compile-cache' ~/.bashrc || cat >> ~/.bashrc <<'EOF' # pragma: allowlist secret
|
||||
export NODE_COMPILE_CACHE=/var/tmp/openclaw-compile-cache
|
||||
mkdir -p /var/tmp/openclaw-compile-cache
|
||||
export OPENCLAW_NO_RESPAWN=1
|
||||
EOF
|
||||
source ~/.bashrc
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- `NODE_COMPILE_CACHE` speeds up subsequent runs (`status`, `health`, `--help`).
|
||||
- `/var/tmp` survives reboots better than `/tmp`.
|
||||
- `OPENCLAW_NO_RESPAWN=1` avoids extra startup cost from CLI self-respawn.
|
||||
- First run warms the cache; later runs benefit most.
|
||||
|
||||
### systemd startup tuning (optional)
|
||||
|
||||
If this Pi is mostly running OpenClaw, add a service drop-in to reduce restart
|
||||
jitter and keep startup env stable:
|
||||
|
||||
```bash
|
||||
systemctl --user edit openclaw-gateway.service
|
||||
```
|
||||
|
||||
```ini
|
||||
[Service]
|
||||
Environment=OPENCLAW_NO_RESPAWN=1
|
||||
Environment=NODE_COMPILE_CACHE=/var/tmp/openclaw-compile-cache
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
TimeoutStartSec=90
|
||||
```
|
||||
|
||||
Then apply:
|
||||
|
||||
```bash
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user restart openclaw-gateway.service
|
||||
```
|
||||
|
||||
If possible, keep OpenClaw state/cache on SSD-backed storage to avoid SD-card
|
||||
random-I/O bottlenecks during cold starts.
|
||||
|
||||
If this is a headless Pi, enable lingering once so the user service survives
|
||||
logout:
|
||||
|
||||
```bash
|
||||
sudo loginctl enable-linger "$(whoami)"
|
||||
```
|
||||
|
||||
How `Restart=` policies help automated recovery:
|
||||
[systemd can automate service recovery](https://www.redhat.com/en/blog/systemd-automate-recovery).
|
||||
|
||||
### Reduce memory usage
|
||||
|
||||
```bash
|
||||
# Disable GPU memory allocation (headless)
|
||||
echo 'gpu_mem=16' | sudo tee -a /boot/config.txt
|
||||
|
||||
# Disable Bluetooth if not needed
|
||||
sudo systemctl disable bluetooth
|
||||
```
|
||||
|
||||
### Monitor resources
|
||||
|
||||
```bash
|
||||
# Check memory
|
||||
free -h
|
||||
|
||||
# Check CPU temperature
|
||||
vcgencmd measure_temp
|
||||
|
||||
# Live monitoring
|
||||
htop
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ARM-Specific Notes
|
||||
|
||||
### Binary compatibility
|
||||
|
||||
Most OpenClaw features work on ARM64, but some external binaries may need ARM builds:
|
||||
|
||||
| Tool | ARM64 Status | Notes |
|
||||
| ------------------ | ------------ | ----------------------------------- |
|
||||
| Node.js | ✅ | Works great |
|
||||
| WhatsApp (Baileys) | ✅ | Pure JS, no issues |
|
||||
| Telegram | ✅ | Pure JS, no issues |
|
||||
| gog (Gmail CLI) | ⚠️ | Check for ARM release |
|
||||
| Chromium (browser) | ✅ | `sudo apt install chromium-browser` |
|
||||
|
||||
If a skill fails, check if its binary has an ARM build. Many Go/Rust tools do; some don't.
|
||||
|
||||
### 32-bit vs 64-bit
|
||||
|
||||
**Always use 64-bit OS.** Node.js and many modern tools require it. Check with:
|
||||
|
||||
```bash
|
||||
uname -m
|
||||
# Should show: aarch64 (64-bit) not armv7l (32-bit)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Recommended model setup
|
||||
|
||||
Since the Pi is just the Gateway (models run in the cloud), use API-based models:
|
||||
|
||||
```json
|
||||
{
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": {
|
||||
"primary": "anthropic/claude-sonnet-4-6",
|
||||
"fallbacks": ["openai/gpt-5.4-mini"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Don't try to run local LLMs on a Pi** — even small models are too slow. Let Claude/GPT do the heavy lifting.
|
||||
|
||||
---
|
||||
|
||||
## Auto-Start on Boot
|
||||
|
||||
Onboarding sets this up, but to verify:
|
||||
|
||||
```bash
|
||||
# Check service is enabled
|
||||
systemctl --user is-enabled openclaw-gateway.service
|
||||
|
||||
# Enable if not
|
||||
systemctl --user enable openclaw-gateway.service
|
||||
|
||||
# Start on boot
|
||||
systemctl --user start openclaw-gateway.service
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Out of Memory (OOM)
|
||||
|
||||
```bash
|
||||
# Check memory
|
||||
free -h
|
||||
|
||||
# Add more swap (see Step 5)
|
||||
# Or reduce services running on the Pi
|
||||
```
|
||||
|
||||
### Slow performance
|
||||
|
||||
- Use USB SSD instead of SD card
|
||||
- Disable unused services: `sudo systemctl disable cups bluetooth avahi-daemon`
|
||||
- Check CPU throttling: `vcgencmd get_throttled` (should return `0x0`)
|
||||
|
||||
### Service will not start
|
||||
|
||||
```bash
|
||||
# Check logs
|
||||
journalctl --user -u openclaw-gateway.service --no-pager -n 100
|
||||
|
||||
# Common fix: rebuild
|
||||
cd ~/openclaw # if using hackable install
|
||||
npm run build
|
||||
systemctl --user restart openclaw-gateway.service
|
||||
```
|
||||
|
||||
### ARM Binary Issues
|
||||
|
||||
If a skill fails with "exec format error":
|
||||
|
||||
1. Check if the binary has an ARM64 build
|
||||
2. Try building from source
|
||||
3. Or use a Docker container with ARM support
|
||||
|
||||
### WiFi Drops
|
||||
|
||||
For headless Pis on WiFi:
|
||||
|
||||
```bash
|
||||
# Disable WiFi power management
|
||||
sudo iwconfig wlan0 power off
|
||||
|
||||
# Make permanent
|
||||
echo 'wireless-power off' | sudo tee -a /etc/network/interfaces
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Cost comparison
|
||||
|
||||
| Setup | One-Time Cost | Monthly Cost | Notes |
|
||||
| -------------- | ------------- | ------------ | ------------------------- |
|
||||
| **Pi 4 (2GB)** | ~$45 | $0 | + power (~$5/yr) |
|
||||
| **Pi 4 (4GB)** | ~$55 | $0 | Recommended |
|
||||
| **Pi 5 (4GB)** | ~$60 | $0 | Best performance |
|
||||
| **Pi 5 (8GB)** | ~$80 | $0 | Overkill but future-proof |
|
||||
| DigitalOcean | $0 | $6/mo | $72/year |
|
||||
| Hetzner | $0 | €3.79/mo | ~$50/year |
|
||||
|
||||
**Break-even:** A Pi pays for itself in ~6-12 months vs cloud VPS.
|
||||
|
||||
---
|
||||
This page has moved to [Raspberry Pi](/install/raspberry-pi).
|
||||
|
||||
## Related
|
||||
|
||||
- [Linux guide](/platforms/linux) — general Linux setup
|
||||
- [DigitalOcean guide](/platforms/digitalocean) — cloud alternative
|
||||
- [Hetzner guide](/install/hetzner) — Docker setup
|
||||
- [Tailscale](/gateway/tailscale) — remote access
|
||||
- [Nodes](/nodes) — pair your laptop/phone with the Pi gateway
|
||||
- [Install overview](/install)
|
||||
- [Linux server](/vps)
|
||||
- [Platforms](/platforms)
|
||||
|
||||
133
docs/plugins/adding-capabilities.md
Normal file
133
docs/plugins/adding-capabilities.md
Normal file
@@ -0,0 +1,133 @@
|
||||
---
|
||||
summary: "Contributor guide for adding a new shared capability to the OpenClaw plugin system"
|
||||
read_when:
|
||||
- Adding a new core capability and plugin registration surface
|
||||
- Deciding whether code belongs in core, a vendor plugin, or a feature plugin
|
||||
- Wiring a new runtime helper for channels or tools
|
||||
title: "Adding capabilities (contributor guide)"
|
||||
sidebarTitle: "Adding capabilities"
|
||||
---
|
||||
|
||||
<Info>
|
||||
This is a **contributor guide** for OpenClaw core developers. If you are
|
||||
building an external plugin, see [Building plugins](/plugins/building-plugins)
|
||||
instead. For the deep architecture reference (capability model, ownership,
|
||||
load pipeline, runtime helpers), see [Plugin internals](/plugins/architecture).
|
||||
</Info>
|
||||
|
||||
Use this when OpenClaw needs a new shared domain such as image generation, video generation, or some future vendor-backed feature area.
|
||||
|
||||
The rule:
|
||||
|
||||
- **plugin** = ownership boundary
|
||||
- **capability** = shared core contract
|
||||
|
||||
Do not start by wiring a vendor directly into a channel or a tool. Start by defining the capability.
|
||||
|
||||
## When to create a capability
|
||||
|
||||
Create a new capability when **all** of these are true:
|
||||
|
||||
1. More than one vendor could plausibly implement it.
|
||||
2. Channels, tools, or feature plugins should consume it without caring about the vendor.
|
||||
3. Core needs to own fallback, policy, config, or delivery behavior.
|
||||
|
||||
If the work is vendor-only and no shared contract exists yet, stop and define the contract first.
|
||||
|
||||
## The standard sequence
|
||||
|
||||
1. Define the typed core contract.
|
||||
2. Add plugin registration for that contract.
|
||||
3. Add a shared runtime helper.
|
||||
4. Wire one real vendor plugin as proof.
|
||||
5. Move feature/channel consumers onto the runtime helper.
|
||||
6. Add contract tests.
|
||||
7. Document the operator-facing config and ownership model.
|
||||
|
||||
## What goes where
|
||||
|
||||
**Core:**
|
||||
|
||||
- Request/response types.
|
||||
- Provider registry + resolution.
|
||||
- Fallback behavior.
|
||||
- Config schema with propagated `title` / `description` docs metadata on nested object, wildcard, array-item, and composition nodes.
|
||||
- Runtime helper surface.
|
||||
|
||||
**Vendor plugin:**
|
||||
|
||||
- Vendor API calls.
|
||||
- Vendor auth handling.
|
||||
- Vendor-specific request normalization.
|
||||
- Registration of the capability implementation.
|
||||
|
||||
**Feature/channel plugin:**
|
||||
|
||||
- Calls `api.runtime.*` or the matching `plugin-sdk/*-runtime` helper.
|
||||
- Never calls a vendor implementation directly.
|
||||
|
||||
## Provider and harness seams
|
||||
|
||||
Use **provider hooks** when the behavior belongs to the model provider contract rather than the generic agent loop. Examples include provider-specific request params after transport selection, auth-profile preference, prompt overlays, and follow-up fallback routing after model/profile failover.
|
||||
|
||||
Use **agent harness hooks** when the behavior belongs to the runtime that is executing a turn. Harnesses can classify successful-but-unusable attempt results such as empty, reasoning-only, or planning-only responses so the outer model fallback policy can make the retry decision.
|
||||
|
||||
Keep both seams narrow:
|
||||
|
||||
- Core owns the retry/fallback policy.
|
||||
- Provider plugins own provider-specific request/auth/routing hints.
|
||||
- Harness plugins own runtime-specific attempt classification.
|
||||
- Third-party plugins return hints, not direct mutations of core state.
|
||||
|
||||
## File checklist
|
||||
|
||||
For a new capability, expect to touch these areas:
|
||||
|
||||
- `src/<capability>/types.ts`
|
||||
- `src/<capability>/...registry/runtime.ts`
|
||||
- `src/plugins/types.ts`
|
||||
- `src/plugins/registry.ts`
|
||||
- `src/plugins/captured-registration.ts`
|
||||
- `src/plugins/contracts/registry.ts`
|
||||
- `src/plugins/runtime/types-core.ts`
|
||||
- `src/plugins/runtime/index.ts`
|
||||
- `src/plugin-sdk/<capability>.ts`
|
||||
- `src/plugin-sdk/<capability>-runtime.ts`
|
||||
- One or more bundled plugin packages.
|
||||
- Config, docs, tests.
|
||||
|
||||
## Worked example: image generation
|
||||
|
||||
Image generation follows the standard shape:
|
||||
|
||||
1. Core defines `ImageGenerationProvider`.
|
||||
2. Core exposes `registerImageGenerationProvider(...)`.
|
||||
3. Core exposes `runtime.imageGeneration.generate(...)`.
|
||||
4. The `openai`, `google`, `fal`, and `minimax` plugins register vendor-backed implementations.
|
||||
5. Future vendors register the same contract without changing channels/tools.
|
||||
|
||||
The config key is intentionally separate from vision-analysis routing:
|
||||
|
||||
- `agents.defaults.imageModel` analyzes images.
|
||||
- `agents.defaults.imageGenerationModel` generates images.
|
||||
|
||||
Keep those separate so fallback and policy remain explicit.
|
||||
|
||||
## Review checklist
|
||||
|
||||
Before shipping a new capability, verify:
|
||||
|
||||
- No channel/tool imports vendor code directly.
|
||||
- The runtime helper is the shared path.
|
||||
- At least one contract test asserts bundled ownership.
|
||||
- Config docs name the new model/config key.
|
||||
- Plugin docs explain the ownership boundary.
|
||||
|
||||
If a PR skips the capability layer and hardcodes vendor behavior into a channel/tool, send it back and define the contract first.
|
||||
|
||||
## Related
|
||||
|
||||
- [Plugin internals](/plugins/architecture) — capability model, ownership, load pipeline, runtime helpers.
|
||||
- [Building plugins](/plugins/building-plugins) — first-plugin tutorial.
|
||||
- [SDK overview](/plugins/sdk-overview) — import map and registration API reference.
|
||||
- [Creating skills](/tools/creating-skills) — companion contributor surface.
|
||||
@@ -84,7 +84,7 @@ Use these hubs to discover every page, including deep dives and reference docs t
|
||||
## Gateway + operations
|
||||
|
||||
- [Gateway runbook](/gateway)
|
||||
- [Network model](/gateway/network-model)
|
||||
- [Network model](/network#core-model)
|
||||
- [Gateway pairing](/gateway/pairing)
|
||||
- [Gateway lock](/gateway/gateway-lock)
|
||||
- [Background process](/gateway/background-process)
|
||||
|
||||
@@ -1,142 +1,12 @@
|
||||
---
|
||||
summary: "Contributor guide for adding a new shared capability to the OpenClaw plugin system"
|
||||
read_when:
|
||||
- Adding a new core capability and plugin registration surface
|
||||
- Deciding whether code belongs in core, a vendor plugin, or a feature plugin
|
||||
- Wiring a new runtime helper for channels or tools
|
||||
title: "Adding capabilities (contributor guide)"
|
||||
sidebarTitle: "Adding Capabilities"
|
||||
summary: "Redirect to /plugins/adding-capabilities"
|
||||
title: "Adding capabilities (redirect)"
|
||||
redirect: /plugins/adding-capabilities
|
||||
---
|
||||
|
||||
<Info>
|
||||
This is a **contributor guide** for OpenClaw core developers. If you are
|
||||
building an external plugin, see [Building Plugins](/plugins/building-plugins)
|
||||
instead.
|
||||
</Info>
|
||||
|
||||
Use this when OpenClaw needs a new domain such as image generation, video
|
||||
generation, or some future vendor-backed feature area.
|
||||
|
||||
The rule:
|
||||
|
||||
- plugin = ownership boundary
|
||||
- capability = shared core contract
|
||||
|
||||
That means you should not start by wiring a vendor directly into a channel or a
|
||||
tool. Start by defining the capability.
|
||||
|
||||
## When to create a capability
|
||||
|
||||
Create a new capability when all of these are true:
|
||||
|
||||
1. more than one vendor could plausibly implement it
|
||||
2. channels, tools, or feature plugins should consume it without caring about
|
||||
the vendor
|
||||
3. core needs to own fallback, policy, config, or delivery behavior
|
||||
|
||||
If the work is vendor-only and no shared contract exists yet, stop and define
|
||||
the contract first.
|
||||
|
||||
## The standard sequence
|
||||
|
||||
1. Define the typed core contract.
|
||||
2. Add plugin registration for that contract.
|
||||
3. Add a shared runtime helper.
|
||||
4. Wire one real vendor plugin as proof.
|
||||
5. Move feature/channel consumers onto the runtime helper.
|
||||
6. Add contract tests.
|
||||
7. Document the operator-facing config and ownership model.
|
||||
|
||||
## What goes where
|
||||
|
||||
Core:
|
||||
|
||||
- request/response types
|
||||
- provider registry + resolution
|
||||
- fallback behavior
|
||||
- config schema plus propagated `title` / `description` docs metadata on nested object, wildcard, array-item, and composition nodes
|
||||
- runtime helper surface
|
||||
|
||||
Vendor plugin:
|
||||
|
||||
- vendor API calls
|
||||
- vendor auth handling
|
||||
- vendor-specific request normalization
|
||||
- registration of the capability implementation
|
||||
|
||||
Feature/channel plugin:
|
||||
|
||||
- calls `api.runtime.*` or the matching `plugin-sdk/*-runtime` helper
|
||||
- never calls a vendor implementation directly
|
||||
|
||||
## Provider and harness seams
|
||||
|
||||
Use provider hooks when the behavior belongs to the model provider contract
|
||||
rather than the generic agent loop. Examples include provider-specific request
|
||||
params after transport selection, auth-profile preference, prompt overlays, and
|
||||
follow-up fallback routing after model/profile failover.
|
||||
|
||||
Use agent harness hooks when the behavior belongs to the runtime that is
|
||||
executing a turn. Harnesses can classify successful-but-unusable attempt results
|
||||
such as empty, reasoning-only, or planning-only responses so the outer model
|
||||
fallback policy can make the retry decision.
|
||||
|
||||
Keep both seams narrow:
|
||||
|
||||
- core owns the retry/fallback policy
|
||||
- provider plugins own provider-specific request/auth/routing hints
|
||||
- harness plugins own runtime-specific attempt classification
|
||||
- third-party plugins return hints, not direct mutations of core state
|
||||
|
||||
## File checklist
|
||||
|
||||
For a new capability, expect to touch these areas:
|
||||
|
||||
- `src/<capability>/types.ts`
|
||||
- `src/<capability>/...registry/runtime.ts`
|
||||
- `src/plugins/types.ts`
|
||||
- `src/plugins/registry.ts`
|
||||
- `src/plugins/captured-registration.ts`
|
||||
- `src/plugins/contracts/registry.ts`
|
||||
- `src/plugins/runtime/types-core.ts`
|
||||
- `src/plugins/runtime/index.ts`
|
||||
- `src/plugin-sdk/<capability>.ts`
|
||||
- `src/plugin-sdk/<capability>-runtime.ts`
|
||||
- one or more bundled plugin packages
|
||||
- config/docs/tests
|
||||
|
||||
## Example: image generation
|
||||
|
||||
Image generation follows the standard shape:
|
||||
|
||||
1. core defines `ImageGenerationProvider`
|
||||
2. core exposes `registerImageGenerationProvider(...)`
|
||||
3. core exposes `runtime.imageGeneration.generate(...)`
|
||||
4. the `openai`, `google`, `fal`, and `minimax` plugins register vendor-backed implementations
|
||||
5. future vendors can register the same contract without changing channels/tools
|
||||
|
||||
The config key is separate from vision-analysis routing:
|
||||
|
||||
- `agents.defaults.imageModel` = analyze images
|
||||
- `agents.defaults.imageGenerationModel` = generate images
|
||||
|
||||
Keep those separate so fallback and policy remain explicit.
|
||||
|
||||
## Review checklist
|
||||
|
||||
Before shipping a new capability, verify:
|
||||
|
||||
- no channel/tool imports vendor code directly
|
||||
- the runtime helper is the shared path
|
||||
- at least one contract test asserts bundled ownership
|
||||
- config docs name the new model/config key
|
||||
- plugin docs explain the ownership boundary
|
||||
|
||||
If a PR skips the capability layer and hardcodes vendor behavior into a
|
||||
channel/tool, send it back and define the contract first.
|
||||
This contributor guide moved to [Adding capabilities](/plugins/adding-capabilities).
|
||||
|
||||
## Related
|
||||
|
||||
- [Plugin](/tools/plugin)
|
||||
- [Creating skills](/tools/creating-skills)
|
||||
- [Tools and plugins](/tools)
|
||||
- [Plugin internals](/plugins/architecture)
|
||||
- [Building plugins](/plugins/building-plugins)
|
||||
|
||||
@@ -196,10 +196,10 @@ Use `group:*` shorthands in allow/deny lists:
|
||||
| `group:memory` | memory_search, memory_get |
|
||||
| `group:web` | web_search, x_search, web_fetch |
|
||||
| `group:ui` | browser, canvas |
|
||||
| `group:automation` | cron, gateway |
|
||||
| `group:automation` | heartbeat_respond, cron, gateway |
|
||||
| `group:messaging` | message |
|
||||
| `group:nodes` | nodes |
|
||||
| `group:agents` | agents_list |
|
||||
| `group:agents` | agents_list, update_plan |
|
||||
| `group:media` | image, image_generate, music_generate, video_generate, tts |
|
||||
| `group:openclaw` | All built-in OpenClaw tools (excludes plugin tools) |
|
||||
|
||||
|
||||
Reference in New Issue
Block a user