mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-10 06:33:18 +08:00
重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。
同时收敛启动与运维脚本默认行为(含 wiki worker)、更新 Admin 可观测性与相关测试,降低首轮时延并提高运行稳定性。 Made-with: Cursor
This commit is contained in:
parent
4a23b715a2
commit
dbbe3add6a
14438 changed files with 2693620 additions and 2546 deletions
230
openclaw/docs/install/ansible.md
Normal file
230
openclaw/docs/install/ansible.md
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
---
|
||||
summary: "Automated, hardened OpenClaw installation with Ansible, Tailscale VPN, and firewall isolation"
|
||||
read_when:
|
||||
- You want automated server deployment with security hardening
|
||||
- You need firewall-isolated setup with VPN access
|
||||
- You're deploying to remote Debian/Ubuntu servers
|
||||
title: "Ansible"
|
||||
---
|
||||
|
||||
# Ansible Installation
|
||||
|
||||
Deploy OpenClaw to production servers with **[openclaw-ansible](https://github.com/openclaw/openclaw-ansible)** -- an automated installer with security-first architecture.
|
||||
|
||||
<Info>
|
||||
The [openclaw-ansible](https://github.com/openclaw/openclaw-ansible) repo is the source of truth for Ansible deployment. This page is a quick overview.
|
||||
</Info>
|
||||
|
||||
## Prerequisites
|
||||
|
||||
| Requirement | Details |
|
||||
| ----------- | --------------------------------------------------------- |
|
||||
| **OS** | Debian 11+ or Ubuntu 20.04+ |
|
||||
| **Access** | Root or sudo privileges |
|
||||
| **Network** | Internet connection for package installation |
|
||||
| **Ansible** | 2.14+ (installed automatically by the quick-start script) |
|
||||
|
||||
## What You Get
|
||||
|
||||
- **Firewall-first security** -- UFW + Docker isolation (only SSH + Tailscale accessible)
|
||||
- **Tailscale VPN** -- secure remote access without exposing services publicly
|
||||
- **Docker** -- isolated sandbox containers, localhost-only bindings
|
||||
- **Defense in depth** -- 4-layer security architecture
|
||||
- **Systemd integration** -- auto-start on boot with hardening
|
||||
- **One-command setup** -- complete deployment in minutes
|
||||
|
||||
## Quick Start
|
||||
|
||||
One-command install:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/openclaw/openclaw-ansible/main/install.sh | bash
|
||||
```
|
||||
|
||||
## What Gets Installed
|
||||
|
||||
The Ansible playbook installs and configures:
|
||||
|
||||
1. **Tailscale** -- mesh VPN for secure remote access
|
||||
2. **UFW firewall** -- SSH + Tailscale ports only
|
||||
3. **Docker CE + Compose V2** -- for agent sandboxes
|
||||
4. **Node.js 24 + pnpm** -- runtime dependencies (Node 22 LTS, currently `22.14+`, remains supported)
|
||||
5. **OpenClaw** -- host-based, not containerized
|
||||
6. **Systemd service** -- auto-start with security hardening
|
||||
|
||||
<Note>
|
||||
The gateway runs directly on the host (not in Docker), but agent sandboxes use Docker for isolation. See [Sandboxing](/gateway/sandboxing) for details.
|
||||
</Note>
|
||||
|
||||
## Post-Install Setup
|
||||
|
||||
<Steps>
|
||||
<Step title="Switch to the openclaw user">
|
||||
```bash
|
||||
sudo -i -u openclaw
|
||||
```
|
||||
</Step>
|
||||
<Step title="Run the onboarding wizard">
|
||||
The post-install script guides you through configuring OpenClaw settings.
|
||||
</Step>
|
||||
<Step title="Connect messaging providers">
|
||||
Log in to WhatsApp, Telegram, Discord, or Signal:
|
||||
```bash
|
||||
openclaw channels login
|
||||
```
|
||||
</Step>
|
||||
<Step title="Verify the installation">
|
||||
```bash
|
||||
sudo systemctl status openclaw
|
||||
sudo journalctl -u openclaw -f
|
||||
```
|
||||
</Step>
|
||||
<Step title="Connect to Tailscale">
|
||||
Join your VPN mesh for secure remote access.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
### Quick Commands
|
||||
|
||||
```bash
|
||||
# Check service status
|
||||
sudo systemctl status openclaw
|
||||
|
||||
# View live logs
|
||||
sudo journalctl -u openclaw -f
|
||||
|
||||
# Restart gateway
|
||||
sudo systemctl restart openclaw
|
||||
|
||||
# Provider login (run as openclaw user)
|
||||
sudo -i -u openclaw
|
||||
openclaw channels login
|
||||
```
|
||||
|
||||
## Security Architecture
|
||||
|
||||
The deployment uses a 4-layer defense model:
|
||||
|
||||
1. **Firewall (UFW)** -- only SSH (22) + Tailscale (41641/udp) exposed publicly
|
||||
2. **VPN (Tailscale)** -- gateway accessible only via VPN mesh
|
||||
3. **Docker isolation** -- DOCKER-USER iptables chain prevents external port exposure
|
||||
4. **Systemd hardening** -- NoNewPrivileges, PrivateTmp, unprivileged user
|
||||
|
||||
To verify your external attack surface:
|
||||
|
||||
```bash
|
||||
nmap -p- YOUR_SERVER_IP
|
||||
```
|
||||
|
||||
Only port 22 (SSH) should be open. All other services (gateway, Docker) are locked down.
|
||||
|
||||
Docker is installed for agent sandboxes (isolated tool execution), not for running the gateway itself. See [Multi-Agent Sandbox and Tools](/tools/multi-agent-sandbox-tools) for sandbox configuration.
|
||||
|
||||
## Manual Installation
|
||||
|
||||
If you prefer manual control over the automation:
|
||||
|
||||
<Steps>
|
||||
<Step title="Install prerequisites">
|
||||
```bash
|
||||
sudo apt update && sudo apt install -y ansible git
|
||||
```
|
||||
</Step>
|
||||
<Step title="Clone the repository">
|
||||
```bash
|
||||
git clone https://github.com/openclaw/openclaw-ansible.git
|
||||
cd openclaw-ansible
|
||||
```
|
||||
</Step>
|
||||
<Step title="Install Ansible collections">
|
||||
```bash
|
||||
ansible-galaxy collection install -r requirements.yml
|
||||
```
|
||||
</Step>
|
||||
<Step title="Run the playbook">
|
||||
```bash
|
||||
./run-playbook.sh
|
||||
```
|
||||
|
||||
Alternatively, run directly and then manually execute the setup script afterward:
|
||||
```bash
|
||||
ansible-playbook playbook.yml --ask-become-pass
|
||||
# Then run: /tmp/openclaw-setup.sh
|
||||
```
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Updating
|
||||
|
||||
The Ansible installer sets up OpenClaw for manual updates. See [Updating](/install/updating) for the standard update flow.
|
||||
|
||||
To re-run the Ansible playbook (for example, for configuration changes):
|
||||
|
||||
```bash
|
||||
cd openclaw-ansible
|
||||
./run-playbook.sh
|
||||
```
|
||||
|
||||
This is idempotent and safe to run multiple times.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Firewall blocks my connection">
|
||||
- Ensure you can access via Tailscale VPN first
|
||||
- SSH access (port 22) is always allowed
|
||||
- The gateway is only accessible via Tailscale by design
|
||||
</Accordion>
|
||||
<Accordion title="Service will not start">
|
||||
```bash
|
||||
# Check logs
|
||||
sudo journalctl -u openclaw -n 100
|
||||
|
||||
# Verify permissions
|
||||
sudo ls -la /opt/openclaw
|
||||
|
||||
# Test manual start
|
||||
sudo -i -u openclaw
|
||||
cd ~/openclaw
|
||||
openclaw gateway run
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Docker sandbox issues">
|
||||
```bash
|
||||
# Verify Docker is running
|
||||
sudo systemctl status docker
|
||||
|
||||
# Check sandbox image
|
||||
sudo docker images | grep openclaw-sandbox
|
||||
|
||||
# Build sandbox image if missing
|
||||
cd /opt/openclaw/openclaw
|
||||
sudo -u openclaw ./scripts/sandbox-setup.sh
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Provider login fails">
|
||||
Make sure you are running as the `openclaw` user:
|
||||
```bash
|
||||
sudo -i -u openclaw
|
||||
openclaw channels login
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
For detailed security architecture and troubleshooting, see the openclaw-ansible repo:
|
||||
|
||||
- [Security Architecture](https://github.com/openclaw/openclaw-ansible/blob/main/docs/security.md)
|
||||
- [Technical Details](https://github.com/openclaw/openclaw-ansible/blob/main/docs/architecture.md)
|
||||
- [Troubleshooting Guide](https://github.com/openclaw/openclaw-ansible/blob/main/docs/troubleshooting.md)
|
||||
|
||||
## Related
|
||||
|
||||
- [openclaw-ansible](https://github.com/openclaw/openclaw-ansible) -- full deployment guide
|
||||
- [Docker](/install/docker) -- containerized gateway setup
|
||||
- [Sandboxing](/gateway/sandboxing) -- agent sandbox configuration
|
||||
- [Multi-Agent Sandbox and Tools](/tools/multi-agent-sandbox-tools) -- per-agent isolation
|
||||
311
openclaw/docs/install/azure.md
Normal file
311
openclaw/docs/install/azure.md
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
---
|
||||
summary: "Run OpenClaw Gateway 24/7 on an Azure Linux VM with durable state"
|
||||
read_when:
|
||||
- You want OpenClaw running 24/7 on Azure with Network Security Group hardening
|
||||
- You want a production-grade, always-on OpenClaw Gateway on your own Azure Linux VM
|
||||
- You want secure administration with Azure Bastion SSH
|
||||
title: "Azure"
|
||||
---
|
||||
|
||||
# OpenClaw on Azure Linux VM
|
||||
|
||||
This guide sets up an Azure Linux VM with the Azure CLI, applies Network Security Group (NSG) hardening, configures Azure Bastion for SSH access, and installs OpenClaw.
|
||||
|
||||
## What you will do
|
||||
|
||||
- Create Azure networking (VNet, subnets, NSG) and compute resources with the Azure CLI
|
||||
- Apply Network Security Group rules so VM SSH is allowed only from Azure Bastion
|
||||
- Use Azure Bastion for SSH access (no public IP on the VM)
|
||||
- Install OpenClaw with the installer script
|
||||
- Verify the Gateway
|
||||
|
||||
## What you need
|
||||
|
||||
- An Azure subscription with permission to create compute and network resources
|
||||
- Azure CLI installed (see [Azure CLI install steps](https://learn.microsoft.com/cli/azure/install-azure-cli) if needed)
|
||||
- An SSH key pair (the guide covers generating one if needed)
|
||||
- ~20-30 minutes
|
||||
|
||||
## Configure deployment
|
||||
|
||||
<Steps>
|
||||
<Step title="Sign in to Azure CLI">
|
||||
```bash
|
||||
az login
|
||||
az extension add -n ssh
|
||||
```
|
||||
|
||||
The `ssh` extension is required for Azure Bastion native SSH tunneling.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Register required resource providers (one-time)">
|
||||
```bash
|
||||
az provider register --namespace Microsoft.Compute
|
||||
az provider register --namespace Microsoft.Network
|
||||
```
|
||||
|
||||
Verify registration. Wait until both show `Registered`.
|
||||
|
||||
```bash
|
||||
az provider show --namespace Microsoft.Compute --query registrationState -o tsv
|
||||
az provider show --namespace Microsoft.Network --query registrationState -o tsv
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Set deployment variables">
|
||||
```bash
|
||||
RG="rg-openclaw"
|
||||
LOCATION="westus2"
|
||||
VNET_NAME="vnet-openclaw"
|
||||
VNET_PREFIX="10.40.0.0/16"
|
||||
VM_SUBNET_NAME="snet-openclaw-vm"
|
||||
VM_SUBNET_PREFIX="10.40.2.0/24"
|
||||
BASTION_SUBNET_PREFIX="10.40.1.0/26"
|
||||
NSG_NAME="nsg-openclaw-vm"
|
||||
VM_NAME="vm-openclaw"
|
||||
ADMIN_USERNAME="openclaw"
|
||||
BASTION_NAME="bas-openclaw"
|
||||
BASTION_PIP_NAME="pip-openclaw-bastion"
|
||||
```
|
||||
|
||||
Adjust names and CIDR ranges to fit your environment. The Bastion subnet must be at least `/26`.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Select SSH key">
|
||||
Use your existing public key if you have one:
|
||||
|
||||
```bash
|
||||
SSH_PUB_KEY="$(cat ~/.ssh/id_ed25519.pub)"
|
||||
```
|
||||
|
||||
If you don't have an SSH key yet, generate one:
|
||||
|
||||
```bash
|
||||
ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519 -C "you@example.com"
|
||||
SSH_PUB_KEY="$(cat ~/.ssh/id_ed25519.pub)"
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Select VM size and OS disk size">
|
||||
```bash
|
||||
VM_SIZE="Standard_B2as_v2"
|
||||
OS_DISK_SIZE_GB=64
|
||||
```
|
||||
|
||||
Choose a VM size and OS disk size available in your subscription and region:
|
||||
|
||||
- Start smaller for light usage and scale up later
|
||||
- Use more vCPU/RAM/disk for heavier automation, more channels, or larger model/tool workloads
|
||||
- If a VM size is unavailable in your region or subscription quota, pick the closest available SKU
|
||||
|
||||
List VM sizes available in your target region:
|
||||
|
||||
```bash
|
||||
az vm list-skus --location "${LOCATION}" --resource-type virtualMachines -o table
|
||||
```
|
||||
|
||||
Check your current vCPU and disk usage/quota:
|
||||
|
||||
```bash
|
||||
az vm list-usage --location "${LOCATION}" -o table
|
||||
```
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Deploy Azure resources
|
||||
|
||||
<Steps>
|
||||
<Step title="Create the resource group">
|
||||
```bash
|
||||
az group create -n "${RG}" -l "${LOCATION}"
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create the network security group">
|
||||
Create the NSG and add rules so only the Bastion subnet can SSH into the VM.
|
||||
|
||||
```bash
|
||||
az network nsg create \
|
||||
-g "${RG}" -n "${NSG_NAME}" -l "${LOCATION}"
|
||||
|
||||
# Allow SSH from the Bastion subnet only
|
||||
az network nsg rule create \
|
||||
-g "${RG}" --nsg-name "${NSG_NAME}" \
|
||||
-n AllowSshFromBastionSubnet --priority 100 \
|
||||
--access Allow --direction Inbound --protocol Tcp \
|
||||
--source-address-prefixes "${BASTION_SUBNET_PREFIX}" \
|
||||
--destination-port-ranges 22
|
||||
|
||||
# Deny SSH from the public internet
|
||||
az network nsg rule create \
|
||||
-g "${RG}" --nsg-name "${NSG_NAME}" \
|
||||
-n DenyInternetSsh --priority 110 \
|
||||
--access Deny --direction Inbound --protocol Tcp \
|
||||
--source-address-prefixes Internet \
|
||||
--destination-port-ranges 22
|
||||
|
||||
# Deny SSH from other VNet sources
|
||||
az network nsg rule create \
|
||||
-g "${RG}" --nsg-name "${NSG_NAME}" \
|
||||
-n DenyVnetSsh --priority 120 \
|
||||
--access Deny --direction Inbound --protocol Tcp \
|
||||
--source-address-prefixes VirtualNetwork \
|
||||
--destination-port-ranges 22
|
||||
```
|
||||
|
||||
The rules are evaluated by priority (lowest number first): Bastion traffic is allowed at 100, then all other SSH is blocked at 110 and 120.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Create the virtual network and subnets">
|
||||
Create the VNet with the VM subnet (NSG attached), then add the Bastion subnet.
|
||||
|
||||
```bash
|
||||
az network vnet create \
|
||||
-g "${RG}" -n "${VNET_NAME}" -l "${LOCATION}" \
|
||||
--address-prefixes "${VNET_PREFIX}" \
|
||||
--subnet-name "${VM_SUBNET_NAME}" \
|
||||
--subnet-prefixes "${VM_SUBNET_PREFIX}"
|
||||
|
||||
# Attach the NSG to the VM subnet
|
||||
az network vnet subnet update \
|
||||
-g "${RG}" --vnet-name "${VNET_NAME}" \
|
||||
-n "${VM_SUBNET_NAME}" --nsg "${NSG_NAME}"
|
||||
|
||||
# AzureBastionSubnet — name is required by Azure
|
||||
az network vnet subnet create \
|
||||
-g "${RG}" --vnet-name "${VNET_NAME}" \
|
||||
-n AzureBastionSubnet \
|
||||
--address-prefixes "${BASTION_SUBNET_PREFIX}"
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Create the VM">
|
||||
The VM has no public IP. SSH access is exclusively through Azure Bastion.
|
||||
|
||||
```bash
|
||||
az vm create \
|
||||
-g "${RG}" -n "${VM_NAME}" -l "${LOCATION}" \
|
||||
--image "Canonical:ubuntu-24_04-lts:server:latest" \
|
||||
--size "${VM_SIZE}" \
|
||||
--os-disk-size-gb "${OS_DISK_SIZE_GB}" \
|
||||
--storage-sku StandardSSD_LRS \
|
||||
--admin-username "${ADMIN_USERNAME}" \
|
||||
--ssh-key-values "${SSH_PUB_KEY}" \
|
||||
--vnet-name "${VNET_NAME}" \
|
||||
--subnet "${VM_SUBNET_NAME}" \
|
||||
--public-ip-address "" \
|
||||
--nsg ""
|
||||
```
|
||||
|
||||
`--public-ip-address ""` prevents a public IP from being assigned. `--nsg ""` skips creating a per-NIC NSG (the subnet-level NSG handles security).
|
||||
|
||||
**Reproducibility:** The command above uses `latest` for the Ubuntu image. To pin a specific version, list available versions and replace `latest`:
|
||||
|
||||
```bash
|
||||
az vm image list \
|
||||
--publisher Canonical --offer ubuntu-24_04-lts \
|
||||
--sku server --all -o table
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Create Azure Bastion">
|
||||
Azure Bastion provides managed SSH access to the VM without exposing a public IP. Standard SKU with tunneling is required for CLI-based `az network bastion ssh`.
|
||||
|
||||
```bash
|
||||
az network public-ip create \
|
||||
-g "${RG}" -n "${BASTION_PIP_NAME}" -l "${LOCATION}" \
|
||||
--sku Standard --allocation-method Static
|
||||
|
||||
az network bastion create \
|
||||
-g "${RG}" -n "${BASTION_NAME}" -l "${LOCATION}" \
|
||||
--vnet-name "${VNET_NAME}" \
|
||||
--public-ip-address "${BASTION_PIP_NAME}" \
|
||||
--sku Standard --enable-tunneling true
|
||||
```
|
||||
|
||||
Bastion provisioning typically takes 5-10 minutes but can take up to 15-30 minutes in some regions.
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Install OpenClaw
|
||||
|
||||
<Steps>
|
||||
<Step title="SSH into the VM through Azure Bastion">
|
||||
```bash
|
||||
VM_ID="$(az vm show -g "${RG}" -n "${VM_NAME}" --query id -o tsv)"
|
||||
|
||||
az network bastion ssh \
|
||||
--name "${BASTION_NAME}" \
|
||||
--resource-group "${RG}" \
|
||||
--target-resource-id "${VM_ID}" \
|
||||
--auth-type ssh-key \
|
||||
--username "${ADMIN_USERNAME}" \
|
||||
--ssh-key ~/.ssh/id_ed25519
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Install OpenClaw (in the VM shell)">
|
||||
```bash
|
||||
curl -fsSL https://openclaw.ai/install.sh -o /tmp/install.sh
|
||||
bash /tmp/install.sh
|
||||
rm -f /tmp/install.sh
|
||||
```
|
||||
|
||||
The installer installs Node LTS and dependencies if not already present, installs OpenClaw, and launches the onboarding wizard. See [Install](/install) for details.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Verify the Gateway">
|
||||
After onboarding completes:
|
||||
|
||||
```bash
|
||||
openclaw gateway status
|
||||
```
|
||||
|
||||
Most enterprise Azure teams already have GitHub Copilot licenses. If that is your case, we recommend choosing the GitHub Copilot provider in the OpenClaw onboarding wizard. See [GitHub Copilot provider](/providers/github-copilot).
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Cost considerations
|
||||
|
||||
Azure Bastion Standard SKU runs approximately **\$140/month** and the VM (Standard_B2as_v2) runs approximately **\$55/month**.
|
||||
|
||||
To reduce costs:
|
||||
|
||||
- **Deallocate the VM** when not in use (stops compute billing; disk charges remain). The OpenClaw Gateway will not be reachable while the VM is deallocated — restart it when you need it live again:
|
||||
|
||||
```bash
|
||||
az vm deallocate -g "${RG}" -n "${VM_NAME}"
|
||||
az vm start -g "${RG}" -n "${VM_NAME}" # restart later
|
||||
```
|
||||
|
||||
- **Delete Bastion when not needed** and recreate it when you need SSH access. Bastion is the largest cost component and takes only a few minutes to provision.
|
||||
- **Use the Basic Bastion SKU** (~\$38/month) if you only need Portal-based SSH and don't require CLI tunneling (`az network bastion ssh`).
|
||||
|
||||
## Cleanup
|
||||
|
||||
To delete all resources created by this guide:
|
||||
|
||||
```bash
|
||||
az group delete -n "${RG}" --yes --no-wait
|
||||
```
|
||||
|
||||
This removes the resource group and everything inside it (VM, VNet, NSG, Bastion, public IP).
|
||||
|
||||
## Next steps
|
||||
|
||||
- Set up messaging channels: [Channels](/channels)
|
||||
- Pair local devices as nodes: [Nodes](/nodes)
|
||||
- Configure the Gateway: [Gateway configuration](/gateway/configuration)
|
||||
- For more details on OpenClaw Azure deployment with the GitHub Copilot model provider: [OpenClaw on Azure with GitHub Copilot](https://github.com/johnsonshi/openclaw-azure-github-copilot)
|
||||
55
openclaw/docs/install/bun.md
Normal file
55
openclaw/docs/install/bun.md
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
---
|
||||
summary: "Bun workflow (experimental): installs and gotchas vs pnpm"
|
||||
read_when:
|
||||
- You want the fastest local dev loop (bun + watch)
|
||||
- You hit Bun install/patch/lifecycle script issues
|
||||
title: "Bun (Experimental)"
|
||||
---
|
||||
|
||||
# Bun (Experimental)
|
||||
|
||||
<Warning>
|
||||
Bun is **not recommended for gateway runtime** (known issues with WhatsApp and Telegram). Use Node for production.
|
||||
</Warning>
|
||||
|
||||
Bun is an optional local runtime for running TypeScript directly (`bun run ...`, `bun --watch ...`). The default package manager remains `pnpm`, which is fully supported and used by docs tooling. Bun cannot use `pnpm-lock.yaml` and will ignore it.
|
||||
|
||||
## Install
|
||||
|
||||
<Steps>
|
||||
<Step title="Install dependencies">
|
||||
```sh
|
||||
bun install
|
||||
```
|
||||
|
||||
`bun.lock` / `bun.lockb` are gitignored, so there is no repo churn. To skip lockfile writes entirely:
|
||||
|
||||
```sh
|
||||
bun install --no-save
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="Build and test">
|
||||
```sh
|
||||
bun run build
|
||||
bun run vitest run
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Lifecycle Scripts
|
||||
|
||||
Bun blocks dependency lifecycle scripts unless explicitly trusted. For this repo, the commonly blocked scripts are not required:
|
||||
|
||||
- `@whiskeysockets/baileys` `preinstall` -- checks Node major >= 20 (OpenClaw defaults to Node 24 and still supports Node 22 LTS, currently `22.14+`)
|
||||
- `protobufjs` `postinstall` -- emits warnings about incompatible version schemes (no build artifacts)
|
||||
|
||||
If you hit a runtime issue that requires these scripts, trust them explicitly:
|
||||
|
||||
```sh
|
||||
bun pm trust @whiskeysockets/baileys protobufjs
|
||||
```
|
||||
|
||||
## Caveats
|
||||
|
||||
Some scripts still hardcode pnpm (for example `docs:build`, `ui:*`, `protocol:check`). Run those via pnpm for now.
|
||||
106
openclaw/docs/install/clawdock.md
Normal file
106
openclaw/docs/install/clawdock.md
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
---
|
||||
summary: "ClawDock shell helpers for Docker-based OpenClaw installs"
|
||||
read_when:
|
||||
- You run OpenClaw with Docker often and want shorter day-to-day commands
|
||||
- You want a helper layer for dashboard, logs, token setup, and pairing flows
|
||||
title: "ClawDock"
|
||||
---
|
||||
|
||||
# ClawDock
|
||||
|
||||
ClawDock is a small shell-helper layer for Docker-based OpenClaw installs.
|
||||
|
||||
It gives you short commands like `clawdock-start`, `clawdock-dashboard`, and `clawdock-fix-token` instead of longer `docker compose ...` invocations.
|
||||
|
||||
If you have not set up Docker yet, start with [Docker](/install/docker).
|
||||
|
||||
## Install
|
||||
|
||||
Use the canonical helper path:
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.clawdock && curl -sL https://raw.githubusercontent.com/openclaw/openclaw/main/scripts/clawdock/clawdock-helpers.sh -o ~/.clawdock/clawdock-helpers.sh
|
||||
echo 'source ~/.clawdock/clawdock-helpers.sh' >> ~/.zshrc && source ~/.zshrc
|
||||
```
|
||||
|
||||
If you previously installed ClawDock from `scripts/shell-helpers/clawdock-helpers.sh`, reinstall from the new `scripts/clawdock/clawdock-helpers.sh` path. The old raw GitHub path was removed.
|
||||
|
||||
## What you get
|
||||
|
||||
### Basic operations
|
||||
|
||||
| Command | Description |
|
||||
| ------------------ | ---------------------- |
|
||||
| `clawdock-start` | Start the gateway |
|
||||
| `clawdock-stop` | Stop the gateway |
|
||||
| `clawdock-restart` | Restart the gateway |
|
||||
| `clawdock-status` | Check container status |
|
||||
| `clawdock-logs` | Follow gateway logs |
|
||||
|
||||
### Container access
|
||||
|
||||
| Command | Description |
|
||||
| ------------------------- | --------------------------------------------- |
|
||||
| `clawdock-shell` | Open a shell inside the gateway container |
|
||||
| `clawdock-cli <command>` | Run OpenClaw CLI commands in Docker |
|
||||
| `clawdock-exec <command>` | Execute an arbitrary command in the container |
|
||||
|
||||
### Web UI and pairing
|
||||
|
||||
| Command | Description |
|
||||
| ----------------------- | ---------------------------- |
|
||||
| `clawdock-dashboard` | Open the Control UI URL |
|
||||
| `clawdock-devices` | List pending device pairings |
|
||||
| `clawdock-approve <id>` | Approve a pairing request |
|
||||
|
||||
### Setup and maintenance
|
||||
|
||||
| Command | Description |
|
||||
| -------------------- | ------------------------------------------------ |
|
||||
| `clawdock-fix-token` | Configure the gateway token inside the container |
|
||||
| `clawdock-update` | Pull, rebuild, and restart |
|
||||
| `clawdock-rebuild` | Rebuild the Docker image only |
|
||||
| `clawdock-clean` | Remove containers and volumes |
|
||||
|
||||
### Utilities
|
||||
|
||||
| Command | Description |
|
||||
| ---------------------- | --------------------------------------- |
|
||||
| `clawdock-health` | Run a gateway health check |
|
||||
| `clawdock-token` | Print the gateway token |
|
||||
| `clawdock-cd` | Jump to the OpenClaw project directory |
|
||||
| `clawdock-config` | Open `~/.openclaw` |
|
||||
| `clawdock-show-config` | Print config files with redacted values |
|
||||
| `clawdock-workspace` | Open the workspace directory |
|
||||
|
||||
## First-time flow
|
||||
|
||||
```bash
|
||||
clawdock-start
|
||||
clawdock-fix-token
|
||||
clawdock-dashboard
|
||||
```
|
||||
|
||||
If the browser says pairing is required:
|
||||
|
||||
```bash
|
||||
clawdock-devices
|
||||
clawdock-approve <request-id>
|
||||
```
|
||||
|
||||
## Config and secrets
|
||||
|
||||
ClawDock works with the same Docker config split described in [Docker](/install/docker):
|
||||
|
||||
- `<project>/.env` for Docker-specific values like image name, ports, and the gateway token
|
||||
- `~/.openclaw/.env` for env-backed provider keys and bot tokens
|
||||
- `~/.openclaw/agents/<agentId>/agent/auth-profiles.json` for stored provider OAuth/API-key auth
|
||||
- `~/.openclaw/openclaw.json` for behavior config
|
||||
|
||||
Use `clawdock-show-config` when you want to inspect the `.env` files and `openclaw.json` quickly. It redacts `.env` values in its printed output.
|
||||
|
||||
## Related pages
|
||||
|
||||
- [Docker](/install/docker)
|
||||
- [Docker VM Runtime](/install/docker-vm-runtime)
|
||||
- [Updating](/install/updating)
|
||||
131
openclaw/docs/install/development-channels.md
Normal file
131
openclaw/docs/install/development-channels.md
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
---
|
||||
summary: "Stable, beta, and dev channels: semantics, switching, pinning, and tagging"
|
||||
read_when:
|
||||
- You want to switch between stable/beta/dev
|
||||
- You want to pin a specific version, tag, or SHA
|
||||
- You are tagging or publishing prereleases
|
||||
title: "Release Channels"
|
||||
sidebarTitle: "Release Channels"
|
||||
---
|
||||
|
||||
# Development channels
|
||||
|
||||
OpenClaw ships three update channels:
|
||||
|
||||
- **stable**: npm dist-tag `latest`. Recommended for most users.
|
||||
- **beta**: npm dist-tag `beta` when it is current; if beta is missing or older than
|
||||
the latest stable release, the update flow falls back to `latest`.
|
||||
- **dev**: moving head of `main` (git). npm dist-tag: `dev` (when published).
|
||||
The `main` branch is for experimentation and active development. It may contain
|
||||
incomplete features or breaking changes. Do not use it for production gateways.
|
||||
|
||||
We usually ship stable builds to **beta** first, test them there, then run an
|
||||
explicit promotion step that moves the vetted build to `latest` without
|
||||
changing the version number. Maintainers can also publish a stable release
|
||||
directly to `latest` when needed. Dist-tags are the source of truth for npm
|
||||
installs.
|
||||
|
||||
## Switching channels
|
||||
|
||||
```bash
|
||||
openclaw update --channel stable
|
||||
openclaw update --channel beta
|
||||
openclaw update --channel dev
|
||||
```
|
||||
|
||||
`--channel` persists your choice in config (`update.channel`) and aligns the
|
||||
install method:
|
||||
|
||||
- **`stable`** (package installs): updates via npm dist-tag `latest`.
|
||||
- **`beta`** (package installs): prefers npm dist-tag `beta`, but falls back to
|
||||
`latest` when `beta` is missing or older than the current stable tag.
|
||||
- **`stable`** (git installs): checks out the latest stable git tag.
|
||||
- **`beta`** (git installs): prefers the latest beta git tag, but falls back to
|
||||
the latest stable git tag when beta is missing or older.
|
||||
- **`dev`**: ensures a git checkout (default `~/openclaw`, override with
|
||||
`OPENCLAW_GIT_DIR`), switches to `main`, rebases on upstream, builds, and
|
||||
installs the global CLI from that checkout.
|
||||
|
||||
Tip: if you want stable + dev in parallel, keep two clones and point your
|
||||
gateway at the stable one.
|
||||
|
||||
## One-off version or tag targeting
|
||||
|
||||
Use `--tag` to target a specific dist-tag, version, or package spec for a single
|
||||
update **without** changing your persisted channel:
|
||||
|
||||
```bash
|
||||
# Install a specific version
|
||||
openclaw update --tag 2026.4.1-beta.1
|
||||
|
||||
# Install from the beta dist-tag (one-off, does not persist)
|
||||
openclaw update --tag beta
|
||||
|
||||
# Install from GitHub main branch (npm tarball)
|
||||
openclaw update --tag main
|
||||
|
||||
# Install a specific npm package spec
|
||||
openclaw update --tag openclaw@2026.4.1-beta.1
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- `--tag` applies to **package (npm) installs only**. Git installs ignore it.
|
||||
- The tag is not persisted. Your next `openclaw update` uses your configured
|
||||
channel as usual.
|
||||
- Downgrade protection: if the target version is older than your current version,
|
||||
OpenClaw prompts for confirmation (skip with `--yes`).
|
||||
- `--channel beta` is different from `--tag beta`: the channel flow can fall back
|
||||
to stable/latest when beta is missing or older, while `--tag beta` targets the
|
||||
raw `beta` dist-tag for that one run.
|
||||
|
||||
## Dry run
|
||||
|
||||
Preview what `openclaw update` would do without making changes:
|
||||
|
||||
```bash
|
||||
openclaw update --dry-run
|
||||
openclaw update --channel beta --dry-run
|
||||
openclaw update --tag 2026.4.1-beta.1 --dry-run
|
||||
openclaw update --dry-run --json
|
||||
```
|
||||
|
||||
The dry run shows the effective channel, target version, planned actions, and
|
||||
whether a downgrade confirmation would be required.
|
||||
|
||||
## Plugins and channels
|
||||
|
||||
When you switch channels with `openclaw update`, OpenClaw also syncs plugin
|
||||
sources:
|
||||
|
||||
- `dev` prefers bundled plugins from the git checkout.
|
||||
- `stable` and `beta` restore npm-installed plugin packages.
|
||||
- npm-installed plugins are updated after the core update completes.
|
||||
|
||||
## Checking current status
|
||||
|
||||
```bash
|
||||
openclaw update status
|
||||
```
|
||||
|
||||
Shows the active channel, install kind (git or package), current version, and
|
||||
source (config, git tag, git branch, or default).
|
||||
|
||||
## Tagging best practices
|
||||
|
||||
- Tag releases you want git checkouts to land on (`vYYYY.M.D` for stable,
|
||||
`vYYYY.M.D-beta.N` for beta).
|
||||
- `vYYYY.M.D.beta.N` is also recognized for compatibility, but prefer `-beta.N`.
|
||||
- Legacy `vYYYY.M.D-<patch>` tags are still recognized as stable (non-beta).
|
||||
- Keep tags immutable: never move or reuse a tag.
|
||||
- npm dist-tags remain the source of truth for npm installs:
|
||||
- `latest` -> stable
|
||||
- `beta` -> candidate build or beta-first stable build
|
||||
- `dev` -> main snapshot (optional)
|
||||
|
||||
## macOS app availability
|
||||
|
||||
Beta and dev builds may **not** include a macOS app release. That is OK:
|
||||
|
||||
- The git tag and npm dist-tag can still be published.
|
||||
- Call out "no macOS build for this beta" in release notes or changelog.
|
||||
129
openclaw/docs/install/digitalocean.md
Normal file
129
openclaw/docs/install/digitalocean.md
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
---
|
||||
summary: "Host OpenClaw on a DigitalOcean Droplet"
|
||||
read_when:
|
||||
- Setting up OpenClaw on DigitalOcean
|
||||
- Looking for a simple paid VPS for OpenClaw
|
||||
title: "DigitalOcean"
|
||||
---
|
||||
|
||||
# DigitalOcean
|
||||
|
||||
Run a persistent OpenClaw Gateway on a DigitalOcean Droplet.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- DigitalOcean account ([signup](https://cloud.digitalocean.com/registrations/new))
|
||||
- SSH key pair (or willingness to use password auth)
|
||||
- About 20 minutes
|
||||
|
||||
## Setup
|
||||
|
||||
<Steps>
|
||||
<Step title="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
|
||||
- **Image:** Ubuntu 24.04 LTS
|
||||
- **Size:** Basic, Regular, 1 vCPU / 1 GB RAM / 25 GB SSD
|
||||
- **Authentication:** SSH key (recommended) or password
|
||||
4. Click **Create Droplet** and note the IP address.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Connect and install">
|
||||
```bash
|
||||
ssh root@YOUR_DROPLET_IP
|
||||
|
||||
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
|
||||
openclaw --version
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Run onboarding">
|
||||
```bash
|
||||
openclaw onboard --install-daemon
|
||||
```
|
||||
|
||||
The wizard walks you through model auth, channel setup, gateway token generation, and daemon installation (systemd).
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Add swap (recommended for 1 GB Droplets)">
|
||||
```bash
|
||||
fallocate -l 2G /swapfile
|
||||
chmod 600 /swapfile
|
||||
mkswap /swapfile
|
||||
swapon /swapfile
|
||||
echo '/swapfile none swap sw 0 0' >> /etc/fstab
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Verify the gateway">
|
||||
```bash
|
||||
openclaw status
|
||||
systemctl --user status openclaw-gateway.service
|
||||
journalctl --user -u openclaw-gateway.service -f
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Access the Control UI">
|
||||
The gateway binds to loopback by default. Pick one of these options.
|
||||
|
||||
**Option A: SSH tunnel (simplest)**
|
||||
|
||||
```bash
|
||||
# From your local machine
|
||||
ssh -L 18789:localhost:18789 root@YOUR_DROPLET_IP
|
||||
```
|
||||
|
||||
Then open `http://localhost:18789`.
|
||||
|
||||
**Option B: Tailscale Serve**
|
||||
|
||||
```bash
|
||||
curl -fsSL https://tailscale.com/install.sh | sh
|
||||
tailscale up
|
||||
openclaw config set gateway.tailscale.mode serve
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
Then open `https://<magicdns>/` from any device on your tailnet.
|
||||
|
||||
**Option C: Tailnet bind (no Serve)**
|
||||
|
||||
```bash
|
||||
openclaw config set gateway.bind tailnet
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
Then open `http://<tailscale-ip>:18789` (token required).
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Gateway will not start** -- Run `openclaw doctor --non-interactive` and check logs with `journalctl --user -u openclaw-gateway.service -n 50`.
|
||||
|
||||
**Port already in use** -- Run `lsof -i :18789` to find the process, then stop it.
|
||||
|
||||
**Out of memory** -- Verify swap is active with `free -h`. If still hitting OOM, use API-based models (Claude, GPT) rather than local models, or upgrade to a 2 GB Droplet.
|
||||
|
||||
## Next steps
|
||||
|
||||
- [Channels](/channels) -- connect Telegram, WhatsApp, Discord, and more
|
||||
- [Gateway configuration](/gateway/configuration) -- all config options
|
||||
- [Updating](/install/updating) -- keep OpenClaw up to date
|
||||
142
openclaw/docs/install/docker-vm-runtime.md
Normal file
142
openclaw/docs/install/docker-vm-runtime.md
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
---
|
||||
summary: "Shared Docker VM runtime steps for long-lived OpenClaw Gateway hosts"
|
||||
read_when:
|
||||
- You are deploying OpenClaw on a cloud VM with Docker
|
||||
- You need the shared binary bake, persistence, and update flow
|
||||
title: "Docker VM Runtime"
|
||||
---
|
||||
|
||||
# Docker VM Runtime
|
||||
|
||||
Shared runtime steps for VM-based Docker installs such as GCP, Hetzner, and similar VPS providers.
|
||||
|
||||
## Bake required binaries into the image
|
||||
|
||||
Installing binaries inside a running container is a trap.
|
||||
Anything installed at runtime will be lost on restart.
|
||||
|
||||
All external binaries required by skills must be installed at image build time.
|
||||
|
||||
The examples below show three common binaries only:
|
||||
|
||||
- `gog` for Gmail access
|
||||
- `goplaces` for Google Places
|
||||
- `wacli` for WhatsApp
|
||||
|
||||
These are examples, not a complete list.
|
||||
You may install as many binaries as needed using the same pattern.
|
||||
|
||||
If you add new skills later that depend on additional binaries, you must:
|
||||
|
||||
1. Update the Dockerfile
|
||||
2. Rebuild the image
|
||||
3. Restart the containers
|
||||
|
||||
**Example Dockerfile**
|
||||
|
||||
```dockerfile
|
||||
FROM node:24-bookworm
|
||||
|
||||
RUN apt-get update && apt-get install -y socat && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Example binary 1: Gmail CLI
|
||||
RUN curl -L https://github.com/steipete/gog/releases/latest/download/gog_Linux_x86_64.tar.gz \
|
||||
| tar -xz -C /usr/local/bin && chmod +x /usr/local/bin/gog
|
||||
|
||||
# Example binary 2: Google Places CLI
|
||||
RUN curl -L https://github.com/steipete/goplaces/releases/latest/download/goplaces_Linux_x86_64.tar.gz \
|
||||
| tar -xz -C /usr/local/bin && chmod +x /usr/local/bin/goplaces
|
||||
|
||||
# Example binary 3: WhatsApp CLI
|
||||
RUN curl -L https://github.com/steipete/wacli/releases/latest/download/wacli_Linux_x86_64.tar.gz \
|
||||
| tar -xz -C /usr/local/bin && chmod +x /usr/local/bin/wacli
|
||||
|
||||
# Add more binaries below using the same pattern
|
||||
|
||||
WORKDIR /app
|
||||
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
|
||||
COPY ui/package.json ./ui/package.json
|
||||
COPY scripts ./scripts
|
||||
|
||||
RUN corepack enable
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
COPY . .
|
||||
RUN pnpm build
|
||||
RUN pnpm ui:install
|
||||
RUN pnpm ui:build
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
CMD ["node","dist/index.js"]
|
||||
```
|
||||
|
||||
<Note>
|
||||
The download URLs above are for x86_64 (amd64). For ARM-based VMs (e.g. Hetzner ARM, GCP Tau T2A), replace the download URLs with the appropriate ARM64 variants from each tool's release page.
|
||||
</Note>
|
||||
|
||||
## Build and launch
|
||||
|
||||
```bash
|
||||
docker compose build
|
||||
docker compose up -d openclaw-gateway
|
||||
```
|
||||
|
||||
If build fails with `Killed` or `exit code 137` during `pnpm install --frozen-lockfile`, the VM is out of memory.
|
||||
Use a larger machine class before retrying.
|
||||
|
||||
Verify binaries:
|
||||
|
||||
```bash
|
||||
docker compose exec openclaw-gateway which gog
|
||||
docker compose exec openclaw-gateway which goplaces
|
||||
docker compose exec openclaw-gateway which wacli
|
||||
```
|
||||
|
||||
Expected output:
|
||||
|
||||
```
|
||||
/usr/local/bin/gog
|
||||
/usr/local/bin/goplaces
|
||||
/usr/local/bin/wacli
|
||||
```
|
||||
|
||||
Verify Gateway:
|
||||
|
||||
```bash
|
||||
docker compose logs -f openclaw-gateway
|
||||
```
|
||||
|
||||
Expected output:
|
||||
|
||||
```
|
||||
[gateway] listening on ws://0.0.0.0:18789
|
||||
```
|
||||
|
||||
## What persists where
|
||||
|
||||
OpenClaw runs in Docker, but Docker is not the source of truth.
|
||||
All long-lived state must survive restarts, rebuilds, and reboots.
|
||||
|
||||
| Component | Location | Persistence mechanism | Notes |
|
||||
| ------------------- | --------------------------------- | ---------------------- | ------------------------------------------------------------- |
|
||||
| Gateway config | `/home/node/.openclaw/` | Host volume mount | Includes `openclaw.json`, `.env` |
|
||||
| Model auth profiles | `/home/node/.openclaw/agents/` | Host volume mount | `agents/<agentId>/agent/auth-profiles.json` (OAuth, API keys) |
|
||||
| Skill configs | `/home/node/.openclaw/skills/` | Host volume mount | Skill-level state |
|
||||
| Agent workspace | `/home/node/.openclaw/workspace/` | Host volume mount | Code and agent artifacts |
|
||||
| WhatsApp session | `/home/node/.openclaw/` | Host volume mount | Preserves QR login |
|
||||
| Gmail keyring | `/home/node/.openclaw/` | Host volume + password | Requires `GOG_KEYRING_PASSWORD` |
|
||||
| External binaries | `/usr/local/bin/` | Docker image | Must be baked at build time |
|
||||
| Node runtime | Container filesystem | Docker image | Rebuilt every image build |
|
||||
| OS packages | Container filesystem | Docker image | Do not install at runtime |
|
||||
| Docker container | Ephemeral | Restartable | Safe to destroy |
|
||||
|
||||
## Updates
|
||||
|
||||
To update OpenClaw on the VM:
|
||||
|
||||
```bash
|
||||
git pull
|
||||
docker compose build
|
||||
docker compose up -d
|
||||
```
|
||||
406
openclaw/docs/install/docker.md
Normal file
406
openclaw/docs/install/docker.md
Normal file
|
|
@ -0,0 +1,406 @@
|
|||
---
|
||||
summary: "Optional Docker-based setup and onboarding for OpenClaw"
|
||||
read_when:
|
||||
- You want a containerized gateway instead of local installs
|
||||
- You are validating the Docker flow
|
||||
title: "Docker"
|
||||
---
|
||||
|
||||
# Docker (optional)
|
||||
|
||||
Docker is **optional**. Use it only if you want a containerized gateway or to validate the Docker flow.
|
||||
|
||||
## Is Docker right for me?
|
||||
|
||||
- **Yes**: you want an isolated, throwaway gateway environment or to run OpenClaw on a host without local installs.
|
||||
- **No**: you are running on your own machine and just want the fastest dev loop. Use the normal install flow instead.
|
||||
- **Sandboxing note**: agent sandboxing uses Docker too, but it does **not** require the full gateway to run in Docker. See [Sandboxing](/gateway/sandboxing).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Docker Desktop (or Docker Engine) + Docker Compose v2
|
||||
- At least 2 GB RAM for image build (`pnpm install` may be OOM-killed on 1 GB hosts with exit 137)
|
||||
- Enough disk for images and logs
|
||||
- If running on a VPS/public host, review
|
||||
[Security hardening for network exposure](/gateway/security),
|
||||
especially Docker `DOCKER-USER` firewall policy.
|
||||
|
||||
## Containerized Gateway
|
||||
|
||||
<Steps>
|
||||
<Step title="Build the image">
|
||||
From the repo root, run the setup script:
|
||||
|
||||
```bash
|
||||
./scripts/docker/setup.sh
|
||||
```
|
||||
|
||||
This builds the gateway image locally. To use a pre-built image instead:
|
||||
|
||||
```bash
|
||||
export OPENCLAW_IMAGE="ghcr.io/openclaw/openclaw:latest"
|
||||
./scripts/docker/setup.sh
|
||||
```
|
||||
|
||||
Pre-built images are published at the
|
||||
[GitHub Container Registry](https://github.com/openclaw/openclaw/pkgs/container/openclaw).
|
||||
Common tags: `main`, `latest`, `<version>` (e.g. `2026.2.26`).
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Complete onboarding">
|
||||
The setup script runs onboarding automatically. It will:
|
||||
|
||||
- prompt for provider API keys
|
||||
- generate a gateway token and write it to `.env`
|
||||
- start the gateway via Docker Compose
|
||||
|
||||
During setup, pre-start onboarding and config writes run through
|
||||
`openclaw-gateway` directly. `openclaw-cli` is for commands you run after
|
||||
the gateway container already exists.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Open the Control UI">
|
||||
Open `http://127.0.0.1:18789/` in your browser and paste the configured
|
||||
shared secret into Settings. The setup script writes a token to `.env` by
|
||||
default; if you switch the container config to password auth, use that
|
||||
password instead.
|
||||
|
||||
Need the URL again?
|
||||
|
||||
```bash
|
||||
docker compose run --rm openclaw-cli dashboard --no-open
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Configure channels (optional)">
|
||||
Use the CLI container to add messaging channels:
|
||||
|
||||
```bash
|
||||
# WhatsApp (QR)
|
||||
docker compose run --rm openclaw-cli channels login
|
||||
|
||||
# Telegram
|
||||
docker compose run --rm openclaw-cli channels add --channel telegram --token "<token>"
|
||||
|
||||
# Discord
|
||||
docker compose run --rm openclaw-cli channels add --channel discord --token "<token>"
|
||||
```
|
||||
|
||||
Docs: [WhatsApp](/channels/whatsapp), [Telegram](/channels/telegram), [Discord](/channels/discord)
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
### Manual flow
|
||||
|
||||
If you prefer to run each step yourself instead of using the setup script:
|
||||
|
||||
```bash
|
||||
docker build -t openclaw:local -f Dockerfile .
|
||||
docker compose run --rm --no-deps --entrypoint node openclaw-gateway \
|
||||
dist/index.js onboard --mode local --no-install-daemon
|
||||
docker compose run --rm --no-deps --entrypoint node openclaw-gateway \
|
||||
dist/index.js config set --batch-json '[{"path":"gateway.mode","value":"local"},{"path":"gateway.bind","value":"lan"},{"path":"gateway.controlUi.allowedOrigins","value":["http://localhost:18789","http://127.0.0.1:18789"]}]'
|
||||
docker compose up -d openclaw-gateway
|
||||
```
|
||||
|
||||
<Note>
|
||||
Run `docker compose` from the repo root. If you enabled `OPENCLAW_EXTRA_MOUNTS`
|
||||
or `OPENCLAW_HOME_VOLUME`, the setup script writes `docker-compose.extra.yml`;
|
||||
include it with `-f docker-compose.yml -f docker-compose.extra.yml`.
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
Because `openclaw-cli` shares `openclaw-gateway`'s network namespace, it is a
|
||||
post-start tool. Before `docker compose up -d openclaw-gateway`, run onboarding
|
||||
and setup-time config writes through `openclaw-gateway` with
|
||||
`--no-deps --entrypoint node`.
|
||||
</Note>
|
||||
|
||||
### Environment variables
|
||||
|
||||
The setup script accepts these optional environment variables:
|
||||
|
||||
| Variable | Purpose |
|
||||
| ------------------------------ | ---------------------------------------------------------------- |
|
||||
| `OPENCLAW_IMAGE` | Use a remote image instead of building locally |
|
||||
| `OPENCLAW_DOCKER_APT_PACKAGES` | Install extra apt packages during build (space-separated) |
|
||||
| `OPENCLAW_EXTENSIONS` | Pre-install extension deps at build time (space-separated names) |
|
||||
| `OPENCLAW_EXTRA_MOUNTS` | Extra host bind mounts (comma-separated `source:target[:opts]`) |
|
||||
| `OPENCLAW_HOME_VOLUME` | Persist `/home/node` in a named Docker volume |
|
||||
| `OPENCLAW_SANDBOX` | Opt in to sandbox bootstrap (`1`, `true`, `yes`, `on`) |
|
||||
| `OPENCLAW_DOCKER_SOCKET` | Override Docker socket path |
|
||||
|
||||
### Health checks
|
||||
|
||||
Container probe endpoints (no auth required):
|
||||
|
||||
```bash
|
||||
curl -fsS http://127.0.0.1:18789/healthz # liveness
|
||||
curl -fsS http://127.0.0.1:18789/readyz # readiness
|
||||
```
|
||||
|
||||
The Docker image includes a built-in `HEALTHCHECK` that pings `/healthz`.
|
||||
If checks keep failing, Docker marks the container as `unhealthy` and
|
||||
orchestration systems can restart or replace it.
|
||||
|
||||
Authenticated deep health snapshot:
|
||||
|
||||
```bash
|
||||
docker compose exec openclaw-gateway node dist/index.js health --token "$OPENCLAW_GATEWAY_TOKEN"
|
||||
```
|
||||
|
||||
### LAN vs loopback
|
||||
|
||||
`scripts/docker/setup.sh` defaults `OPENCLAW_GATEWAY_BIND=lan` so host access to
|
||||
`http://127.0.0.1:18789` works with Docker port publishing.
|
||||
|
||||
- `lan` (default): host browser and host CLI can reach the published gateway port.
|
||||
- `loopback`: only processes inside the container network namespace can reach
|
||||
the gateway directly.
|
||||
|
||||
<Note>
|
||||
Use bind mode values in `gateway.bind` (`lan` / `loopback` / `custom` /
|
||||
`tailnet` / `auto`), not host aliases like `0.0.0.0` or `127.0.0.1`.
|
||||
</Note>
|
||||
|
||||
### Storage and persistence
|
||||
|
||||
Docker Compose bind-mounts `OPENCLAW_CONFIG_DIR` to `/home/node/.openclaw` and
|
||||
`OPENCLAW_WORKSPACE_DIR` to `/home/node/.openclaw/workspace`, so those paths
|
||||
survive container replacement.
|
||||
|
||||
That mounted config directory is where OpenClaw keeps:
|
||||
|
||||
- `openclaw.json` for behavior config
|
||||
- `agents/<agentId>/agent/auth-profiles.json` for stored provider OAuth/API-key auth
|
||||
- `.env` for env-backed runtime secrets such as `OPENCLAW_GATEWAY_TOKEN`
|
||||
|
||||
For full persistence details on VM deployments, see
|
||||
[Docker VM Runtime - What persists where](/install/docker-vm-runtime#what-persists-where).
|
||||
|
||||
**Disk growth hotspots:** watch `media/`, session JSONL files, `cron/runs/*.jsonl`,
|
||||
and rolling file logs under `/tmp/openclaw/`.
|
||||
|
||||
### Shell helpers (optional)
|
||||
|
||||
For easier day-to-day Docker management, install `ClawDock`:
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.clawdock && curl -sL https://raw.githubusercontent.com/openclaw/openclaw/main/scripts/clawdock/clawdock-helpers.sh -o ~/.clawdock/clawdock-helpers.sh
|
||||
echo 'source ~/.clawdock/clawdock-helpers.sh' >> ~/.zshrc && source ~/.zshrc
|
||||
```
|
||||
|
||||
If you installed ClawDock from the older `scripts/shell-helpers/clawdock-helpers.sh` raw path, rerun the install command above so your local helper file tracks the new location.
|
||||
|
||||
Then use `clawdock-start`, `clawdock-stop`, `clawdock-dashboard`, etc. Run
|
||||
`clawdock-help` for all commands.
|
||||
See [ClawDock](/install/clawdock) for the full helper guide.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Enable agent sandbox for Docker gateway">
|
||||
```bash
|
||||
export OPENCLAW_SANDBOX=1
|
||||
./scripts/docker/setup.sh
|
||||
```
|
||||
|
||||
Custom socket path (e.g. rootless Docker):
|
||||
|
||||
```bash
|
||||
export OPENCLAW_SANDBOX=1
|
||||
export OPENCLAW_DOCKER_SOCKET=/run/user/1000/docker.sock
|
||||
./scripts/docker/setup.sh
|
||||
```
|
||||
|
||||
The script mounts `docker.sock` only after sandbox prerequisites pass. If
|
||||
sandbox setup cannot complete, the script resets `agents.defaults.sandbox.mode`
|
||||
to `off`.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Automation / CI (non-interactive)">
|
||||
Disable Compose pseudo-TTY allocation with `-T`:
|
||||
|
||||
```bash
|
||||
docker compose run -T --rm openclaw-cli gateway probe
|
||||
docker compose run -T --rm openclaw-cli devices list --json
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Shared-network security note">
|
||||
`openclaw-cli` uses `network_mode: "service:openclaw-gateway"` so CLI
|
||||
commands can reach the gateway over `127.0.0.1`. Treat this as a shared
|
||||
trust boundary. The compose config drops `NET_RAW`/`NET_ADMIN` and enables
|
||||
`no-new-privileges` on `openclaw-cli`.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Permissions and EACCES">
|
||||
The image runs as `node` (uid 1000). If you see permission errors on
|
||||
`/home/node/.openclaw`, make sure your host bind mounts are owned by uid 1000:
|
||||
|
||||
```bash
|
||||
sudo chown -R 1000:1000 /path/to/openclaw-config /path/to/openclaw-workspace
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Faster rebuilds">
|
||||
Order your Dockerfile so dependency layers are cached. This avoids re-running
|
||||
`pnpm install` unless lockfiles change:
|
||||
|
||||
```dockerfile
|
||||
FROM node:24-bookworm
|
||||
RUN curl -fsSL https://bun.sh/install | bash
|
||||
ENV PATH="/root/.bun/bin:${PATH}"
|
||||
RUN corepack enable
|
||||
WORKDIR /app
|
||||
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
|
||||
COPY ui/package.json ./ui/package.json
|
||||
COPY scripts ./scripts
|
||||
RUN pnpm install --frozen-lockfile
|
||||
COPY . .
|
||||
RUN pnpm build
|
||||
RUN pnpm ui:install
|
||||
RUN pnpm ui:build
|
||||
ENV NODE_ENV=production
|
||||
CMD ["node","dist/index.js"]
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Power-user container options">
|
||||
The default image is security-first and runs as non-root `node`. For a more
|
||||
full-featured container:
|
||||
|
||||
1. **Persist `/home/node`**: `export OPENCLAW_HOME_VOLUME="openclaw_home"`
|
||||
2. **Bake system deps**: `export OPENCLAW_DOCKER_APT_PACKAGES="git curl jq"`
|
||||
3. **Install Playwright browsers**:
|
||||
```bash
|
||||
docker compose run --rm openclaw-cli \
|
||||
node /app/node_modules/playwright-core/cli.js install chromium
|
||||
```
|
||||
4. **Persist browser downloads**: set
|
||||
`PLAYWRIGHT_BROWSERS_PATH=/home/node/.cache/ms-playwright` and use
|
||||
`OPENCLAW_HOME_VOLUME` or `OPENCLAW_EXTRA_MOUNTS`.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="OpenAI Codex OAuth (headless Docker)">
|
||||
If you pick OpenAI Codex OAuth in the wizard, it opens a browser URL. In
|
||||
Docker or headless setups, copy the full redirect URL you land on and paste
|
||||
it back into the wizard to finish auth.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Base image metadata">
|
||||
The main Docker image uses `node:24-bookworm` and publishes OCI base-image
|
||||
annotations including `org.opencontainers.image.base.name`,
|
||||
`org.opencontainers.image.source`, and others. See
|
||||
[OCI image annotations](https://github.com/opencontainers/image-spec/blob/main/annotations.md).
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
### Running on a VPS?
|
||||
|
||||
See [Hetzner (Docker VPS)](/install/hetzner) and
|
||||
[Docker VM Runtime](/install/docker-vm-runtime) for shared VM deployment steps
|
||||
including binary baking, persistence, and updates.
|
||||
|
||||
## Agent Sandbox
|
||||
|
||||
When `agents.defaults.sandbox` is enabled, the gateway runs agent tool execution
|
||||
(shell, file read/write, etc.) inside isolated Docker containers while the
|
||||
gateway itself stays on the host. This gives you a hard wall around untrusted or
|
||||
multi-tenant agent sessions without containerizing the entire gateway.
|
||||
|
||||
Sandbox scope can be per-agent (default), per-session, or shared. Each scope
|
||||
gets its own workspace mounted at `/workspace`. You can also configure
|
||||
allow/deny tool policies, network isolation, resource limits, and browser
|
||||
containers.
|
||||
|
||||
For full configuration, images, security notes, and multi-agent profiles, see:
|
||||
|
||||
- [Sandboxing](/gateway/sandboxing) -- complete sandbox reference
|
||||
- [OpenShell](/gateway/openshell) -- interactive shell access to sandbox containers
|
||||
- [Multi-Agent Sandbox and Tools](/tools/multi-agent-sandbox-tools) -- per-agent overrides
|
||||
|
||||
### Quick enable
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
sandbox: {
|
||||
mode: "non-main", // off | non-main | all
|
||||
scope: "agent", // session | agent | shared
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Build the default sandbox image:
|
||||
|
||||
```bash
|
||||
scripts/sandbox-setup.sh
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Image missing or sandbox container not starting">
|
||||
Build the sandbox image with
|
||||
[`scripts/sandbox-setup.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/sandbox-setup.sh)
|
||||
or set `agents.defaults.sandbox.docker.image` to your custom image.
|
||||
Containers are auto-created per session on demand.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Permission errors in sandbox">
|
||||
Set `docker.user` to a UID:GID that matches your mounted workspace ownership,
|
||||
or chown the workspace folder.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Custom tools not found in sandbox">
|
||||
OpenClaw runs commands with `sh -lc` (login shell), which sources
|
||||
`/etc/profile` and may reset PATH. Set `docker.env.PATH` to prepend your
|
||||
custom tool paths, or add a script under `/etc/profile.d/` in your Dockerfile.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="OOM-killed during image build (exit 137)">
|
||||
The VM needs at least 2 GB RAM. Use a larger machine class and retry.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Unauthorized or pairing required in Control UI">
|
||||
Fetch a fresh dashboard link and approve the browser device:
|
||||
|
||||
```bash
|
||||
docker compose run --rm openclaw-cli dashboard --no-open
|
||||
docker compose run --rm openclaw-cli devices list
|
||||
docker compose run --rm openclaw-cli devices approve <requestId>
|
||||
```
|
||||
|
||||
More detail: [Dashboard](/web/dashboard), [Devices](/cli/devices).
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Gateway target shows ws://172.x.x.x or pairing errors from Docker CLI">
|
||||
Reset gateway mode and bind:
|
||||
|
||||
```bash
|
||||
docker compose run --rm openclaw-cli config set --batch-json '[{"path":"gateway.mode","value":"local"},{"path":"gateway.bind","value":"lan"}]'
|
||||
docker compose run --rm openclaw-cli devices list --url ws://127.0.0.1:18789
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Related
|
||||
|
||||
- [Install Overview](/install) — all installation methods
|
||||
- [Podman](/install/podman) — Podman alternative to Docker
|
||||
- [ClawDock](/install/clawdock) — Docker Compose community setup
|
||||
- [Updating](/install/updating) — keeping OpenClaw up to date
|
||||
- [Configuration](/gateway/configuration) — gateway configuration after install
|
||||
133
openclaw/docs/install/exe-dev.md
Normal file
133
openclaw/docs/install/exe-dev.md
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
---
|
||||
summary: "Run OpenClaw Gateway on exe.dev (VM + HTTPS proxy) for remote access"
|
||||
read_when:
|
||||
- You want a cheap always-on Linux host for the Gateway
|
||||
- You want remote Control UI access without running your own VPS
|
||||
title: "exe.dev"
|
||||
---
|
||||
|
||||
# exe.dev
|
||||
|
||||
Goal: OpenClaw Gateway running on an exe.dev VM, reachable from your laptop via: `https://<vm-name>.exe.xyz`
|
||||
|
||||
This page assumes exe.dev's default **exeuntu** image. If you picked a different distro, map packages accordingly.
|
||||
|
||||
## Beginner quick path
|
||||
|
||||
1. [https://exe.new/openclaw](https://exe.new/openclaw)
|
||||
2. Fill in your auth key/token as needed
|
||||
3. Click on "Agent" next to your VM and wait for Shelley to finish provisioning
|
||||
4. Open `https://<vm-name>.exe.xyz/` and authenticate with the configured shared secret (this guide uses token auth by default, but password auth works too if you switch `gateway.auth.mode`)
|
||||
5. Approve any pending device pairing requests with `openclaw devices approve <requestId>`
|
||||
|
||||
## What you need
|
||||
|
||||
- exe.dev account
|
||||
- `ssh exe.dev` access to [exe.dev](https://exe.dev) virtual machines (optional)
|
||||
|
||||
## Automated Install with Shelley
|
||||
|
||||
Shelley, [exe.dev](https://exe.dev)'s agent, can install OpenClaw instantly with our
|
||||
prompt. The prompt used is as below:
|
||||
|
||||
```
|
||||
Set up OpenClaw (https://docs.openclaw.ai/install) on this VM. Use the non-interactive and accept-risk flags for openclaw onboarding. Add the supplied auth or token as needed. Configure nginx to forward from the default port 18789 to the root location on the default enabled site config, making sure to enable Websocket support. Pairing is done by "openclaw devices list" and "openclaw devices approve <request id>". Make sure the dashboard shows that OpenClaw's health is OK. exe.dev handles forwarding from port 8000 to port 80/443 and HTTPS for us, so the final "reachable" should be <vm-name>.exe.xyz, without port specification.
|
||||
```
|
||||
|
||||
## Manual installation
|
||||
|
||||
## 1) Create the VM
|
||||
|
||||
From your device:
|
||||
|
||||
```bash
|
||||
ssh exe.dev new
|
||||
```
|
||||
|
||||
Then connect:
|
||||
|
||||
```bash
|
||||
ssh <vm-name>.exe.xyz
|
||||
```
|
||||
|
||||
Tip: keep this VM **stateful**. OpenClaw stores `openclaw.json`, per-agent
|
||||
`auth-profiles.json`, sessions, and channel/provider state under
|
||||
`~/.openclaw/`, plus the workspace under `~/.openclaw/workspace/`.
|
||||
|
||||
## 2) Install prerequisites (on the VM)
|
||||
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y git curl jq ca-certificates openssl
|
||||
```
|
||||
|
||||
## 3) Install OpenClaw
|
||||
|
||||
Run the OpenClaw install script:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://openclaw.ai/install.sh | bash
|
||||
```
|
||||
|
||||
## 4) Setup nginx to proxy OpenClaw to port 8000
|
||||
|
||||
Edit `/etc/nginx/sites-enabled/default` with
|
||||
|
||||
```
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
listen 8000;
|
||||
listen [::]:8000;
|
||||
|
||||
server_name _;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:18789;
|
||||
proxy_http_version 1.1;
|
||||
|
||||
# WebSocket support
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
# Standard proxy headers
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# Timeout settings for long-lived connections
|
||||
proxy_read_timeout 86400s;
|
||||
proxy_send_timeout 86400s;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Overwrite forwarding headers instead of preserving client-supplied chains.
|
||||
OpenClaw trusts forwarded IP metadata only from explicitly configured proxies,
|
||||
and append-style `X-Forwarded-For` chains are treated as a hardening risk.
|
||||
|
||||
## 5) Access OpenClaw and grant privileges
|
||||
|
||||
Access `https://<vm-name>.exe.xyz/` (see the Control UI output from onboarding). If it prompts for auth, paste the
|
||||
configured shared secret from the VM. This guide uses token auth, so retrieve `gateway.auth.token`
|
||||
with `openclaw config get gateway.auth.token` (or generate one with `openclaw doctor --generate-gateway-token`).
|
||||
If you changed the gateway to password auth, use `gateway.auth.password` / `OPENCLAW_GATEWAY_PASSWORD` instead.
|
||||
Approve devices with `openclaw devices list` and `openclaw devices approve <requestId>`. When in doubt, use Shelley from your browser!
|
||||
|
||||
## Remote Access
|
||||
|
||||
Remote access is handled by [exe.dev](https://exe.dev)'s authentication. By
|
||||
default, HTTP traffic from port 8000 is forwarded to `https://<vm-name>.exe.xyz`
|
||||
with email auth.
|
||||
|
||||
## Updating
|
||||
|
||||
```bash
|
||||
npm i -g openclaw@latest
|
||||
openclaw doctor
|
||||
openclaw gateway restart
|
||||
openclaw health
|
||||
```
|
||||
|
||||
Guide: [Updating](/install/updating)
|
||||
504
openclaw/docs/install/fly.md
Normal file
504
openclaw/docs/install/fly.md
Normal file
|
|
@ -0,0 +1,504 @@
|
|||
---
|
||||
title: Fly.io
|
||||
summary: "Step-by-step Fly.io deployment for OpenClaw with persistent storage and HTTPS"
|
||||
read_when:
|
||||
- Deploying OpenClaw on Fly.io
|
||||
- Setting up Fly volumes, secrets, and first-run config
|
||||
---
|
||||
|
||||
# Fly.io Deployment
|
||||
|
||||
**Goal:** OpenClaw Gateway running on a [Fly.io](https://fly.io) machine with persistent storage, automatic HTTPS, and Discord/channel access.
|
||||
|
||||
## What you need
|
||||
|
||||
- [flyctl CLI](https://fly.io/docs/hands-on/install-flyctl/) installed
|
||||
- Fly.io account (free tier works)
|
||||
- Model auth: API key for your chosen model provider
|
||||
- Channel credentials: Discord bot token, Telegram token, etc.
|
||||
|
||||
## Beginner quick path
|
||||
|
||||
1. Clone repo → customize `fly.toml`
|
||||
2. Create app + volume → set secrets
|
||||
3. Deploy with `fly deploy`
|
||||
4. SSH in to create config or use Control UI
|
||||
|
||||
<Steps>
|
||||
<Step title="Create the Fly app">
|
||||
```bash
|
||||
# Clone the repo
|
||||
git clone https://github.com/openclaw/openclaw.git
|
||||
cd openclaw
|
||||
|
||||
# Create a new Fly app (pick your own name)
|
||||
fly apps create my-openclaw
|
||||
|
||||
# Create a persistent volume (1GB is usually enough)
|
||||
fly volumes create openclaw_data --size 1 --region iad
|
||||
```
|
||||
|
||||
**Tip:** Choose a region close to you. Common options: `lhr` (London), `iad` (Virginia), `sjc` (San Jose).
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Configure fly.toml">
|
||||
Edit `fly.toml` to match your app name and requirements.
|
||||
|
||||
**Security note:** The default config exposes a public URL. For a hardened deployment with no public IP, see [Private Deployment](#private-deployment-hardened) or use `fly.private.toml`.
|
||||
|
||||
```toml
|
||||
app = "my-openclaw" # Your app name
|
||||
primary_region = "iad"
|
||||
|
||||
[build]
|
||||
dockerfile = "Dockerfile"
|
||||
|
||||
[env]
|
||||
NODE_ENV = "production"
|
||||
OPENCLAW_PREFER_PNPM = "1"
|
||||
OPENCLAW_STATE_DIR = "/data"
|
||||
NODE_OPTIONS = "--max-old-space-size=1536"
|
||||
|
||||
[processes]
|
||||
app = "node dist/index.js gateway --allow-unconfigured --port 3000 --bind lan"
|
||||
|
||||
[http_service]
|
||||
internal_port = 3000
|
||||
force_https = true
|
||||
auto_stop_machines = false
|
||||
auto_start_machines = true
|
||||
min_machines_running = 1
|
||||
processes = ["app"]
|
||||
|
||||
[[vm]]
|
||||
size = "shared-cpu-2x"
|
||||
memory = "2048mb"
|
||||
|
||||
[mounts]
|
||||
source = "openclaw_data"
|
||||
destination = "/data"
|
||||
```
|
||||
|
||||
**Key settings:**
|
||||
|
||||
| Setting | Why |
|
||||
| ------------------------------ | --------------------------------------------------------------------------- |
|
||||
| `--bind lan` | Binds to `0.0.0.0` so Fly's proxy can reach the gateway |
|
||||
| `--allow-unconfigured` | Starts without a config file (you'll create one after) |
|
||||
| `internal_port = 3000` | Must match `--port 3000` (or `OPENCLAW_GATEWAY_PORT`) for Fly health checks |
|
||||
| `memory = "2048mb"` | 512MB is too small; 2GB recommended |
|
||||
| `OPENCLAW_STATE_DIR = "/data"` | Persists state on the volume |
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Set secrets">
|
||||
```bash
|
||||
# Required: Gateway token (for non-loopback binding)
|
||||
fly secrets set OPENCLAW_GATEWAY_TOKEN=$(openssl rand -hex 32)
|
||||
|
||||
# Model provider API keys
|
||||
fly secrets set ANTHROPIC_API_KEY=sk-ant-...
|
||||
|
||||
# Optional: Other providers
|
||||
fly secrets set OPENAI_API_KEY=sk-...
|
||||
fly secrets set GOOGLE_API_KEY=...
|
||||
|
||||
# Channel tokens
|
||||
fly secrets set DISCORD_BOT_TOKEN=MTQ...
|
||||
```
|
||||
|
||||
**Notes:**
|
||||
|
||||
- Non-loopback binds (`--bind lan`) require a valid gateway auth path. This Fly.io example uses `OPENCLAW_GATEWAY_TOKEN`, but `gateway.auth.password` or a correctly configured non-loopback `trusted-proxy` deployment also satisfy the requirement.
|
||||
- Treat these tokens like passwords.
|
||||
- **Prefer env vars over config file** for all API keys and tokens. This keeps secrets out of `openclaw.json` where they could be accidentally exposed or logged.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Deploy">
|
||||
```bash
|
||||
fly deploy
|
||||
```
|
||||
|
||||
First deploy builds the Docker image (~2-3 minutes). Subsequent deploys are faster.
|
||||
|
||||
After deployment, verify:
|
||||
|
||||
```bash
|
||||
fly status
|
||||
fly logs
|
||||
```
|
||||
|
||||
You should see:
|
||||
|
||||
```
|
||||
[gateway] listening on ws://0.0.0.0:3000 (PID xxx)
|
||||
[discord] logged in to discord as xxx
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Create config file">
|
||||
SSH into the machine to create a proper config:
|
||||
|
||||
```bash
|
||||
fly ssh console
|
||||
```
|
||||
|
||||
Create the config directory and file:
|
||||
|
||||
```bash
|
||||
mkdir -p /data
|
||||
cat > /data/openclaw.json << 'EOF'
|
||||
{
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": {
|
||||
"primary": "anthropic/claude-opus-4-6",
|
||||
"fallbacks": ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4"]
|
||||
},
|
||||
"maxConcurrent": 4
|
||||
},
|
||||
"list": [
|
||||
{
|
||||
"id": "main",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"auth": {
|
||||
"profiles": {
|
||||
"anthropic:default": { "mode": "token", "provider": "anthropic" },
|
||||
"openai:default": { "mode": "token", "provider": "openai" }
|
||||
}
|
||||
},
|
||||
"bindings": [
|
||||
{
|
||||
"agentId": "main",
|
||||
"match": { "channel": "discord" }
|
||||
}
|
||||
],
|
||||
"channels": {
|
||||
"discord": {
|
||||
"enabled": true,
|
||||
"groupPolicy": "allowlist",
|
||||
"guilds": {
|
||||
"YOUR_GUILD_ID": {
|
||||
"channels": { "general": { "allow": true } },
|
||||
"requireMention": false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"gateway": {
|
||||
"mode": "local",
|
||||
"bind": "auto"
|
||||
},
|
||||
"meta": {}
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
**Note:** With `OPENCLAW_STATE_DIR=/data`, the config path is `/data/openclaw.json`.
|
||||
|
||||
**Note:** The Discord token can come from either:
|
||||
|
||||
- Environment variable: `DISCORD_BOT_TOKEN` (recommended for secrets)
|
||||
- Config file: `channels.discord.token`
|
||||
|
||||
If using env var, no need to add token to config. The gateway reads `DISCORD_BOT_TOKEN` automatically.
|
||||
|
||||
Restart to apply:
|
||||
|
||||
```bash
|
||||
exit
|
||||
fly machine restart <machine-id>
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Access the Gateway">
|
||||
### Control UI
|
||||
|
||||
Open in browser:
|
||||
|
||||
```bash
|
||||
fly open
|
||||
```
|
||||
|
||||
Or visit `https://my-openclaw.fly.dev/`
|
||||
|
||||
Authenticate with the configured shared secret. This guide uses the gateway
|
||||
token from `OPENCLAW_GATEWAY_TOKEN`; if you switched to password auth, use
|
||||
that password instead.
|
||||
|
||||
### Logs
|
||||
|
||||
```bash
|
||||
fly logs # Live logs
|
||||
fly logs --no-tail # Recent logs
|
||||
```
|
||||
|
||||
### SSH Console
|
||||
|
||||
```bash
|
||||
fly ssh console
|
||||
```
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "App is not listening on expected address"
|
||||
|
||||
The gateway is binding to `127.0.0.1` instead of `0.0.0.0`.
|
||||
|
||||
**Fix:** Add `--bind lan` to your process command in `fly.toml`.
|
||||
|
||||
### Health checks failing / connection refused
|
||||
|
||||
Fly can't reach the gateway on the configured port.
|
||||
|
||||
**Fix:** Ensure `internal_port` matches the gateway port (set `--port 3000` or `OPENCLAW_GATEWAY_PORT=3000`).
|
||||
|
||||
### OOM / Memory Issues
|
||||
|
||||
Container keeps restarting or getting killed. Signs: `SIGABRT`, `v8::internal::Runtime_AllocateInYoungGeneration`, or silent restarts.
|
||||
|
||||
**Fix:** Increase memory in `fly.toml`:
|
||||
|
||||
```toml
|
||||
[[vm]]
|
||||
memory = "2048mb"
|
||||
```
|
||||
|
||||
Or update an existing machine:
|
||||
|
||||
```bash
|
||||
fly machine update <machine-id> --vm-memory 2048 -y
|
||||
```
|
||||
|
||||
**Note:** 512MB is too small. 1GB may work but can OOM under load or with verbose logging. **2GB is recommended.**
|
||||
|
||||
### Gateway Lock Issues
|
||||
|
||||
Gateway refuses to start with "already running" errors.
|
||||
|
||||
This happens when the container restarts but the PID lock file persists on the volume.
|
||||
|
||||
**Fix:** Delete the lock file:
|
||||
|
||||
```bash
|
||||
fly ssh console --command "rm -f /data/gateway.*.lock"
|
||||
fly machine restart <machine-id>
|
||||
```
|
||||
|
||||
The lock file is at `/data/gateway.*.lock` (not in a subdirectory).
|
||||
|
||||
### Config Not Being Read
|
||||
|
||||
`--allow-unconfigured` only bypasses the startup guard. It does not create or repair `/data/openclaw.json`, so make sure your real config exists and includes `gateway.mode="local"` when you want a normal local gateway start.
|
||||
|
||||
Verify the config exists:
|
||||
|
||||
```bash
|
||||
fly ssh console --command "cat /data/openclaw.json"
|
||||
```
|
||||
|
||||
### Writing Config via SSH
|
||||
|
||||
The `fly ssh console -C` command doesn't support shell redirection. To write a config file:
|
||||
|
||||
```bash
|
||||
# Use echo + tee (pipe from local to remote)
|
||||
echo '{"your":"config"}' | fly ssh console -C "tee /data/openclaw.json"
|
||||
|
||||
# Or use sftp
|
||||
fly sftp shell
|
||||
> put /local/path/config.json /data/openclaw.json
|
||||
```
|
||||
|
||||
**Note:** `fly sftp` may fail if the file already exists. Delete first:
|
||||
|
||||
```bash
|
||||
fly ssh console --command "rm /data/openclaw.json"
|
||||
```
|
||||
|
||||
### State Not Persisting
|
||||
|
||||
If you lose auth profiles, channel/provider state, or sessions after a restart,
|
||||
the state dir is writing to the container filesystem.
|
||||
|
||||
**Fix:** Ensure `OPENCLAW_STATE_DIR=/data` is set in `fly.toml` and redeploy.
|
||||
|
||||
## Updates
|
||||
|
||||
```bash
|
||||
# Pull latest changes
|
||||
git pull
|
||||
|
||||
# Redeploy
|
||||
fly deploy
|
||||
|
||||
# Check health
|
||||
fly status
|
||||
fly logs
|
||||
```
|
||||
|
||||
### Updating Machine Command
|
||||
|
||||
If you need to change the startup command without a full redeploy:
|
||||
|
||||
```bash
|
||||
# Get machine ID
|
||||
fly machines list
|
||||
|
||||
# Update command
|
||||
fly machine update <machine-id> --command "node dist/index.js gateway --port 3000 --bind lan" -y
|
||||
|
||||
# Or with memory increase
|
||||
fly machine update <machine-id> --vm-memory 2048 --command "node dist/index.js gateway --port 3000 --bind lan" -y
|
||||
```
|
||||
|
||||
**Note:** After `fly deploy`, the machine command may reset to what's in `fly.toml`. If you made manual changes, re-apply them after deploy.
|
||||
|
||||
## Private Deployment (Hardened)
|
||||
|
||||
By default, Fly allocates public IPs, making your gateway accessible at `https://your-app.fly.dev`. This is convenient but means your deployment is discoverable by internet scanners (Shodan, Censys, etc.).
|
||||
|
||||
For a hardened deployment with **no public exposure**, use the private template.
|
||||
|
||||
### When to use private deployment
|
||||
|
||||
- You only make **outbound** calls/messages (no inbound webhooks)
|
||||
- You use **ngrok or Tailscale** tunnels for any webhook callbacks
|
||||
- You access the gateway via **SSH, proxy, or WireGuard** instead of browser
|
||||
- You want the deployment **hidden from internet scanners**
|
||||
|
||||
### Setup
|
||||
|
||||
Use `fly.private.toml` instead of the standard config:
|
||||
|
||||
```bash
|
||||
# Deploy with private config
|
||||
fly deploy -c fly.private.toml
|
||||
```
|
||||
|
||||
Or convert an existing deployment:
|
||||
|
||||
```bash
|
||||
# List current IPs
|
||||
fly ips list -a my-openclaw
|
||||
|
||||
# Release public IPs
|
||||
fly ips release <public-ipv4> -a my-openclaw
|
||||
fly ips release <public-ipv6> -a my-openclaw
|
||||
|
||||
# Switch to private config so future deploys don't re-allocate public IPs
|
||||
# (remove [http_service] or deploy with the private template)
|
||||
fly deploy -c fly.private.toml
|
||||
|
||||
# Allocate private-only IPv6
|
||||
fly ips allocate-v6 --private -a my-openclaw
|
||||
```
|
||||
|
||||
After this, `fly ips list` should show only a `private` type IP:
|
||||
|
||||
```
|
||||
VERSION IP TYPE REGION
|
||||
v6 fdaa:x:x:x:x::x private global
|
||||
```
|
||||
|
||||
### Accessing a private deployment
|
||||
|
||||
Since there's no public URL, use one of these methods:
|
||||
|
||||
**Option 1: Local proxy (simplest)**
|
||||
|
||||
```bash
|
||||
# Forward local port 3000 to the app
|
||||
fly proxy 3000:3000 -a my-openclaw
|
||||
|
||||
# Then open http://localhost:3000 in browser
|
||||
```
|
||||
|
||||
**Option 2: WireGuard VPN**
|
||||
|
||||
```bash
|
||||
# Create WireGuard config (one-time)
|
||||
fly wireguard create
|
||||
|
||||
# Import to WireGuard client, then access via internal IPv6
|
||||
# Example: http://[fdaa:x:x:x:x::x]:3000
|
||||
```
|
||||
|
||||
**Option 3: SSH only**
|
||||
|
||||
```bash
|
||||
fly ssh console -a my-openclaw
|
||||
```
|
||||
|
||||
### Webhooks with private deployment
|
||||
|
||||
If you need webhook callbacks (Twilio, Telnyx, etc.) without public exposure:
|
||||
|
||||
1. **ngrok tunnel** - Run ngrok inside the container or as a sidecar
|
||||
2. **Tailscale Funnel** - Expose specific paths via Tailscale
|
||||
3. **Outbound-only** - Some providers (Twilio) work fine for outbound calls without webhooks
|
||||
|
||||
Example voice-call config with ngrok:
|
||||
|
||||
```json5
|
||||
{
|
||||
plugins: {
|
||||
entries: {
|
||||
"voice-call": {
|
||||
enabled: true,
|
||||
config: {
|
||||
provider: "twilio",
|
||||
tunnel: { provider: "ngrok" },
|
||||
webhookSecurity: {
|
||||
allowedHosts: ["example.ngrok.app"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
The ngrok tunnel runs inside the container and provides a public webhook URL without exposing the Fly app itself. Set `webhookSecurity.allowedHosts` to the public tunnel hostname so forwarded host headers are accepted.
|
||||
|
||||
### Security benefits
|
||||
|
||||
| Aspect | Public | Private |
|
||||
| ----------------- | ------------ | ---------- |
|
||||
| Internet scanners | Discoverable | Hidden |
|
||||
| Direct attacks | Possible | Blocked |
|
||||
| Control UI access | Browser | Proxy/VPN |
|
||||
| Webhook delivery | Direct | Via tunnel |
|
||||
|
||||
## Notes
|
||||
|
||||
- Fly.io uses **x86 architecture** (not ARM)
|
||||
- The Dockerfile is compatible with both architectures
|
||||
- For WhatsApp/Telegram onboarding, use `fly ssh console`
|
||||
- Persistent data lives on the volume at `/data`
|
||||
- Signal requires Java + signal-cli; use a custom image and keep memory at 2GB+.
|
||||
|
||||
## Cost
|
||||
|
||||
With the recommended config (`shared-cpu-2x`, 2GB RAM):
|
||||
|
||||
- ~$10-15/month depending on usage
|
||||
- Free tier includes some allowance
|
||||
|
||||
See [Fly.io pricing](https://fly.io/docs/about/pricing/) for details.
|
||||
|
||||
## Next steps
|
||||
|
||||
- Set up messaging channels: [Channels](/channels)
|
||||
- Configure the Gateway: [Gateway configuration](/gateway/configuration)
|
||||
- Keep OpenClaw up to date: [Updating](/install/updating)
|
||||
415
openclaw/docs/install/gcp.md
Normal file
415
openclaw/docs/install/gcp.md
Normal file
|
|
@ -0,0 +1,415 @@
|
|||
---
|
||||
summary: "Run OpenClaw Gateway 24/7 on a GCP Compute Engine VM (Docker) with durable state"
|
||||
read_when:
|
||||
- You want OpenClaw running 24/7 on GCP
|
||||
- You want a production-grade, always-on Gateway on your own VM
|
||||
- You want full control over persistence, binaries, and restart behavior
|
||||
title: "GCP"
|
||||
---
|
||||
|
||||
# OpenClaw on GCP Compute Engine (Docker, Production VPS Guide)
|
||||
|
||||
## Goal
|
||||
|
||||
Run a persistent OpenClaw Gateway on a GCP Compute Engine VM using Docker, with durable state, baked-in binaries, and safe restart behavior.
|
||||
|
||||
If you want "OpenClaw 24/7 for ~$5-12/mo", this is a reliable setup on Google Cloud.
|
||||
Pricing varies by machine type and region; pick the smallest VM that fits your workload and scale up if you hit OOMs.
|
||||
|
||||
## What are we doing (simple terms)?
|
||||
|
||||
- Create a GCP project and enable billing
|
||||
- Create a Compute Engine VM
|
||||
- Install Docker (isolated app runtime)
|
||||
- Start the OpenClaw Gateway in Docker
|
||||
- Persist `~/.openclaw` + `~/.openclaw/workspace` on the host (survives restarts/rebuilds)
|
||||
- Access the Control UI from your laptop via an SSH tunnel
|
||||
|
||||
That mounted `~/.openclaw` state includes `openclaw.json`, per-agent
|
||||
`agents/<agentId>/agent/auth-profiles.json`, and `.env`.
|
||||
|
||||
The Gateway can be accessed via:
|
||||
|
||||
- SSH port forwarding from your laptop
|
||||
- Direct port exposure if you manage firewalling and tokens yourself
|
||||
|
||||
This guide uses Debian on GCP Compute Engine.
|
||||
Ubuntu also works; map packages accordingly.
|
||||
For the generic Docker flow, see [Docker](/install/docker).
|
||||
|
||||
---
|
||||
|
||||
## Quick path (experienced operators)
|
||||
|
||||
1. Create GCP project + enable Compute Engine API
|
||||
2. Create Compute Engine VM (e2-small, Debian 12, 20GB)
|
||||
3. SSH into the VM
|
||||
4. Install Docker
|
||||
5. Clone OpenClaw repository
|
||||
6. Create persistent host directories
|
||||
7. Configure `.env` and `docker-compose.yml`
|
||||
8. Bake required binaries, build, and launch
|
||||
|
||||
---
|
||||
|
||||
## What you need
|
||||
|
||||
- GCP account (free tier eligible for e2-micro)
|
||||
- gcloud CLI installed (or use Cloud Console)
|
||||
- SSH access from your laptop
|
||||
- Basic comfort with SSH + copy/paste
|
||||
- ~20-30 minutes
|
||||
- Docker and Docker Compose
|
||||
- Model auth credentials
|
||||
- Optional provider credentials
|
||||
- WhatsApp QR
|
||||
- Telegram bot token
|
||||
- Gmail OAuth
|
||||
|
||||
---
|
||||
|
||||
<Steps>
|
||||
<Step title="Install gcloud CLI (or use Console)">
|
||||
**Option A: gcloud CLI** (recommended for automation)
|
||||
|
||||
Install from [https://cloud.google.com/sdk/docs/install](https://cloud.google.com/sdk/docs/install)
|
||||
|
||||
Initialize and authenticate:
|
||||
|
||||
```bash
|
||||
gcloud init
|
||||
gcloud auth login
|
||||
```
|
||||
|
||||
**Option B: Cloud Console**
|
||||
|
||||
All steps can be done via the web UI at [https://console.cloud.google.com](https://console.cloud.google.com)
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Create a GCP project">
|
||||
**CLI:**
|
||||
|
||||
```bash
|
||||
gcloud projects create my-openclaw-project --name="OpenClaw Gateway"
|
||||
gcloud config set project my-openclaw-project
|
||||
```
|
||||
|
||||
Enable billing at [https://console.cloud.google.com/billing](https://console.cloud.google.com/billing) (required for Compute Engine).
|
||||
|
||||
Enable the Compute Engine API:
|
||||
|
||||
```bash
|
||||
gcloud services enable compute.googleapis.com
|
||||
```
|
||||
|
||||
**Console:**
|
||||
|
||||
1. Go to IAM & Admin > Create Project
|
||||
2. Name it and create
|
||||
3. Enable billing for the project
|
||||
4. Navigate to APIs & Services > Enable APIs > search "Compute Engine API" > Enable
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Create the VM">
|
||||
**Machine types:**
|
||||
|
||||
| Type | Specs | Cost | Notes |
|
||||
| --------- | ------------------------ | ------------------ | -------------------------------------------- |
|
||||
| e2-medium | 2 vCPU, 4GB RAM | ~$25/mo | Most reliable for local Docker builds |
|
||||
| e2-small | 2 vCPU, 2GB RAM | ~$12/mo | Minimum recommended for Docker build |
|
||||
| e2-micro | 2 vCPU (shared), 1GB RAM | Free tier eligible | Often fails with Docker build OOM (exit 137) |
|
||||
|
||||
**CLI:**
|
||||
|
||||
```bash
|
||||
gcloud compute instances create openclaw-gateway \
|
||||
--zone=us-central1-a \
|
||||
--machine-type=e2-small \
|
||||
--boot-disk-size=20GB \
|
||||
--image-family=debian-12 \
|
||||
--image-project=debian-cloud
|
||||
```
|
||||
|
||||
**Console:**
|
||||
|
||||
1. Go to Compute Engine > VM instances > Create instance
|
||||
2. Name: `openclaw-gateway`
|
||||
3. Region: `us-central1`, Zone: `us-central1-a`
|
||||
4. Machine type: `e2-small`
|
||||
5. Boot disk: Debian 12, 20GB
|
||||
6. Create
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="SSH into the VM">
|
||||
**CLI:**
|
||||
|
||||
```bash
|
||||
gcloud compute ssh openclaw-gateway --zone=us-central1-a
|
||||
```
|
||||
|
||||
**Console:**
|
||||
|
||||
Click the "SSH" button next to your VM in the Compute Engine dashboard.
|
||||
|
||||
Note: SSH key propagation can take 1-2 minutes after VM creation. If connection is refused, wait and retry.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Install Docker (on the VM)">
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y git curl ca-certificates
|
||||
curl -fsSL https://get.docker.com | sudo sh
|
||||
sudo usermod -aG docker $USER
|
||||
```
|
||||
|
||||
Log out and back in for the group change to take effect:
|
||||
|
||||
```bash
|
||||
exit
|
||||
```
|
||||
|
||||
Then SSH back in:
|
||||
|
||||
```bash
|
||||
gcloud compute ssh openclaw-gateway --zone=us-central1-a
|
||||
```
|
||||
|
||||
Verify:
|
||||
|
||||
```bash
|
||||
docker --version
|
||||
docker compose version
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Clone the OpenClaw repository">
|
||||
```bash
|
||||
git clone https://github.com/openclaw/openclaw.git
|
||||
cd openclaw
|
||||
```
|
||||
|
||||
This guide assumes you will build a custom image to guarantee binary persistence.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Create persistent host directories">
|
||||
Docker containers are ephemeral.
|
||||
All long-lived state must live on the host.
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.openclaw
|
||||
mkdir -p ~/.openclaw/workspace
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Configure environment variables">
|
||||
Create `.env` in the repository root.
|
||||
|
||||
```bash
|
||||
OPENCLAW_IMAGE=openclaw:latest
|
||||
OPENCLAW_GATEWAY_TOKEN=
|
||||
OPENCLAW_GATEWAY_BIND=lan
|
||||
OPENCLAW_GATEWAY_PORT=18789
|
||||
|
||||
OPENCLAW_CONFIG_DIR=/home/$USER/.openclaw
|
||||
OPENCLAW_WORKSPACE_DIR=/home/$USER/.openclaw/workspace
|
||||
|
||||
GOG_KEYRING_PASSWORD=
|
||||
XDG_CONFIG_HOME=/home/node/.openclaw
|
||||
```
|
||||
|
||||
Leave `OPENCLAW_GATEWAY_TOKEN` blank unless you explicitly want to
|
||||
manage it through `.env`; OpenClaw writes a random gateway token to
|
||||
config on first start. Generate a keyring password and paste it into
|
||||
`GOG_KEYRING_PASSWORD`:
|
||||
|
||||
```bash
|
||||
openssl rand -hex 32
|
||||
```
|
||||
|
||||
**Do not commit this file.**
|
||||
|
||||
This `.env` file is for container/runtime env such as `OPENCLAW_GATEWAY_TOKEN`.
|
||||
Stored provider OAuth/API-key auth lives in the mounted
|
||||
`~/.openclaw/agents/<agentId>/agent/auth-profiles.json`.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Docker Compose configuration">
|
||||
Create or update `docker-compose.yml`.
|
||||
|
||||
```yaml
|
||||
services:
|
||||
openclaw-gateway:
|
||||
image: ${OPENCLAW_IMAGE}
|
||||
build: .
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- HOME=/home/node
|
||||
- NODE_ENV=production
|
||||
- TERM=xterm-256color
|
||||
- OPENCLAW_GATEWAY_BIND=${OPENCLAW_GATEWAY_BIND}
|
||||
- OPENCLAW_GATEWAY_PORT=${OPENCLAW_GATEWAY_PORT}
|
||||
- OPENCLAW_GATEWAY_TOKEN=${OPENCLAW_GATEWAY_TOKEN}
|
||||
- GOG_KEYRING_PASSWORD=${GOG_KEYRING_PASSWORD}
|
||||
- XDG_CONFIG_HOME=${XDG_CONFIG_HOME}
|
||||
- PATH=/home/linuxbrew/.linuxbrew/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
volumes:
|
||||
- ${OPENCLAW_CONFIG_DIR}:/home/node/.openclaw
|
||||
- ${OPENCLAW_WORKSPACE_DIR}:/home/node/.openclaw/workspace
|
||||
ports:
|
||||
# Recommended: keep the Gateway loopback-only on the VM; access via SSH tunnel.
|
||||
# To expose it publicly, remove the `127.0.0.1:` prefix and firewall accordingly.
|
||||
- "127.0.0.1:${OPENCLAW_GATEWAY_PORT}:18789"
|
||||
command:
|
||||
[
|
||||
"node",
|
||||
"dist/index.js",
|
||||
"gateway",
|
||||
"--bind",
|
||||
"${OPENCLAW_GATEWAY_BIND}",
|
||||
"--port",
|
||||
"${OPENCLAW_GATEWAY_PORT}",
|
||||
"--allow-unconfigured",
|
||||
]
|
||||
```
|
||||
|
||||
`--allow-unconfigured` is only for bootstrap convenience, it is not a replacement for a proper gateway configuration. Still set auth (`gateway.auth.token` or password) and use safe bind settings for your deployment.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Shared Docker VM runtime steps">
|
||||
Use the shared runtime guide for the common Docker host flow:
|
||||
|
||||
- [Bake required binaries into the image](/install/docker-vm-runtime#bake-required-binaries-into-the-image)
|
||||
- [Build and launch](/install/docker-vm-runtime#build-and-launch)
|
||||
- [What persists where](/install/docker-vm-runtime#what-persists-where)
|
||||
- [Updates](/install/docker-vm-runtime#updates)
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="GCP-specific launch notes">
|
||||
On GCP, if build fails with `Killed` or `exit code 137` during `pnpm install --frozen-lockfile`, the VM is out of memory. Use `e2-small` minimum, or `e2-medium` for more reliable first builds.
|
||||
|
||||
When binding to LAN (`OPENCLAW_GATEWAY_BIND=lan`), configure a trusted browser origin before continuing:
|
||||
|
||||
```bash
|
||||
docker compose run --rm openclaw-cli config set gateway.controlUi.allowedOrigins '["http://127.0.0.1:18789"]' --strict-json
|
||||
```
|
||||
|
||||
If you changed the gateway port, replace `18789` with your configured port.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Access from your laptop">
|
||||
Create an SSH tunnel to forward the Gateway port:
|
||||
|
||||
```bash
|
||||
gcloud compute ssh openclaw-gateway --zone=us-central1-a -- -L 18789:127.0.0.1:18789
|
||||
```
|
||||
|
||||
Open in your browser:
|
||||
|
||||
`http://127.0.0.1:18789/`
|
||||
|
||||
Reprint a clean dashboard link:
|
||||
|
||||
```bash
|
||||
docker compose run --rm openclaw-cli dashboard --no-open
|
||||
```
|
||||
|
||||
If the UI prompts for shared-secret auth, paste the configured token or
|
||||
password into Control UI settings. This Docker flow writes a token by
|
||||
default; if you switch the container config to password auth, use that
|
||||
password instead.
|
||||
|
||||
If Control UI shows `unauthorized` or `disconnected (1008): pairing required`, approve the browser device:
|
||||
|
||||
```bash
|
||||
docker compose run --rm openclaw-cli devices list
|
||||
docker compose run --rm openclaw-cli devices approve <requestId>
|
||||
```
|
||||
|
||||
Need the shared persistence and update reference again?
|
||||
See [Docker VM Runtime](/install/docker-vm-runtime#what-persists-where) and [Docker VM Runtime updates](/install/docker-vm-runtime#updates).
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**SSH connection refused**
|
||||
|
||||
SSH key propagation can take 1-2 minutes after VM creation. Wait and retry.
|
||||
|
||||
**OS Login issues**
|
||||
|
||||
Check your OS Login profile:
|
||||
|
||||
```bash
|
||||
gcloud compute os-login describe-profile
|
||||
```
|
||||
|
||||
Ensure your account has the required IAM permissions (Compute OS Login or Compute OS Admin Login).
|
||||
|
||||
**Out of memory (OOM)**
|
||||
|
||||
If Docker build fails with `Killed` and `exit code 137`, the VM was OOM-killed. Upgrade to e2-small (minimum) or e2-medium (recommended for reliable local builds):
|
||||
|
||||
```bash
|
||||
# Stop the VM first
|
||||
gcloud compute instances stop openclaw-gateway --zone=us-central1-a
|
||||
|
||||
# Change machine type
|
||||
gcloud compute instances set-machine-type openclaw-gateway \
|
||||
--zone=us-central1-a \
|
||||
--machine-type=e2-small
|
||||
|
||||
# Start the VM
|
||||
gcloud compute instances start openclaw-gateway --zone=us-central1-a
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Service accounts (security best practice)
|
||||
|
||||
For personal use, your default user account works fine.
|
||||
|
||||
For automation or CI/CD pipelines, create a dedicated service account with minimal permissions:
|
||||
|
||||
1. Create a service account:
|
||||
|
||||
```bash
|
||||
gcloud iam service-accounts create openclaw-deploy \
|
||||
--display-name="OpenClaw Deployment"
|
||||
```
|
||||
|
||||
2. Grant Compute Instance Admin role (or narrower custom role):
|
||||
|
||||
```bash
|
||||
gcloud projects add-iam-policy-binding my-openclaw-project \
|
||||
--member="serviceAccount:openclaw-deploy@my-openclaw-project.iam.gserviceaccount.com" \
|
||||
--role="roles/compute.instanceAdmin.v1"
|
||||
```
|
||||
|
||||
Avoid using the Owner role for automation. Use the principle of least privilege.
|
||||
|
||||
See [https://cloud.google.com/iam/docs/understanding-roles](https://cloud.google.com/iam/docs/understanding-roles) for IAM role details.
|
||||
|
||||
---
|
||||
|
||||
## Next steps
|
||||
|
||||
- Set up messaging channels: [Channels](/channels)
|
||||
- Pair local devices as nodes: [Nodes](/nodes)
|
||||
- Configure the Gateway: [Gateway configuration](/gateway/configuration)
|
||||
262
openclaw/docs/install/hetzner.md
Normal file
262
openclaw/docs/install/hetzner.md
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
---
|
||||
summary: "Run OpenClaw Gateway 24/7 on a cheap Hetzner VPS (Docker) with durable state and baked-in binaries"
|
||||
read_when:
|
||||
- You want OpenClaw running 24/7 on a cloud VPS (not your laptop)
|
||||
- You want a production-grade, always-on Gateway on your own VPS
|
||||
- You want full control over persistence, binaries, and restart behavior
|
||||
- You are running OpenClaw in Docker on Hetzner or a similar provider
|
||||
title: "Hetzner"
|
||||
---
|
||||
|
||||
# OpenClaw on Hetzner (Docker, Production VPS Guide)
|
||||
|
||||
## Goal
|
||||
|
||||
Run a persistent OpenClaw Gateway on a Hetzner VPS using Docker, with durable state, baked-in binaries, and safe restart behavior.
|
||||
|
||||
If you want “OpenClaw 24/7 for ~$5”, this is the simplest reliable setup.
|
||||
Hetzner pricing changes; pick the smallest Debian/Ubuntu VPS and scale up if you hit OOMs.
|
||||
|
||||
Security model reminder:
|
||||
|
||||
- Company-shared agents are fine when everyone is in the same trust boundary and the runtime is business-only.
|
||||
- Keep strict separation: dedicated VPS/runtime + dedicated accounts; no personal Apple/Google/browser/password-manager profiles on that host.
|
||||
- If users are adversarial to each other, split by gateway/host/OS user.
|
||||
|
||||
See [Security](/gateway/security) and [VPS hosting](/vps).
|
||||
|
||||
## What are we doing (simple terms)?
|
||||
|
||||
- Rent a small Linux server (Hetzner VPS)
|
||||
- Install Docker (isolated app runtime)
|
||||
- Start the OpenClaw Gateway in Docker
|
||||
- Persist `~/.openclaw` + `~/.openclaw/workspace` on the host (survives restarts/rebuilds)
|
||||
- Access the Control UI from your laptop via an SSH tunnel
|
||||
|
||||
That mounted `~/.openclaw` state includes `openclaw.json`, per-agent
|
||||
`agents/<agentId>/agent/auth-profiles.json`, and `.env`.
|
||||
|
||||
The Gateway can be accessed via:
|
||||
|
||||
- SSH port forwarding from your laptop
|
||||
- Direct port exposure if you manage firewalling and tokens yourself
|
||||
|
||||
This guide assumes Ubuntu or Debian on Hetzner.
|
||||
If you are on another Linux VPS, map packages accordingly.
|
||||
For the generic Docker flow, see [Docker](/install/docker).
|
||||
|
||||
---
|
||||
|
||||
## Quick path (experienced operators)
|
||||
|
||||
1. Provision Hetzner VPS
|
||||
2. Install Docker
|
||||
3. Clone OpenClaw repository
|
||||
4. Create persistent host directories
|
||||
5. Configure `.env` and `docker-compose.yml`
|
||||
6. Bake required binaries into the image
|
||||
7. `docker compose up -d`
|
||||
8. Verify persistence and Gateway access
|
||||
|
||||
---
|
||||
|
||||
## What you need
|
||||
|
||||
- Hetzner VPS with root access
|
||||
- SSH access from your laptop
|
||||
- Basic comfort with SSH + copy/paste
|
||||
- ~20 minutes
|
||||
- Docker and Docker Compose
|
||||
- Model auth credentials
|
||||
- Optional provider credentials
|
||||
- WhatsApp QR
|
||||
- Telegram bot token
|
||||
- Gmail OAuth
|
||||
|
||||
---
|
||||
|
||||
<Steps>
|
||||
<Step title="Provision the VPS">
|
||||
Create an Ubuntu or Debian VPS in Hetzner.
|
||||
|
||||
Connect as root:
|
||||
|
||||
```bash
|
||||
ssh root@YOUR_VPS_IP
|
||||
```
|
||||
|
||||
This guide assumes the VPS is stateful.
|
||||
Do not treat it as disposable infrastructure.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Install Docker (on the VPS)">
|
||||
```bash
|
||||
apt-get update
|
||||
apt-get install -y git curl ca-certificates
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
```
|
||||
|
||||
Verify:
|
||||
|
||||
```bash
|
||||
docker --version
|
||||
docker compose version
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Clone the OpenClaw repository">
|
||||
```bash
|
||||
git clone https://github.com/openclaw/openclaw.git
|
||||
cd openclaw
|
||||
```
|
||||
|
||||
This guide assumes you will build a custom image to guarantee binary persistence.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Create persistent host directories">
|
||||
Docker containers are ephemeral.
|
||||
All long-lived state must live on the host.
|
||||
|
||||
```bash
|
||||
mkdir -p /root/.openclaw/workspace
|
||||
|
||||
# Set ownership to the container user (uid 1000):
|
||||
chown -R 1000:1000 /root/.openclaw
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Configure environment variables">
|
||||
Create `.env` in the repository root.
|
||||
|
||||
```bash
|
||||
OPENCLAW_IMAGE=openclaw:latest
|
||||
OPENCLAW_GATEWAY_TOKEN=
|
||||
OPENCLAW_GATEWAY_BIND=lan
|
||||
OPENCLAW_GATEWAY_PORT=18789
|
||||
|
||||
OPENCLAW_CONFIG_DIR=/root/.openclaw
|
||||
OPENCLAW_WORKSPACE_DIR=/root/.openclaw/workspace
|
||||
|
||||
GOG_KEYRING_PASSWORD=
|
||||
XDG_CONFIG_HOME=/home/node/.openclaw
|
||||
```
|
||||
|
||||
Leave `OPENCLAW_GATEWAY_TOKEN` blank unless you explicitly want to
|
||||
manage it through `.env`; OpenClaw writes a random gateway token to
|
||||
config on first start. Generate a keyring password and paste it into
|
||||
`GOG_KEYRING_PASSWORD`:
|
||||
|
||||
```bash
|
||||
openssl rand -hex 32
|
||||
```
|
||||
|
||||
**Do not commit this file.**
|
||||
|
||||
This `.env` file is for container/runtime env such as `OPENCLAW_GATEWAY_TOKEN`.
|
||||
Stored provider OAuth/API-key auth lives in the mounted
|
||||
`~/.openclaw/agents/<agentId>/agent/auth-profiles.json`.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Docker Compose configuration">
|
||||
Create or update `docker-compose.yml`.
|
||||
|
||||
```yaml
|
||||
services:
|
||||
openclaw-gateway:
|
||||
image: ${OPENCLAW_IMAGE}
|
||||
build: .
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- HOME=/home/node
|
||||
- NODE_ENV=production
|
||||
- TERM=xterm-256color
|
||||
- OPENCLAW_GATEWAY_BIND=${OPENCLAW_GATEWAY_BIND}
|
||||
- OPENCLAW_GATEWAY_PORT=${OPENCLAW_GATEWAY_PORT}
|
||||
- OPENCLAW_GATEWAY_TOKEN=${OPENCLAW_GATEWAY_TOKEN}
|
||||
- GOG_KEYRING_PASSWORD=${GOG_KEYRING_PASSWORD}
|
||||
- XDG_CONFIG_HOME=${XDG_CONFIG_HOME}
|
||||
- PATH=/home/linuxbrew/.linuxbrew/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
volumes:
|
||||
- ${OPENCLAW_CONFIG_DIR}:/home/node/.openclaw
|
||||
- ${OPENCLAW_WORKSPACE_DIR}:/home/node/.openclaw/workspace
|
||||
ports:
|
||||
# Recommended: keep the Gateway loopback-only on the VPS; access via SSH tunnel.
|
||||
# To expose it publicly, remove the `127.0.0.1:` prefix and firewall accordingly.
|
||||
- "127.0.0.1:${OPENCLAW_GATEWAY_PORT}:18789"
|
||||
command:
|
||||
[
|
||||
"node",
|
||||
"dist/index.js",
|
||||
"gateway",
|
||||
"--bind",
|
||||
"${OPENCLAW_GATEWAY_BIND}",
|
||||
"--port",
|
||||
"${OPENCLAW_GATEWAY_PORT}",
|
||||
"--allow-unconfigured",
|
||||
]
|
||||
```
|
||||
|
||||
`--allow-unconfigured` is only for bootstrap convenience, it is not a replacement for a proper gateway configuration. Still set auth (`gateway.auth.token` or password) and use safe bind settings for your deployment.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Shared Docker VM runtime steps">
|
||||
Use the shared runtime guide for the common Docker host flow:
|
||||
|
||||
- [Bake required binaries into the image](/install/docker-vm-runtime#bake-required-binaries-into-the-image)
|
||||
- [Build and launch](/install/docker-vm-runtime#build-and-launch)
|
||||
- [What persists where](/install/docker-vm-runtime#what-persists-where)
|
||||
- [Updates](/install/docker-vm-runtime#updates)
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Hetzner-specific access">
|
||||
After the shared build and launch steps, tunnel from your laptop:
|
||||
|
||||
```bash
|
||||
ssh -N -L 18789:127.0.0.1:18789 root@YOUR_VPS_IP
|
||||
```
|
||||
|
||||
Open:
|
||||
|
||||
`http://127.0.0.1:18789/`
|
||||
|
||||
Paste the configured shared secret. This guide uses the gateway token by
|
||||
default; if you switched to password auth, use that password instead.
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
The shared persistence map lives in [Docker VM Runtime](/install/docker-vm-runtime#what-persists-where).
|
||||
|
||||
## Infrastructure as Code (Terraform)
|
||||
|
||||
For teams preferring infrastructure-as-code workflows, a community-maintained Terraform setup provides:
|
||||
|
||||
- Modular Terraform configuration with remote state management
|
||||
- Automated provisioning via cloud-init
|
||||
- Deployment scripts (bootstrap, deploy, backup/restore)
|
||||
- Security hardening (firewall, UFW, SSH-only access)
|
||||
- SSH tunnel configuration for gateway access
|
||||
|
||||
**Repositories:**
|
||||
|
||||
- Infrastructure: [openclaw-terraform-hetzner](https://github.com/andreesg/openclaw-terraform-hetzner)
|
||||
- Docker config: [openclaw-docker-config](https://github.com/andreesg/openclaw-docker-config)
|
||||
|
||||
This approach complements the Docker setup above with reproducible deployments, version-controlled infrastructure, and automated disaster recovery.
|
||||
|
||||
> **Note:** Community-maintained. For issues or contributions, see the repository links above.
|
||||
|
||||
## Next steps
|
||||
|
||||
- Set up messaging channels: [Channels](/channels)
|
||||
- Configure the Gateway: [Gateway configuration](/gateway/configuration)
|
||||
- Keep OpenClaw up to date: [Updating](/install/updating)
|
||||
94
openclaw/docs/install/hostinger.md
Normal file
94
openclaw/docs/install/hostinger.md
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
---
|
||||
summary: "Host OpenClaw on Hostinger"
|
||||
read_when:
|
||||
- Setting up OpenClaw on Hostinger
|
||||
- Looking for a managed VPS for OpenClaw
|
||||
- Using Hostinger 1-Click OpenClaw
|
||||
title: "Hostinger"
|
||||
---
|
||||
|
||||
# Hostinger
|
||||
|
||||
Run a persistent OpenClaw Gateway on [Hostinger](https://www.hostinger.com/openclaw) via a **1-Click** managed deployment or a **VPS** install.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Hostinger account ([signup](https://www.hostinger.com/openclaw))
|
||||
- About 5-10 minutes
|
||||
|
||||
## Option A: 1-Click OpenClaw
|
||||
|
||||
The fastest way to get started. Hostinger handles infrastructure, Docker, and automatic updates.
|
||||
|
||||
<Steps>
|
||||
<Step title="Purchase and launch">
|
||||
1. From the [Hostinger OpenClaw page](https://www.hostinger.com/openclaw), choose a Managed OpenClaw plan and complete checkout.
|
||||
|
||||
<Note>
|
||||
During checkout you can select **Ready-to-Use AI** credits that are pre-purchased and integrated instantly inside OpenClaw -- no external accounts or API keys from other providers needed. You can start chatting right away. Alternatively, provide your own key from Anthropic, OpenAI, Google Gemini, or xAI during setup.
|
||||
</Note>
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Select a messaging channel">
|
||||
Choose one or more channels to connect:
|
||||
|
||||
- **WhatsApp** -- scan the QR code shown in the setup wizard.
|
||||
- **Telegram** -- paste the bot token from [BotFather](https://t.me/BotFather).
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Complete installation">
|
||||
Click **Finish** to deploy the instance. Once ready, access the OpenClaw dashboard from **OpenClaw Overview** in hPanel.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
## Option B: OpenClaw on VPS
|
||||
|
||||
More control over your server. Hostinger deploys OpenClaw via Docker on your VPS and you manage it through the **Docker Manager** in hPanel.
|
||||
|
||||
<Steps>
|
||||
<Step title="Purchase a VPS">
|
||||
1. From the [Hostinger OpenClaw page](https://www.hostinger.com/openclaw), choose an OpenClaw on VPS plan and complete checkout.
|
||||
|
||||
<Note>
|
||||
You can select **Ready-to-Use AI** credits during checkout -- these are pre-purchased and integrated instantly inside OpenClaw, so you can start chatting without any external accounts or API keys from other providers.
|
||||
</Note>
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Configure OpenClaw">
|
||||
Once the VPS is provisioned, fill in the configuration fields:
|
||||
|
||||
- **Gateway token** -- auto-generated; save it for later use.
|
||||
- **WhatsApp number** -- your number with country code (optional).
|
||||
- **Telegram bot token** -- from [BotFather](https://t.me/BotFather) (optional).
|
||||
- **API keys** -- only needed if you did not select Ready-to-Use AI credits during checkout.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Start OpenClaw">
|
||||
Click **Deploy**. Once running, open the OpenClaw dashboard from the hPanel by clicking on **Open**.
|
||||
</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
Logs, restarts, and updates are managed directly from the Docker Manager interface in hPanel. To update, press on **Update** in Docker Manager and that will pull the latest image.
|
||||
|
||||
## Verify your setup
|
||||
|
||||
Send "Hi" to your assistant on the channel you connected. OpenClaw will reply and walk you through initial preferences.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Dashboard not loading** -- Wait a few minutes for the container to finish provisioning. Check the Docker Manager logs in hPanel.
|
||||
|
||||
**Docker container keeps restarting** -- Open Docker Manager logs and look for configuration errors (missing tokens, invalid API keys).
|
||||
|
||||
**Telegram bot not responding** -- Send your pairing code message from Telegram directly as a message inside your OpenClaw chat to complete the connection.
|
||||
|
||||
## Next steps
|
||||
|
||||
- [Channels](/channels) -- connect Telegram, WhatsApp, Discord, and more
|
||||
- [Gateway configuration](/gateway/configuration) -- all config optionss
|
||||
212
openclaw/docs/install/index.md
Normal file
212
openclaw/docs/install/index.md
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
---
|
||||
summary: "Install OpenClaw — installer script, npm/pnpm/bun, from source, Docker, and more"
|
||||
read_when:
|
||||
- You need an install method other than the Getting Started quickstart
|
||||
- You want to deploy to a cloud platform
|
||||
- You need to update, migrate, or uninstall
|
||||
title: "Install"
|
||||
---
|
||||
|
||||
# Install
|
||||
|
||||
## Recommended: installer script
|
||||
|
||||
The fastest way to install. It detects your OS, installs Node if needed, installs OpenClaw, and launches onboarding.
|
||||
|
||||
<Tabs>
|
||||
<Tab title="macOS / Linux / WSL2">
|
||||
```bash
|
||||
curl -fsSL https://openclaw.ai/install.sh | bash
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Windows (PowerShell)">
|
||||
```powershell
|
||||
iwr -useb https://openclaw.ai/install.ps1 | iex
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
To install without running onboarding:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="macOS / Linux / WSL2">
|
||||
```bash
|
||||
curl -fsSL https://openclaw.ai/install.sh | bash -s -- --no-onboard
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Windows (PowerShell)">
|
||||
```powershell
|
||||
& ([scriptblock]::Create((iwr -useb https://openclaw.ai/install.ps1))) -NoOnboard
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
For all flags and CI/automation options, see [Installer internals](/install/installer).
|
||||
|
||||
## System requirements
|
||||
|
||||
- **Node 24** (recommended) or Node 22.14+ — the installer script handles this automatically
|
||||
- **macOS, Linux, or Windows** — both native Windows and WSL2 are supported; WSL2 is more stable. See [Windows](/platforms/windows).
|
||||
- `pnpm` is only needed if you build from source
|
||||
|
||||
## Alternative install methods
|
||||
|
||||
### Local prefix installer (`install-cli.sh`)
|
||||
|
||||
Use this when you want OpenClaw and Node kept under a local prefix such as
|
||||
`~/.openclaw`, without depending on a system-wide Node install:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://openclaw.ai/install-cli.sh | bash
|
||||
```
|
||||
|
||||
It supports npm installs by default, plus git-checkout installs under the same
|
||||
prefix flow. Full reference: [Installer internals](/install/installer#install-clish).
|
||||
|
||||
### npm, pnpm, or bun
|
||||
|
||||
If you already manage Node yourself:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="npm">
|
||||
```bash
|
||||
npm install -g openclaw@latest
|
||||
openclaw onboard --install-daemon
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="pnpm">
|
||||
```bash
|
||||
pnpm add -g openclaw@latest
|
||||
pnpm approve-builds -g
|
||||
openclaw onboard --install-daemon
|
||||
```
|
||||
|
||||
<Note>
|
||||
pnpm requires explicit approval for packages with build scripts. Run `pnpm approve-builds -g` after the first install.
|
||||
</Note>
|
||||
|
||||
</Tab>
|
||||
<Tab title="bun">
|
||||
```bash
|
||||
bun add -g openclaw@latest
|
||||
openclaw onboard --install-daemon
|
||||
```
|
||||
|
||||
<Note>
|
||||
Bun is supported for the global CLI install path. For the Gateway runtime, Node remains the recommended daemon runtime.
|
||||
</Note>
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<Accordion title="Troubleshooting: sharp build errors (npm)">
|
||||
If `sharp` fails due to a globally installed libvips:
|
||||
|
||||
```bash
|
||||
SHARP_IGNORE_GLOBAL_LIBVIPS=1 npm install -g openclaw@latest
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
|
||||
### From source
|
||||
|
||||
For contributors or anyone who wants to run from a local checkout:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/openclaw/openclaw.git
|
||||
cd openclaw
|
||||
pnpm install && pnpm build && pnpm ui:build
|
||||
pnpm link --global
|
||||
openclaw onboard --install-daemon
|
||||
```
|
||||
|
||||
Or skip the link and use `pnpm openclaw ...` from inside the repo. See [Setup](/start/setup) for full development workflows.
|
||||
|
||||
### Install from GitHub main
|
||||
|
||||
```bash
|
||||
npm install -g github:openclaw/openclaw#main
|
||||
```
|
||||
|
||||
### Containers and package managers
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Docker" href="/install/docker" icon="container">
|
||||
Containerized or headless deployments.
|
||||
</Card>
|
||||
<Card title="Podman" href="/install/podman" icon="container">
|
||||
Rootless container alternative to Docker.
|
||||
</Card>
|
||||
<Card title="Nix" href="/install/nix" icon="snowflake">
|
||||
Declarative install via Nix flake.
|
||||
</Card>
|
||||
<Card title="Ansible" href="/install/ansible" icon="server">
|
||||
Automated fleet provisioning.
|
||||
</Card>
|
||||
<Card title="Bun" href="/install/bun" icon="zap">
|
||||
CLI-only usage via the Bun runtime.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Verify the install
|
||||
|
||||
```bash
|
||||
openclaw --version # confirm the CLI is available
|
||||
openclaw doctor # check for config issues
|
||||
openclaw gateway status # verify the Gateway is running
|
||||
```
|
||||
|
||||
If you want managed startup after install:
|
||||
|
||||
- macOS: LaunchAgent via `openclaw onboard --install-daemon` or `openclaw gateway install`
|
||||
- Linux/WSL2: systemd user service via the same commands
|
||||
- Native Windows: Scheduled Task first, with a per-user Startup-folder login item fallback if task creation is denied
|
||||
|
||||
## Hosting and deployment
|
||||
|
||||
Deploy OpenClaw on a cloud server or VPS:
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="VPS" href="/vps">Any Linux VPS</Card>
|
||||
<Card title="Docker VM" href="/install/docker-vm-runtime">Shared Docker steps</Card>
|
||||
<Card title="Kubernetes" href="/install/kubernetes">K8s</Card>
|
||||
<Card title="Fly.io" href="/install/fly">Fly.io</Card>
|
||||
<Card title="Hetzner" href="/install/hetzner">Hetzner</Card>
|
||||
<Card title="GCP" href="/install/gcp">Google Cloud</Card>
|
||||
<Card title="Azure" href="/install/azure">Azure</Card>
|
||||
<Card title="Railway" href="/install/railway">Railway</Card>
|
||||
<Card title="Render" href="/install/render">Render</Card>
|
||||
<Card title="Northflank" href="/install/northflank">Northflank</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Update, migrate, or uninstall
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Updating" href="/install/updating" icon="refresh-cw">
|
||||
Keep OpenClaw up to date.
|
||||
</Card>
|
||||
<Card title="Migrating" href="/install/migrating" icon="arrow-right">
|
||||
Move to a new machine.
|
||||
</Card>
|
||||
<Card title="Uninstall" href="/install/uninstall" icon="trash-2">
|
||||
Remove OpenClaw completely.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Troubleshooting: `openclaw` not found
|
||||
|
||||
If the install succeeded but `openclaw` is not found in your terminal:
|
||||
|
||||
```bash
|
||||
node -v # Node installed?
|
||||
npm prefix -g # Where are global packages?
|
||||
echo "$PATH" # Is the global bin dir in PATH?
|
||||
```
|
||||
|
||||
If `$(npm prefix -g)/bin` is not in your `$PATH`, add it to your shell startup file (`~/.zshrc` or `~/.bashrc`):
|
||||
|
||||
```bash
|
||||
export PATH="$(npm prefix -g)/bin:$PATH"
|
||||
```
|
||||
|
||||
Then open a new terminal. See [Node setup](/install/node) for more details.
|
||||
443
openclaw/docs/install/installer.md
Normal file
443
openclaw/docs/install/installer.md
Normal file
|
|
@ -0,0 +1,443 @@
|
|||
---
|
||||
summary: "How the installer scripts work (install.sh, install-cli.sh, install.ps1), flags, and automation"
|
||||
read_when:
|
||||
- You want to understand `openclaw.ai/install.sh`
|
||||
- You want to automate installs (CI / headless)
|
||||
- You want to install from a GitHub checkout
|
||||
title: "Installer Internals"
|
||||
---
|
||||
|
||||
# Installer internals
|
||||
|
||||
OpenClaw ships three installer scripts, served from `openclaw.ai`.
|
||||
|
||||
| Script | Platform | What it does |
|
||||
| ---------------------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------- |
|
||||
| [`install.sh`](#installsh) | macOS / Linux / WSL | Installs Node if needed, installs OpenClaw via npm (default) or git, and can run onboarding. |
|
||||
| [`install-cli.sh`](#install-clish) | macOS / Linux / WSL | Installs Node + OpenClaw into a local prefix (`~/.openclaw`) with npm or git checkout modes. No root required. |
|
||||
| [`install.ps1`](#installps1) | Windows (PowerShell) | Installs Node if needed, installs OpenClaw via npm (default) or git, and can run onboarding. |
|
||||
|
||||
## Quick commands
|
||||
|
||||
<Tabs>
|
||||
<Tab title="install.sh">
|
||||
```bash
|
||||
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash
|
||||
```
|
||||
|
||||
```bash
|
||||
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --help
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab title="install-cli.sh">
|
||||
```bash
|
||||
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install-cli.sh | bash
|
||||
```
|
||||
|
||||
```bash
|
||||
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install-cli.sh | bash -s -- --help
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab title="install.ps1">
|
||||
```powershell
|
||||
iwr -useb https://openclaw.ai/install.ps1 | iex
|
||||
```
|
||||
|
||||
```powershell
|
||||
& ([scriptblock]::Create((iwr -useb https://openclaw.ai/install.ps1))) -Tag beta -NoOnboard -DryRun
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<Note>
|
||||
If install succeeds but `openclaw` is not found in a new terminal, see [Node.js troubleshooting](/install/node#troubleshooting).
|
||||
</Note>
|
||||
|
||||
---
|
||||
|
||||
<a id="installsh"></a>
|
||||
|
||||
## install.sh
|
||||
|
||||
<Tip>
|
||||
Recommended for most interactive installs on macOS/Linux/WSL.
|
||||
</Tip>
|
||||
|
||||
### Flow (install.sh)
|
||||
|
||||
<Steps>
|
||||
<Step title="Detect OS">
|
||||
Supports macOS and Linux (including WSL). If macOS is detected, installs Homebrew if missing.
|
||||
</Step>
|
||||
<Step title="Ensure Node.js 24 by default">
|
||||
Checks Node version and installs Node 24 if needed (Homebrew on macOS, NodeSource setup scripts on Linux apt/dnf/yum). OpenClaw still supports Node 22 LTS, currently `22.14+`, for compatibility.
|
||||
</Step>
|
||||
<Step title="Ensure Git">
|
||||
Installs Git if missing.
|
||||
</Step>
|
||||
<Step title="Install OpenClaw">
|
||||
- `npm` method (default): global npm install
|
||||
- `git` method: clone/update repo, install deps with pnpm, build, then install wrapper at `~/.local/bin/openclaw`
|
||||
</Step>
|
||||
<Step title="Post-install tasks">
|
||||
- Refreshes a loaded gateway service best-effort (`openclaw gateway install --force`, then restart)
|
||||
- Runs `openclaw doctor --non-interactive` on upgrades and git installs (best effort)
|
||||
- Attempts onboarding when appropriate (TTY available, onboarding not disabled, and bootstrap/config checks pass)
|
||||
- Defaults `SHARP_IGNORE_GLOBAL_LIBVIPS=1`
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
### Source checkout detection
|
||||
|
||||
If run inside an OpenClaw checkout (`package.json` + `pnpm-workspace.yaml`), the script offers:
|
||||
|
||||
- use checkout (`git`), or
|
||||
- use global install (`npm`)
|
||||
|
||||
If no TTY is available and no install method is set, it defaults to `npm` and warns.
|
||||
|
||||
The script exits with code `2` for invalid method selection or invalid `--install-method` values.
|
||||
|
||||
### Examples (install.sh)
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Default">
|
||||
```bash
|
||||
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Skip onboarding">
|
||||
```bash
|
||||
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --no-onboard
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Git install">
|
||||
```bash
|
||||
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --install-method git
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="GitHub main via npm">
|
||||
```bash
|
||||
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --version main
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Dry run">
|
||||
```bash
|
||||
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --dry-run
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Flags reference">
|
||||
|
||||
| Flag | Description |
|
||||
| ------------------------------------- | ---------------------------------------------------------- |
|
||||
| `--install-method npm\|git` | Choose install method (default: `npm`). Alias: `--method` |
|
||||
| `--npm` | Shortcut for npm method |
|
||||
| `--git` | Shortcut for git method. Alias: `--github` |
|
||||
| `--version <version\|dist-tag\|spec>` | npm version, dist-tag, or package spec (default: `latest`) |
|
||||
| `--beta` | Use beta dist-tag if available, else fallback to `latest` |
|
||||
| `--git-dir <path>` | Checkout directory (default: `~/openclaw`). Alias: `--dir` |
|
||||
| `--no-git-update` | Skip `git pull` for existing checkout |
|
||||
| `--no-prompt` | Disable prompts |
|
||||
| `--no-onboard` | Skip onboarding |
|
||||
| `--onboard` | Enable onboarding |
|
||||
| `--dry-run` | Print actions without applying changes |
|
||||
| `--verbose` | Enable debug output (`set -x`, npm notice-level logs) |
|
||||
| `--help` | Show usage (`-h`) |
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Environment variables reference">
|
||||
|
||||
| Variable | Description |
|
||||
| ------------------------------------------------------- | --------------------------------------------- |
|
||||
| `OPENCLAW_INSTALL_METHOD=git\|npm` | Install method |
|
||||
| `OPENCLAW_VERSION=latest\|next\|main\|<semver>\|<spec>` | npm version, dist-tag, or package spec |
|
||||
| `OPENCLAW_BETA=0\|1` | Use beta if available |
|
||||
| `OPENCLAW_GIT_DIR=<path>` | Checkout directory |
|
||||
| `OPENCLAW_GIT_UPDATE=0\|1` | Toggle git updates |
|
||||
| `OPENCLAW_NO_PROMPT=1` | Disable prompts |
|
||||
| `OPENCLAW_NO_ONBOARD=1` | Skip onboarding |
|
||||
| `OPENCLAW_DRY_RUN=1` | Dry run mode |
|
||||
| `OPENCLAW_VERBOSE=1` | Debug mode |
|
||||
| `OPENCLAW_NPM_LOGLEVEL=error\|warn\|notice` | npm log level |
|
||||
| `SHARP_IGNORE_GLOBAL_LIBVIPS=0\|1` | Control sharp/libvips behavior (default: `1`) |
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
---
|
||||
|
||||
<a id="install-clish"></a>
|
||||
|
||||
## install-cli.sh
|
||||
|
||||
<Info>
|
||||
Designed for environments where you want everything under a local prefix
|
||||
(default `~/.openclaw`) and no system Node dependency. Supports npm installs
|
||||
by default, plus git-checkout installs under the same prefix flow.
|
||||
</Info>
|
||||
|
||||
### Flow (install-cli.sh)
|
||||
|
||||
<Steps>
|
||||
<Step title="Install local Node runtime">
|
||||
Downloads a pinned supported Node LTS tarball (the version is embedded in the script and updated independently) to `<prefix>/tools/node-v<version>` and verifies SHA-256.
|
||||
</Step>
|
||||
<Step title="Ensure Git">
|
||||
If Git is missing, attempts install via apt/dnf/yum on Linux or Homebrew on macOS.
|
||||
</Step>
|
||||
<Step title="Install OpenClaw under prefix">
|
||||
- `npm` method (default): installs under the prefix with npm, then writes wrapper to `<prefix>/bin/openclaw`
|
||||
- `git` method: clones/updates a checkout (default `~/openclaw`) and still writes the wrapper to `<prefix>/bin/openclaw`
|
||||
</Step>
|
||||
<Step title="Refresh loaded gateway service">
|
||||
If a gateway service is already loaded from that same prefix, the script runs
|
||||
`openclaw gateway install --force`, then `openclaw gateway restart`, and
|
||||
probes gateway health best-effort.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
### Examples (install-cli.sh)
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Default">
|
||||
```bash
|
||||
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install-cli.sh | bash
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Custom prefix + version">
|
||||
```bash
|
||||
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install-cli.sh | bash -s -- --prefix /opt/openclaw --version latest
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Git install">
|
||||
```bash
|
||||
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install-cli.sh | bash -s -- --install-method git --git-dir ~/openclaw
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Automation JSON output">
|
||||
```bash
|
||||
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install-cli.sh | bash -s -- --json --prefix /opt/openclaw
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Run onboarding">
|
||||
```bash
|
||||
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install-cli.sh | bash -s -- --onboard
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Flags reference">
|
||||
|
||||
| Flag | Description |
|
||||
| --------------------------- | ------------------------------------------------------------------------------- |
|
||||
| `--prefix <path>` | Install prefix (default: `~/.openclaw`) |
|
||||
| `--install-method npm\|git` | Choose install method (default: `npm`). Alias: `--method` |
|
||||
| `--npm` | Shortcut for npm method |
|
||||
| `--git`, `--github` | Shortcut for git method |
|
||||
| `--git-dir <path>` | Git checkout directory (default: `~/openclaw`). Alias: `--dir` |
|
||||
| `--version <ver>` | OpenClaw version or dist-tag (default: `latest`) |
|
||||
| `--node-version <ver>` | Node version (default: `22.22.0`) |
|
||||
| `--json` | Emit NDJSON events |
|
||||
| `--onboard` | Run `openclaw onboard` after install |
|
||||
| `--no-onboard` | Skip onboarding (default) |
|
||||
| `--set-npm-prefix` | On Linux, force npm prefix to `~/.npm-global` if current prefix is not writable |
|
||||
| `--help` | Show usage (`-h`) |
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Environment variables reference">
|
||||
|
||||
| Variable | Description |
|
||||
| ------------------------------------------- | --------------------------------------------- |
|
||||
| `OPENCLAW_PREFIX=<path>` | Install prefix |
|
||||
| `OPENCLAW_INSTALL_METHOD=git\|npm` | Install method |
|
||||
| `OPENCLAW_VERSION=<ver>` | OpenClaw version or dist-tag |
|
||||
| `OPENCLAW_NODE_VERSION=<ver>` | Node version |
|
||||
| `OPENCLAW_GIT_DIR=<path>` | Git checkout directory for git installs |
|
||||
| `OPENCLAW_GIT_UPDATE=0\|1` | Toggle git updates for existing checkouts |
|
||||
| `OPENCLAW_NO_ONBOARD=1` | Skip onboarding |
|
||||
| `OPENCLAW_NPM_LOGLEVEL=error\|warn\|notice` | npm log level |
|
||||
| `SHARP_IGNORE_GLOBAL_LIBVIPS=0\|1` | Control sharp/libvips behavior (default: `1`) |
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
---
|
||||
|
||||
<a id="installps1"></a>
|
||||
|
||||
## install.ps1
|
||||
|
||||
### Flow (install.ps1)
|
||||
|
||||
<Steps>
|
||||
<Step title="Ensure PowerShell + Windows environment">
|
||||
Requires PowerShell 5+.
|
||||
</Step>
|
||||
<Step title="Ensure Node.js 24 by default">
|
||||
If missing, attempts install via winget, then Chocolatey, then Scoop. Node 22 LTS, currently `22.14+`, remains supported for compatibility.
|
||||
</Step>
|
||||
<Step title="Install OpenClaw">
|
||||
- `npm` method (default): global npm install using selected `-Tag`
|
||||
- `git` method: clone/update repo, install/build with pnpm, and install wrapper at `%USERPROFILE%\.local\bin\openclaw.cmd`
|
||||
</Step>
|
||||
<Step title="Post-install tasks">
|
||||
- Adds needed bin directory to user PATH when possible
|
||||
- Refreshes a loaded gateway service best-effort (`openclaw gateway install --force`, then restart)
|
||||
- Runs `openclaw doctor --non-interactive` on upgrades and git installs (best effort)
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
### Examples (install.ps1)
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Default">
|
||||
```powershell
|
||||
iwr -useb https://openclaw.ai/install.ps1 | iex
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Git install">
|
||||
```powershell
|
||||
& ([scriptblock]::Create((iwr -useb https://openclaw.ai/install.ps1))) -InstallMethod git
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="GitHub main via npm">
|
||||
```powershell
|
||||
& ([scriptblock]::Create((iwr -useb https://openclaw.ai/install.ps1))) -Tag main
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Custom git directory">
|
||||
```powershell
|
||||
& ([scriptblock]::Create((iwr -useb https://openclaw.ai/install.ps1))) -InstallMethod git -GitDir "C:\openclaw"
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Dry run">
|
||||
```powershell
|
||||
& ([scriptblock]::Create((iwr -useb https://openclaw.ai/install.ps1))) -DryRun
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Debug trace">
|
||||
```powershell
|
||||
# install.ps1 has no dedicated -Verbose flag yet.
|
||||
Set-PSDebug -Trace 1
|
||||
& ([scriptblock]::Create((iwr -useb https://openclaw.ai/install.ps1))) -NoOnboard
|
||||
Set-PSDebug -Trace 0
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Flags reference">
|
||||
|
||||
| Flag | Description |
|
||||
| --------------------------- | ---------------------------------------------------------- |
|
||||
| `-InstallMethod npm\|git` | Install method (default: `npm`) |
|
||||
| `-Tag <tag\|version\|spec>` | npm dist-tag, version, or package spec (default: `latest`) |
|
||||
| `-GitDir <path>` | Checkout directory (default: `%USERPROFILE%\openclaw`) |
|
||||
| `-NoOnboard` | Skip onboarding |
|
||||
| `-NoGitUpdate` | Skip `git pull` |
|
||||
| `-DryRun` | Print actions only |
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Environment variables reference">
|
||||
|
||||
| Variable | Description |
|
||||
| ---------------------------------- | ------------------ |
|
||||
| `OPENCLAW_INSTALL_METHOD=git\|npm` | Install method |
|
||||
| `OPENCLAW_GIT_DIR=<path>` | Checkout directory |
|
||||
| `OPENCLAW_NO_ONBOARD=1` | Skip onboarding |
|
||||
| `OPENCLAW_GIT_UPDATE=0` | Disable git pull |
|
||||
| `OPENCLAW_DRY_RUN=1` | Dry run mode |
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
<Note>
|
||||
If `-InstallMethod git` is used and Git is missing, the script exits and prints the Git for Windows link.
|
||||
</Note>
|
||||
|
||||
---
|
||||
|
||||
## CI and automation
|
||||
|
||||
Use non-interactive flags/env vars for predictable runs.
|
||||
|
||||
<Tabs>
|
||||
<Tab title="install.sh (non-interactive npm)">
|
||||
```bash
|
||||
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --no-prompt --no-onboard
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="install.sh (non-interactive git)">
|
||||
```bash
|
||||
OPENCLAW_INSTALL_METHOD=git OPENCLAW_NO_PROMPT=1 \
|
||||
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="install-cli.sh (JSON)">
|
||||
```bash
|
||||
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install-cli.sh | bash -s -- --json --prefix /opt/openclaw
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="install.ps1 (skip onboarding)">
|
||||
```powershell
|
||||
& ([scriptblock]::Create((iwr -useb https://openclaw.ai/install.ps1))) -NoOnboard
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Why is Git required?">
|
||||
Git is required for `git` install method. For `npm` installs, Git is still checked/installed to avoid `spawn git ENOENT` failures when dependencies use git URLs.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Why does npm hit EACCES on Linux?">
|
||||
Some Linux setups point npm global prefix to root-owned paths. `install.sh` can switch prefix to `~/.npm-global` and append PATH exports to shell rc files (when those files exist).
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="sharp/libvips issues">
|
||||
The scripts default `SHARP_IGNORE_GLOBAL_LIBVIPS=1` to avoid sharp building against system libvips. To override:
|
||||
|
||||
```bash
|
||||
SHARP_IGNORE_GLOBAL_LIBVIPS=0 curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title='Windows: "npm error spawn git / ENOENT"'>
|
||||
Install Git for Windows, reopen PowerShell, rerun installer.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title='Windows: "openclaw is not recognized"'>
|
||||
Run `npm config get prefix` and add that directory to your user PATH (no `\bin` suffix needed on Windows), then reopen PowerShell.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Windows: how to get verbose installer output">
|
||||
`install.ps1` does not currently expose a `-Verbose` switch.
|
||||
Use PowerShell tracing for script-level diagnostics:
|
||||
|
||||
```powershell
|
||||
Set-PSDebug -Trace 1
|
||||
& ([scriptblock]::Create((iwr -useb https://openclaw.ai/install.ps1))) -NoOnboard
|
||||
Set-PSDebug -Trace 0
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="openclaw not found after install">
|
||||
Usually a PATH issue. See [Node.js troubleshooting](/install/node#troubleshooting).
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
192
openclaw/docs/install/kubernetes.md
Normal file
192
openclaw/docs/install/kubernetes.md
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
---
|
||||
summary: "Deploy OpenClaw Gateway to a Kubernetes cluster with Kustomize"
|
||||
read_when:
|
||||
- You want to run OpenClaw on a Kubernetes cluster
|
||||
- You want to test OpenClaw in a Kubernetes environment
|
||||
title: "Kubernetes"
|
||||
---
|
||||
|
||||
# OpenClaw on Kubernetes
|
||||
|
||||
A minimal starting point for running OpenClaw on Kubernetes — not a production-ready deployment. It covers the core resources and is meant to be adapted to your environment.
|
||||
|
||||
## Why not Helm?
|
||||
|
||||
OpenClaw is a single container with some config files. The interesting customization is in agent content (markdown files, skills, config overrides), not infrastructure templating. Kustomize handles overlays without the overhead of a Helm chart. If your deployment grows more complex, a Helm chart can be layered on top of these manifests.
|
||||
|
||||
## What you need
|
||||
|
||||
- A running Kubernetes cluster (AKS, EKS, GKE, k3s, kind, OpenShift, etc.)
|
||||
- `kubectl` connected to your cluster
|
||||
- An API key for at least one model provider
|
||||
|
||||
## Quick start
|
||||
|
||||
```bash
|
||||
# Replace with your provider: ANTHROPIC, GEMINI, OPENAI, or OPENROUTER
|
||||
export <PROVIDER>_API_KEY="..."
|
||||
./scripts/k8s/deploy.sh
|
||||
|
||||
kubectl port-forward svc/openclaw 18789:18789 -n openclaw
|
||||
open http://localhost:18789
|
||||
```
|
||||
|
||||
Retrieve the configured shared secret for the Control UI. This deploy script
|
||||
creates token auth by default:
|
||||
|
||||
```bash
|
||||
kubectl get secret openclaw-secrets -n openclaw -o jsonpath='{.data.OPENCLAW_GATEWAY_TOKEN}' | base64 -d
|
||||
```
|
||||
|
||||
For local debugging, `./scripts/k8s/deploy.sh --show-token` prints the token after deploy.
|
||||
|
||||
## Local testing with Kind
|
||||
|
||||
If you don't have a cluster, create one locally with [Kind](https://kind.sigs.k8s.io/):
|
||||
|
||||
```bash
|
||||
./scripts/k8s/create-kind.sh # auto-detects docker or podman
|
||||
./scripts/k8s/create-kind.sh --delete # tear down
|
||||
```
|
||||
|
||||
Then deploy as usual with `./scripts/k8s/deploy.sh`.
|
||||
|
||||
## Step by step
|
||||
|
||||
### 1) Deploy
|
||||
|
||||
**Option A** — API key in environment (one step):
|
||||
|
||||
```bash
|
||||
# Replace with your provider: ANTHROPIC, GEMINI, OPENAI, or OPENROUTER
|
||||
export <PROVIDER>_API_KEY="..."
|
||||
./scripts/k8s/deploy.sh
|
||||
```
|
||||
|
||||
The script creates a Kubernetes Secret with the API key and an auto-generated gateway token, then deploys. If the Secret already exists, it preserves the current gateway token and any provider keys not being changed.
|
||||
|
||||
**Option B** — create the secret separately:
|
||||
|
||||
```bash
|
||||
export <PROVIDER>_API_KEY="..."
|
||||
./scripts/k8s/deploy.sh --create-secret
|
||||
./scripts/k8s/deploy.sh
|
||||
```
|
||||
|
||||
Use `--show-token` with either command if you want the token printed to stdout for local testing.
|
||||
|
||||
### 2) Access the gateway
|
||||
|
||||
```bash
|
||||
kubectl port-forward svc/openclaw 18789:18789 -n openclaw
|
||||
open http://localhost:18789
|
||||
```
|
||||
|
||||
## What gets deployed
|
||||
|
||||
```
|
||||
Namespace: openclaw (configurable via OPENCLAW_NAMESPACE)
|
||||
├── Deployment/openclaw # Single pod, init container + gateway
|
||||
├── Service/openclaw # ClusterIP on port 18789
|
||||
├── PersistentVolumeClaim # 10Gi for agent state and config
|
||||
├── ConfigMap/openclaw-config # openclaw.json + AGENTS.md
|
||||
└── Secret/openclaw-secrets # Gateway token + API keys
|
||||
```
|
||||
|
||||
## Customization
|
||||
|
||||
### Agent instructions
|
||||
|
||||
Edit the `AGENTS.md` in `scripts/k8s/manifests/configmap.yaml` and redeploy:
|
||||
|
||||
```bash
|
||||
./scripts/k8s/deploy.sh
|
||||
```
|
||||
|
||||
### Gateway config
|
||||
|
||||
Edit `openclaw.json` in `scripts/k8s/manifests/configmap.yaml`. See [Gateway configuration](/gateway/configuration) for the full reference.
|
||||
|
||||
### Add providers
|
||||
|
||||
Re-run with additional keys exported:
|
||||
|
||||
```bash
|
||||
export ANTHROPIC_API_KEY="..."
|
||||
export OPENAI_API_KEY="..."
|
||||
./scripts/k8s/deploy.sh --create-secret
|
||||
./scripts/k8s/deploy.sh
|
||||
```
|
||||
|
||||
Existing provider keys stay in the Secret unless you overwrite them.
|
||||
|
||||
Or patch the Secret directly:
|
||||
|
||||
```bash
|
||||
kubectl patch secret openclaw-secrets -n openclaw \
|
||||
-p '{"stringData":{"<PROVIDER>_API_KEY":"..."}}'
|
||||
kubectl rollout restart deployment/openclaw -n openclaw
|
||||
```
|
||||
|
||||
### Custom namespace
|
||||
|
||||
```bash
|
||||
OPENCLAW_NAMESPACE=my-namespace ./scripts/k8s/deploy.sh
|
||||
```
|
||||
|
||||
### Custom image
|
||||
|
||||
Edit the `image` field in `scripts/k8s/manifests/deployment.yaml`:
|
||||
|
||||
```yaml
|
||||
image: ghcr.io/openclaw/openclaw:latest # or pin to a specific version from https://github.com/openclaw/openclaw/releases
|
||||
```
|
||||
|
||||
### Expose beyond port-forward
|
||||
|
||||
The default manifests bind the gateway to loopback inside the pod. That works with `kubectl port-forward`, but it does not work with a Kubernetes `Service` or Ingress path that needs to reach the pod IP.
|
||||
|
||||
If you want to expose the gateway through an Ingress or load balancer:
|
||||
|
||||
- Change the gateway bind in `scripts/k8s/manifests/configmap.yaml` from `loopback` to a non-loopback bind that matches your deployment model
|
||||
- Keep gateway auth enabled and use a proper TLS-terminated entrypoint
|
||||
- Configure the Control UI for remote access using the supported web security model (for example HTTPS/Tailscale Serve and explicit allowed origins when needed)
|
||||
|
||||
## Re-deploy
|
||||
|
||||
```bash
|
||||
./scripts/k8s/deploy.sh
|
||||
```
|
||||
|
||||
This applies all manifests and restarts the pod to pick up any config or secret changes.
|
||||
|
||||
## Teardown
|
||||
|
||||
```bash
|
||||
./scripts/k8s/deploy.sh --delete
|
||||
```
|
||||
|
||||
This deletes the namespace and all resources in it, including the PVC.
|
||||
|
||||
## Architecture notes
|
||||
|
||||
- The gateway binds to loopback inside the pod by default, so the included setup is for `kubectl port-forward`
|
||||
- No cluster-scoped resources — everything lives in a single namespace
|
||||
- Security: `readOnlyRootFilesystem`, `drop: ALL` capabilities, non-root user (UID 1000)
|
||||
- The default config keeps the Control UI on the safer local-access path: loopback bind plus `kubectl port-forward` to `http://127.0.0.1:18789`
|
||||
- If you move beyond localhost access, use the supported remote model: HTTPS/Tailscale plus the appropriate gateway bind and Control UI origin settings
|
||||
- Secrets are generated in a temp directory and applied directly to the cluster — no secret material is written to the repo checkout
|
||||
|
||||
## File structure
|
||||
|
||||
```
|
||||
scripts/k8s/
|
||||
├── deploy.sh # Creates namespace + secret, deploys via kustomize
|
||||
├── create-kind.sh # Local Kind cluster (auto-detects docker/podman)
|
||||
└── manifests/
|
||||
├── kustomization.yaml # Kustomize base
|
||||
├── configmap.yaml # openclaw.json + AGENTS.md
|
||||
├── deployment.yaml # Pod spec with security hardening
|
||||
├── pvc.yaml # 10Gi persistent storage
|
||||
└── service.yaml # ClusterIP on 18789
|
||||
```
|
||||
281
openclaw/docs/install/macos-vm.md
Normal file
281
openclaw/docs/install/macos-vm.md
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
---
|
||||
summary: "Run OpenClaw in a sandboxed macOS VM (local or hosted) when you need isolation or iMessage"
|
||||
read_when:
|
||||
- You want OpenClaw isolated from your main macOS environment
|
||||
- You want iMessage integration (BlueBubbles) in a sandbox
|
||||
- You want a resettable macOS environment you can clone
|
||||
- You want to compare local vs hosted macOS VM options
|
||||
title: "macOS VMs"
|
||||
---
|
||||
|
||||
# OpenClaw on macOS VMs (Sandboxing)
|
||||
|
||||
## Recommended default (most users)
|
||||
|
||||
- **Small Linux VPS** for an always-on Gateway and low cost. See [VPS hosting](/vps).
|
||||
- **Dedicated hardware** (Mac mini or Linux box) if you want full control and a **residential IP** for browser automation. Many sites block data center IPs, so local browsing often works better.
|
||||
- **Hybrid:** keep the Gateway on a cheap VPS, and connect your Mac as a **node** when you need browser/UI automation. See [Nodes](/nodes) and [Gateway remote](/gateway/remote).
|
||||
|
||||
Use a macOS VM when you specifically need macOS-only capabilities (iMessage/BlueBubbles) or want strict isolation from your daily Mac.
|
||||
|
||||
## macOS VM options
|
||||
|
||||
### Local VM on your Apple Silicon Mac (Lume)
|
||||
|
||||
Run OpenClaw in a sandboxed macOS VM on your existing Apple Silicon Mac using [Lume](https://cua.ai/docs/lume).
|
||||
|
||||
This gives you:
|
||||
|
||||
- Full macOS environment in isolation (your host stays clean)
|
||||
- iMessage support via BlueBubbles (impossible on Linux/Windows)
|
||||
- Instant reset by cloning VMs
|
||||
- No extra hardware or cloud costs
|
||||
|
||||
### Hosted Mac providers (cloud)
|
||||
|
||||
If you want macOS in the cloud, hosted Mac providers work too:
|
||||
|
||||
- [MacStadium](https://www.macstadium.com/) (hosted Macs)
|
||||
- Other hosted Mac vendors also work; follow their VM + SSH docs
|
||||
|
||||
Once you have SSH access to a macOS VM, continue at step 6 below.
|
||||
|
||||
---
|
||||
|
||||
## Quick path (Lume, experienced users)
|
||||
|
||||
1. Install Lume
|
||||
2. `lume create openclaw --os macos --ipsw latest`
|
||||
3. Complete Setup Assistant, enable Remote Login (SSH)
|
||||
4. `lume run openclaw --no-display`
|
||||
5. SSH in, install OpenClaw, configure channels
|
||||
6. Done
|
||||
|
||||
---
|
||||
|
||||
## What you need (Lume)
|
||||
|
||||
- Apple Silicon Mac (M1/M2/M3/M4)
|
||||
- macOS Sequoia or later on the host
|
||||
- ~60 GB free disk space per VM
|
||||
- ~20 minutes
|
||||
|
||||
---
|
||||
|
||||
## 1) Install Lume
|
||||
|
||||
```bash
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/lume/scripts/install.sh)"
|
||||
```
|
||||
|
||||
If `~/.local/bin` isn't in your PATH:
|
||||
|
||||
```bash
|
||||
echo 'export PATH="$PATH:$HOME/.local/bin"' >> ~/.zshrc && source ~/.zshrc
|
||||
```
|
||||
|
||||
Verify:
|
||||
|
||||
```bash
|
||||
lume --version
|
||||
```
|
||||
|
||||
Docs: [Lume Installation](https://cua.ai/docs/lume/guide/getting-started/installation)
|
||||
|
||||
---
|
||||
|
||||
## 2) Create the macOS VM
|
||||
|
||||
```bash
|
||||
lume create openclaw --os macos --ipsw latest
|
||||
```
|
||||
|
||||
This downloads macOS and creates the VM. A VNC window opens automatically.
|
||||
|
||||
Note: The download can take a while depending on your connection.
|
||||
|
||||
---
|
||||
|
||||
## 3) Complete Setup Assistant
|
||||
|
||||
In the VNC window:
|
||||
|
||||
1. Select language and region
|
||||
2. Skip Apple ID (or sign in if you want iMessage later)
|
||||
3. Create a user account (remember the username and password)
|
||||
4. Skip all optional features
|
||||
|
||||
After setup completes, enable SSH:
|
||||
|
||||
1. Open System Settings → General → Sharing
|
||||
2. Enable "Remote Login"
|
||||
|
||||
---
|
||||
|
||||
## 4) Get the VM IP address
|
||||
|
||||
```bash
|
||||
lume get openclaw
|
||||
```
|
||||
|
||||
Look for the IP address (usually `192.168.64.x`).
|
||||
|
||||
---
|
||||
|
||||
## 5) SSH into the VM
|
||||
|
||||
```bash
|
||||
ssh youruser@192.168.64.X
|
||||
```
|
||||
|
||||
Replace `youruser` with the account you created, and the IP with your VM's IP.
|
||||
|
||||
---
|
||||
|
||||
## 6) Install OpenClaw
|
||||
|
||||
Inside the VM:
|
||||
|
||||
```bash
|
||||
npm install -g openclaw@latest
|
||||
openclaw onboard --install-daemon
|
||||
```
|
||||
|
||||
Follow the onboarding prompts to set up your model provider (Anthropic, OpenAI, etc.).
|
||||
|
||||
---
|
||||
|
||||
## 7) Configure channels
|
||||
|
||||
Edit the config file:
|
||||
|
||||
```bash
|
||||
nano ~/.openclaw/openclaw.json
|
||||
```
|
||||
|
||||
Add your channels:
|
||||
|
||||
```json5
|
||||
{
|
||||
channels: {
|
||||
whatsapp: {
|
||||
dmPolicy: "allowlist",
|
||||
allowFrom: ["+15551234567"],
|
||||
},
|
||||
telegram: {
|
||||
botToken: "YOUR_BOT_TOKEN",
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Then login to WhatsApp (scan QR):
|
||||
|
||||
```bash
|
||||
openclaw channels login
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8) Run the VM headlessly
|
||||
|
||||
Stop the VM and restart without display:
|
||||
|
||||
```bash
|
||||
lume stop openclaw
|
||||
lume run openclaw --no-display
|
||||
```
|
||||
|
||||
The VM runs in the background. OpenClaw's daemon keeps the gateway running.
|
||||
|
||||
To check status:
|
||||
|
||||
```bash
|
||||
ssh youruser@192.168.64.X "openclaw status"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Bonus: iMessage integration
|
||||
|
||||
This is the killer feature of running on macOS. Use [BlueBubbles](https://bluebubbles.app) to add iMessage to OpenClaw.
|
||||
|
||||
Inside the VM:
|
||||
|
||||
1. Download BlueBubbles from bluebubbles.app
|
||||
2. Sign in with your Apple ID
|
||||
3. Enable the Web API and set a password
|
||||
4. Point BlueBubbles webhooks at your gateway (example: `https://your-gateway-host:3000/bluebubbles-webhook?password=<password>`)
|
||||
|
||||
Add to your OpenClaw config:
|
||||
|
||||
```json5
|
||||
{
|
||||
channels: {
|
||||
bluebubbles: {
|
||||
serverUrl: "http://localhost:1234",
|
||||
password: "your-api-password",
|
||||
webhookPath: "/bluebubbles-webhook",
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Restart the gateway. Now your agent can send and receive iMessages.
|
||||
|
||||
Full setup details: [BlueBubbles channel](/channels/bluebubbles)
|
||||
|
||||
---
|
||||
|
||||
## Save a golden image
|
||||
|
||||
Before customizing further, snapshot your clean state:
|
||||
|
||||
```bash
|
||||
lume stop openclaw
|
||||
lume clone openclaw openclaw-golden
|
||||
```
|
||||
|
||||
Reset anytime:
|
||||
|
||||
```bash
|
||||
lume stop openclaw && lume delete openclaw
|
||||
lume clone openclaw-golden openclaw
|
||||
lume run openclaw --no-display
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Running 24/7
|
||||
|
||||
Keep the VM running by:
|
||||
|
||||
- Keeping your Mac plugged in
|
||||
- Disabling sleep in System Settings → Energy Saver
|
||||
- Using `caffeinate` if needed
|
||||
|
||||
For true always-on, consider a dedicated Mac mini or a small VPS. See [VPS hosting](/vps).
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Problem | Solution |
|
||||
| ------------------------ | ---------------------------------------------------------------------------------- |
|
||||
| Can't SSH into VM | Check "Remote Login" is enabled in VM's System Settings |
|
||||
| VM IP not showing | Wait for VM to fully boot, run `lume get openclaw` again |
|
||||
| Lume command not found | Add `~/.local/bin` to your PATH |
|
||||
| WhatsApp QR not scanning | Ensure you're logged into the VM (not host) when running `openclaw channels login` |
|
||||
|
||||
---
|
||||
|
||||
## Related docs
|
||||
|
||||
- [VPS hosting](/vps)
|
||||
- [Nodes](/nodes)
|
||||
- [Gateway remote](/gateway/remote)
|
||||
- [BlueBubbles channel](/channels/bluebubbles)
|
||||
- [Lume Quickstart](https://cua.ai/docs/lume/guide/getting-started/quickstart)
|
||||
- [Lume CLI Reference](https://cua.ai/docs/lume/reference/cli-reference)
|
||||
- [Unattended VM Setup](https://cua.ai/docs/lume/guide/fundamentals/unattended-setup) (advanced)
|
||||
- [Docker Sandboxing](/install/docker) (alternative isolation approach)
|
||||
349
openclaw/docs/install/migrating-matrix.md
Normal file
349
openclaw/docs/install/migrating-matrix.md
Normal file
|
|
@ -0,0 +1,349 @@
|
|||
---
|
||||
summary: "How OpenClaw upgrades the previous Matrix plugin in place, including encrypted-state recovery limits and manual recovery steps."
|
||||
read_when:
|
||||
- Upgrading an existing Matrix installation
|
||||
- Migrating encrypted Matrix history and device state
|
||||
title: "Matrix migration"
|
||||
---
|
||||
|
||||
# Matrix migration
|
||||
|
||||
This page covers upgrades from the previous public `matrix` plugin to the current implementation.
|
||||
|
||||
For most users, the upgrade is in place:
|
||||
|
||||
- the plugin stays `@openclaw/matrix`
|
||||
- the channel stays `matrix`
|
||||
- your config stays under `channels.matrix`
|
||||
- cached credentials stay under `~/.openclaw/credentials/matrix/`
|
||||
- runtime state stays under `~/.openclaw/matrix/`
|
||||
|
||||
You do not need to rename config keys or reinstall the plugin under a new name.
|
||||
|
||||
## What the migration does automatically
|
||||
|
||||
When the gateway starts, and when you run [`openclaw doctor --fix`](/gateway/doctor), OpenClaw tries to repair old Matrix state automatically.
|
||||
Before any actionable Matrix migration step mutates on-disk state, OpenClaw creates or reuses a focused recovery snapshot.
|
||||
|
||||
When you use `openclaw update`, the exact trigger depends on how OpenClaw is installed:
|
||||
|
||||
- source installs run `openclaw doctor --fix` during the update flow, then restart the gateway by default
|
||||
- package-manager installs update the package, run a non-interactive doctor pass, then rely on the default gateway restart so startup can finish Matrix migration
|
||||
- if you use `openclaw update --no-restart`, startup-backed Matrix migration is deferred until you later run `openclaw doctor --fix` and restart the gateway
|
||||
|
||||
Automatic migration covers:
|
||||
|
||||
- creating or reusing a pre-migration snapshot under `~/Backups/openclaw-migrations/`
|
||||
- reusing your cached Matrix credentials
|
||||
- keeping the same account selection and `channels.matrix` config
|
||||
- moving the oldest flat Matrix sync store into the current account-scoped location
|
||||
- moving the oldest flat Matrix crypto store into the current account-scoped location when the target account can be resolved safely
|
||||
- extracting a previously saved Matrix room-key backup decryption key from the old rust crypto store, when that key exists locally
|
||||
- reusing the most complete existing token-hash storage root for the same Matrix account, homeserver, and user when the access token changes later
|
||||
- scanning sibling token-hash storage roots for pending encrypted-state restore metadata when the Matrix access token changed but the account/device identity stayed the same
|
||||
- restoring backed-up room keys into the new crypto store on the next Matrix startup
|
||||
|
||||
Snapshot details:
|
||||
|
||||
- OpenClaw writes a marker file at `~/.openclaw/matrix/migration-snapshot.json` after a successful snapshot so later startup and repair passes can reuse the same archive.
|
||||
- These automatic Matrix migration snapshots back up config + state only (`includeWorkspace: false`).
|
||||
- If Matrix only has warning-only migration state, for example because `userId` or `accessToken` is still missing, OpenClaw does not create the snapshot yet because no Matrix mutation is actionable.
|
||||
- If the snapshot step fails, OpenClaw skips Matrix migration for that run instead of mutating state without a recovery point.
|
||||
|
||||
About multi-account upgrades:
|
||||
|
||||
- the oldest flat Matrix store (`~/.openclaw/matrix/bot-storage.json` and `~/.openclaw/matrix/crypto/`) came from a single-store layout, so OpenClaw can only migrate it into one resolved Matrix account target
|
||||
- already account-scoped legacy Matrix stores are detected and prepared per configured Matrix account
|
||||
|
||||
## What the migration cannot do automatically
|
||||
|
||||
The previous public Matrix plugin did **not** automatically create Matrix room-key backups. It persisted local crypto state and requested device verification, but it did not guarantee that your room keys were backed up to the homeserver.
|
||||
|
||||
That means some encrypted installs can only be migrated partially.
|
||||
|
||||
OpenClaw cannot automatically recover:
|
||||
|
||||
- local-only room keys that were never backed up
|
||||
- encrypted state when the target Matrix account cannot be resolved yet because `homeserver`, `userId`, or `accessToken` are still unavailable
|
||||
- automatic migration of one shared flat Matrix store when multiple Matrix accounts are configured but `channels.matrix.defaultAccount` is not set
|
||||
- custom plugin path installs that are pinned to a repo path instead of the standard Matrix package
|
||||
- a missing recovery key when the old store had backed-up keys but did not keep the decryption key locally
|
||||
|
||||
Current warning scope:
|
||||
|
||||
- custom Matrix plugin path installs are surfaced by both gateway startup and `openclaw doctor`
|
||||
|
||||
If your old installation had local-only encrypted history that was never backed up, some older encrypted messages may remain unreadable after the upgrade.
|
||||
|
||||
## Recommended upgrade flow
|
||||
|
||||
1. Update OpenClaw and the Matrix plugin normally.
|
||||
Prefer plain `openclaw update` without `--no-restart` so startup can finish the Matrix migration immediately.
|
||||
2. Run:
|
||||
|
||||
```bash
|
||||
openclaw doctor --fix
|
||||
```
|
||||
|
||||
If Matrix has actionable migration work, doctor will create or reuse the pre-migration snapshot first and print the archive path.
|
||||
|
||||
3. Start or restart the gateway.
|
||||
4. Check current verification and backup state:
|
||||
|
||||
```bash
|
||||
openclaw matrix verify status
|
||||
openclaw matrix verify backup status
|
||||
```
|
||||
|
||||
5. If OpenClaw tells you a recovery key is needed, run:
|
||||
|
||||
```bash
|
||||
openclaw matrix verify backup restore --recovery-key "<your-recovery-key>"
|
||||
```
|
||||
|
||||
6. If this device is still unverified, run:
|
||||
|
||||
```bash
|
||||
openclaw matrix verify device "<your-recovery-key>"
|
||||
```
|
||||
|
||||
7. If you are intentionally abandoning unrecoverable old history and want a fresh backup baseline for future messages, run:
|
||||
|
||||
```bash
|
||||
openclaw matrix verify backup reset --yes
|
||||
```
|
||||
|
||||
8. If no server-side key backup exists yet, create one for future recoveries:
|
||||
|
||||
```bash
|
||||
openclaw matrix verify bootstrap
|
||||
```
|
||||
|
||||
## How encrypted migration works
|
||||
|
||||
Encrypted migration is a two-stage process:
|
||||
|
||||
1. Startup or `openclaw doctor --fix` creates or reuses the pre-migration snapshot if encrypted migration is actionable.
|
||||
2. Startup or `openclaw doctor --fix` inspects the old Matrix crypto store through the active Matrix plugin install.
|
||||
3. If a backup decryption key is found, OpenClaw writes it into the new recovery-key flow and marks room-key restore as pending.
|
||||
4. On the next Matrix startup, OpenClaw restores backed-up room keys into the new crypto store automatically.
|
||||
|
||||
If the old store reports room keys that were never backed up, OpenClaw warns instead of pretending recovery succeeded.
|
||||
|
||||
## Common messages and what they mean
|
||||
|
||||
### Upgrade and detection messages
|
||||
|
||||
`Matrix plugin upgraded in place.`
|
||||
|
||||
- Meaning: the old on-disk Matrix state was detected and migrated into the current layout.
|
||||
- What to do: nothing unless the same output also includes warnings.
|
||||
|
||||
`Matrix migration snapshot created before applying Matrix upgrades.`
|
||||
|
||||
- Meaning: OpenClaw created a recovery archive before mutating Matrix state.
|
||||
- What to do: keep the printed archive path until you confirm migration succeeded.
|
||||
|
||||
`Matrix migration snapshot reused before applying Matrix upgrades.`
|
||||
|
||||
- Meaning: OpenClaw found an existing Matrix migration snapshot marker and reused that archive instead of creating a duplicate backup.
|
||||
- What to do: keep the printed archive path until you confirm migration succeeded.
|
||||
|
||||
`Legacy Matrix state detected at ... but channels.matrix is not configured yet.`
|
||||
|
||||
- Meaning: old Matrix state exists, but OpenClaw cannot map it to a current Matrix account because Matrix is not configured.
|
||||
- What to do: configure `channels.matrix`, then rerun `openclaw doctor --fix` or restart the gateway.
|
||||
|
||||
`Legacy Matrix state detected at ... but the new account-scoped target could not be resolved yet (need homeserver, userId, and access token for channels.matrix...).`
|
||||
|
||||
- Meaning: OpenClaw found old state, but it still cannot determine the exact current account/device root.
|
||||
- What to do: start the gateway once with a working Matrix login, or rerun `openclaw doctor --fix` after cached credentials exist.
|
||||
|
||||
`Legacy Matrix state detected at ... but multiple Matrix accounts are configured and channels.matrix.defaultAccount is not set.`
|
||||
|
||||
- Meaning: OpenClaw found one shared flat Matrix store, but it refuses to guess which named Matrix account should receive it.
|
||||
- What to do: set `channels.matrix.defaultAccount` to the intended account, then rerun `openclaw doctor --fix` or restart the gateway.
|
||||
|
||||
`Matrix legacy sync store not migrated because the target already exists (...)`
|
||||
|
||||
- Meaning: the new account-scoped location already has a sync or crypto store, so OpenClaw did not overwrite it automatically.
|
||||
- What to do: verify that the current account is the correct one before manually removing or moving the conflicting target.
|
||||
|
||||
`Failed migrating Matrix legacy sync store (...)` or `Failed migrating Matrix legacy crypto store (...)`
|
||||
|
||||
- Meaning: OpenClaw tried to move old Matrix state but the filesystem operation failed.
|
||||
- What to do: inspect filesystem permissions and disk state, then rerun `openclaw doctor --fix`.
|
||||
|
||||
`Legacy Matrix encrypted state detected at ... but channels.matrix is not configured yet.`
|
||||
|
||||
- Meaning: OpenClaw found an old encrypted Matrix store, but there is no current Matrix config to attach it to.
|
||||
- What to do: configure `channels.matrix`, then rerun `openclaw doctor --fix` or restart the gateway.
|
||||
|
||||
`Legacy Matrix encrypted state detected at ... but the account-scoped target could not be resolved yet (need homeserver, userId, and access token for channels.matrix...).`
|
||||
|
||||
- Meaning: the encrypted store exists, but OpenClaw cannot safely decide which current account/device it belongs to.
|
||||
- What to do: start the gateway once with a working Matrix login, or rerun `openclaw doctor --fix` after cached credentials are available.
|
||||
|
||||
`Legacy Matrix encrypted state detected at ... but multiple Matrix accounts are configured and channels.matrix.defaultAccount is not set.`
|
||||
|
||||
- Meaning: OpenClaw found one shared flat legacy crypto store, but it refuses to guess which named Matrix account should receive it.
|
||||
- What to do: set `channels.matrix.defaultAccount` to the intended account, then rerun `openclaw doctor --fix` or restart the gateway.
|
||||
|
||||
`Matrix migration warnings are present, but no on-disk Matrix mutation is actionable yet. No pre-migration snapshot was needed.`
|
||||
|
||||
- Meaning: OpenClaw detected old Matrix state, but the migration is still blocked on missing identity or credential data.
|
||||
- What to do: finish Matrix login or config setup, then rerun `openclaw doctor --fix` or restart the gateway.
|
||||
|
||||
`Legacy Matrix encrypted state was detected, but the Matrix plugin helper is unavailable. Install or repair @openclaw/matrix so OpenClaw can inspect the old rust crypto store before upgrading.`
|
||||
|
||||
- Meaning: OpenClaw found old encrypted Matrix state, but it could not load the helper entrypoint from the Matrix plugin that normally inspects that store.
|
||||
- What to do: reinstall or repair the Matrix plugin (`openclaw plugins install @openclaw/matrix`, or `openclaw plugins install ./path/to/local/matrix-plugin` for a repo checkout), then rerun `openclaw doctor --fix` or restart the gateway.
|
||||
|
||||
`Matrix plugin helper path is unsafe: ... Reinstall @openclaw/matrix and try again.`
|
||||
|
||||
- Meaning: OpenClaw found a helper file path that escapes the plugin root or fails plugin boundary checks, so it refused to import it.
|
||||
- What to do: reinstall the Matrix plugin from a trusted path, then rerun `openclaw doctor --fix` or restart the gateway.
|
||||
|
||||
`- Failed creating a Matrix migration snapshot before repair: ...`
|
||||
|
||||
`- Skipping Matrix migration changes for now. Resolve the snapshot failure, then rerun "openclaw doctor --fix".`
|
||||
|
||||
- Meaning: OpenClaw refused to mutate Matrix state because it could not create the recovery snapshot first.
|
||||
- What to do: resolve the backup error, then rerun `openclaw doctor --fix` or restart the gateway.
|
||||
|
||||
`Failed migrating legacy Matrix client storage: ...`
|
||||
|
||||
- Meaning: the Matrix client-side fallback found old flat storage, but the move failed. OpenClaw now aborts that fallback instead of silently starting with a fresh store.
|
||||
- What to do: inspect filesystem permissions or conflicts, keep the old state intact, and retry after fixing the error.
|
||||
|
||||
`Matrix is installed from a custom path: ...`
|
||||
|
||||
- Meaning: Matrix is pinned to a path install, so mainline updates do not automatically replace it with the repo's standard Matrix package.
|
||||
- What to do: reinstall with `openclaw plugins install @openclaw/matrix` when you want to return to the default Matrix plugin.
|
||||
|
||||
### Encrypted-state recovery messages
|
||||
|
||||
`matrix: restored X/Y room key(s) from legacy encrypted-state backup`
|
||||
|
||||
- Meaning: backed-up room keys were restored successfully into the new crypto store.
|
||||
- What to do: usually nothing.
|
||||
|
||||
`matrix: N legacy local-only room key(s) were never backed up and could not be restored automatically`
|
||||
|
||||
- Meaning: some old room keys existed only in the old local store and had never been uploaded to Matrix backup.
|
||||
- What to do: expect some old encrypted history to remain unavailable unless you can recover those keys manually from another verified client.
|
||||
|
||||
`Legacy Matrix encrypted state for account "..." has backed-up room keys, but no local backup decryption key was found. Ask the operator to run "openclaw matrix verify backup restore --recovery-key <key>" after upgrade if they have the recovery key.`
|
||||
|
||||
- Meaning: backup exists, but OpenClaw could not recover the recovery key automatically.
|
||||
- What to do: run `openclaw matrix verify backup restore --recovery-key "<your-recovery-key>"`.
|
||||
|
||||
`Failed inspecting legacy Matrix encrypted state for account "..." (...): ...`
|
||||
|
||||
- Meaning: OpenClaw found the old encrypted store, but it could not inspect it safely enough to prepare recovery.
|
||||
- What to do: rerun `openclaw doctor --fix`. If it repeats, keep the old state directory intact and recover using another verified Matrix client plus `openclaw matrix verify backup restore --recovery-key "<your-recovery-key>"`.
|
||||
|
||||
`Legacy Matrix backup key was found for account "...", but .../recovery-key.json already contains a different recovery key. Leaving the existing file unchanged.`
|
||||
|
||||
- Meaning: OpenClaw detected a backup key conflict and refused to overwrite the current recovery-key file automatically.
|
||||
- What to do: verify which recovery key is correct before retrying any restore command.
|
||||
|
||||
`Legacy Matrix encrypted state for account "..." cannot be fully converted automatically because the old rust crypto store does not expose all local room keys for export.`
|
||||
|
||||
- Meaning: this is the hard limit of the old storage format.
|
||||
- What to do: backed-up keys can still be restored, but local-only encrypted history may remain unavailable.
|
||||
|
||||
`matrix: failed restoring room keys from legacy encrypted-state backup: ...`
|
||||
|
||||
- Meaning: the new plugin attempted restore but Matrix returned an error.
|
||||
- What to do: run `openclaw matrix verify backup status`, then retry with `openclaw matrix verify backup restore --recovery-key "<your-recovery-key>"` if needed.
|
||||
|
||||
### Manual recovery messages
|
||||
|
||||
`Backup key is not loaded on this device. Run 'openclaw matrix verify backup restore' to load it and restore old room keys.`
|
||||
|
||||
- Meaning: OpenClaw knows you should have a backup key, but it is not active on this device.
|
||||
- What to do: run `openclaw matrix verify backup restore`, or pass `--recovery-key` if needed.
|
||||
|
||||
`Store a recovery key with 'openclaw matrix verify device <key>', then run 'openclaw matrix verify backup restore'.`
|
||||
|
||||
- Meaning: this device does not currently have the recovery key stored.
|
||||
- What to do: verify the device with your recovery key first, then restore the backup.
|
||||
|
||||
`Backup key mismatch on this device. Re-run 'openclaw matrix verify device <key>' with the matching recovery key.`
|
||||
|
||||
- Meaning: the stored key does not match the active Matrix backup.
|
||||
- What to do: rerun `openclaw matrix verify device "<your-recovery-key>"` with the correct key.
|
||||
|
||||
If you accept losing unrecoverable old encrypted history, you can instead reset the
|
||||
current backup baseline with `openclaw matrix verify backup reset --yes`. When the
|
||||
stored backup secret is broken, that reset may also recreate secret storage so the
|
||||
new backup key can load correctly after restart.
|
||||
|
||||
`Backup trust chain is not verified on this device. Re-run 'openclaw matrix verify device <key>'.`
|
||||
|
||||
- Meaning: the backup exists, but this device does not trust the cross-signing chain strongly enough yet.
|
||||
- What to do: rerun `openclaw matrix verify device "<your-recovery-key>"`.
|
||||
|
||||
`Matrix recovery key is required`
|
||||
|
||||
- Meaning: you tried a recovery step without supplying a recovery key when one was required.
|
||||
- What to do: rerun the command with your recovery key.
|
||||
|
||||
`Invalid Matrix recovery key: ...`
|
||||
|
||||
- Meaning: the provided key could not be parsed or did not match the expected format.
|
||||
- What to do: retry with the exact recovery key from your Matrix client or recovery-key file.
|
||||
|
||||
`Matrix device is still unverified after applying recovery key. Verify your recovery key and ensure cross-signing is available.`
|
||||
|
||||
- Meaning: the key was applied, but the device still could not complete verification.
|
||||
- What to do: confirm you used the correct key and that cross-signing is available on the account, then retry.
|
||||
|
||||
`Matrix key backup is not active on this device after loading from secret storage.`
|
||||
|
||||
- Meaning: secret storage did not produce an active backup session on this device.
|
||||
- What to do: verify the device first, then recheck with `openclaw matrix verify backup status`.
|
||||
|
||||
`Matrix crypto backend cannot load backup keys from secret storage. Verify this device with 'openclaw matrix verify device <key>' first.`
|
||||
|
||||
- Meaning: this device cannot restore from secret storage until device verification is complete.
|
||||
- What to do: run `openclaw matrix verify device "<your-recovery-key>"` first.
|
||||
|
||||
### Custom plugin install messages
|
||||
|
||||
`Matrix is installed from a custom path that no longer exists: ...`
|
||||
|
||||
- Meaning: your plugin install record points at a local path that is gone.
|
||||
- What to do: reinstall with `openclaw plugins install @openclaw/matrix`, or if you are running from a repo checkout, `openclaw plugins install ./path/to/local/matrix-plugin`.
|
||||
|
||||
## If encrypted history still does not come back
|
||||
|
||||
Run these checks in order:
|
||||
|
||||
```bash
|
||||
openclaw matrix verify status --verbose
|
||||
openclaw matrix verify backup status --verbose
|
||||
openclaw matrix verify backup restore --recovery-key "<your-recovery-key>" --verbose
|
||||
```
|
||||
|
||||
If the backup restores successfully but some old rooms are still missing history, those missing keys were probably never backed up by the previous plugin.
|
||||
|
||||
## If you want to start fresh for future messages
|
||||
|
||||
If you accept losing unrecoverable old encrypted history and only want a clean backup baseline going forward, run these commands in order:
|
||||
|
||||
```bash
|
||||
openclaw matrix verify backup reset --yes
|
||||
openclaw matrix verify backup status --verbose
|
||||
openclaw matrix verify status
|
||||
```
|
||||
|
||||
If the device is still unverified after that, finish verification from your Matrix client by comparing the SAS emoji or decimal codes and confirming that they match.
|
||||
|
||||
## Related pages
|
||||
|
||||
- [Matrix](/channels/matrix)
|
||||
- [Doctor](/gateway/doctor)
|
||||
- [Migrating](/install/migrating)
|
||||
- [Plugins](/tools/plugin)
|
||||
112
openclaw/docs/install/migrating.md
Normal file
112
openclaw/docs/install/migrating.md
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
---
|
||||
summary: "Move (migrate) an OpenClaw install from one machine to another"
|
||||
read_when:
|
||||
- You are moving OpenClaw to a new laptop/server
|
||||
- You want to preserve sessions, auth, and channel logins (WhatsApp, etc.)
|
||||
title: "Migration Guide"
|
||||
---
|
||||
|
||||
# Migrating OpenClaw to a New Machine
|
||||
|
||||
This guide moves an OpenClaw gateway to a new machine without redoing onboarding.
|
||||
|
||||
## What Gets Migrated
|
||||
|
||||
When you copy the **state directory** (`~/.openclaw/` by default) and your **workspace**, you preserve:
|
||||
|
||||
- **Config** -- `openclaw.json` and all gateway settings
|
||||
- **Auth** -- per-agent `auth-profiles.json` (API keys + OAuth), plus any channel/provider state under `credentials/`
|
||||
- **Sessions** -- conversation history and agent state
|
||||
- **Channel state** -- WhatsApp login, Telegram session, etc.
|
||||
- **Workspace files** -- `MEMORY.md`, `USER.md`, skills, and prompts
|
||||
|
||||
<Tip>
|
||||
Run `openclaw status` on the old machine to confirm your state directory path.
|
||||
Custom profiles use `~/.openclaw-<profile>/` or a path set via `OPENCLAW_STATE_DIR`.
|
||||
</Tip>
|
||||
|
||||
## Migration Steps
|
||||
|
||||
<Steps>
|
||||
<Step title="Stop the gateway and back up">
|
||||
On the **old** machine, stop the gateway so files are not changing mid-copy, then archive:
|
||||
|
||||
```bash
|
||||
openclaw gateway stop
|
||||
cd ~
|
||||
tar -czf openclaw-state.tgz .openclaw
|
||||
```
|
||||
|
||||
If you use multiple profiles (e.g. `~/.openclaw-work`), archive each separately.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Install OpenClaw on the new machine">
|
||||
[Install](/install) the CLI (and Node if needed) on the new machine.
|
||||
It is fine if onboarding creates a fresh `~/.openclaw/` -- you will overwrite it next.
|
||||
</Step>
|
||||
|
||||
<Step title="Copy state directory and workspace">
|
||||
Transfer the archive via `scp`, `rsync -a`, or an external drive, then extract:
|
||||
|
||||
```bash
|
||||
cd ~
|
||||
tar -xzf openclaw-state.tgz
|
||||
```
|
||||
|
||||
Ensure hidden directories were included and file ownership matches the user that will run the gateway.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Run doctor and verify">
|
||||
On the new machine, run [Doctor](/gateway/doctor) to apply config migrations and repair services:
|
||||
|
||||
```bash
|
||||
openclaw doctor
|
||||
openclaw gateway restart
|
||||
openclaw status
|
||||
```
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Profile or state-dir mismatch">
|
||||
If the old gateway used `--profile` or `OPENCLAW_STATE_DIR` and the new one does not,
|
||||
channels will appear logged out and sessions will be empty.
|
||||
Launch the gateway with the **same** profile or state-dir you migrated, then rerun `openclaw doctor`.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Copying only openclaw.json">
|
||||
The config file alone is not enough. Model auth profiles live under
|
||||
`agents/<agentId>/agent/auth-profiles.json`, and channel/provider state still
|
||||
lives under `credentials/`. Always migrate the **entire** state directory.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Permissions and ownership">
|
||||
If you copied as root or switched users, the gateway may fail to read credentials.
|
||||
Ensure the state directory and workspace are owned by the user running the gateway.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Remote mode">
|
||||
If your UI points at a **remote** gateway, the remote host owns sessions and workspace.
|
||||
Migrate the gateway host itself, not your local laptop. See [FAQ](/help/faq#where-things-live-on-disk).
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Secrets in backups">
|
||||
The state directory contains auth profiles, channel credentials, and other
|
||||
provider state.
|
||||
Store backups encrypted, avoid insecure transfer channels, and rotate keys if you suspect exposure.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Verification Checklist
|
||||
|
||||
On the new machine, confirm:
|
||||
|
||||
- [ ] `openclaw status` shows the gateway running
|
||||
- [ ] Channels are still connected (no re-pairing needed)
|
||||
- [ ] The dashboard opens and shows existing sessions
|
||||
- [ ] Workspace files (memory, configs) are present
|
||||
89
openclaw/docs/install/nix.md
Normal file
89
openclaw/docs/install/nix.md
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
---
|
||||
summary: "Install OpenClaw declaratively with Nix"
|
||||
read_when:
|
||||
- You want reproducible, rollback-able installs
|
||||
- You're already using Nix/NixOS/Home Manager
|
||||
- You want everything pinned and managed declaratively
|
||||
title: "Nix"
|
||||
---
|
||||
|
||||
# Nix Installation
|
||||
|
||||
Install OpenClaw declaratively with **[nix-openclaw](https://github.com/openclaw/nix-openclaw)** -- a batteries-included Home Manager module.
|
||||
|
||||
<Info>
|
||||
The [nix-openclaw](https://github.com/openclaw/nix-openclaw) repo is the source of truth for Nix installation. This page is a quick overview.
|
||||
</Info>
|
||||
|
||||
## What You Get
|
||||
|
||||
- Gateway + macOS app + tools (whisper, spotify, cameras) -- all pinned
|
||||
- Launchd service that survives reboots
|
||||
- Plugin system with declarative config
|
||||
- Instant rollback: `home-manager switch --rollback`
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Determinate Nix">
|
||||
If Nix is not already installed, follow the [Determinate Nix installer](https://github.com/DeterminateSystems/nix-installer) instructions.
|
||||
</Step>
|
||||
<Step title="Create a local flake">
|
||||
Use the agent-first template from the nix-openclaw repo:
|
||||
```bash
|
||||
mkdir -p ~/code/openclaw-local
|
||||
# Copy templates/agent-first/flake.nix from the nix-openclaw repo
|
||||
```
|
||||
</Step>
|
||||
<Step title="Configure secrets">
|
||||
Set up your messaging bot token and model provider API key. Plain files at `~/.secrets/` work fine.
|
||||
</Step>
|
||||
<Step title="Fill in template placeholders and switch">
|
||||
```bash
|
||||
home-manager switch
|
||||
```
|
||||
</Step>
|
||||
<Step title="Verify">
|
||||
Confirm the launchd service is running and your bot responds to messages.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
See the [nix-openclaw README](https://github.com/openclaw/nix-openclaw) for full module options and examples.
|
||||
|
||||
## Nix Mode Runtime Behavior
|
||||
|
||||
When `OPENCLAW_NIX_MODE=1` is set (automatic with nix-openclaw), OpenClaw enters a deterministic mode that disables auto-install flows.
|
||||
|
||||
You can also set it manually:
|
||||
|
||||
```bash
|
||||
export OPENCLAW_NIX_MODE=1
|
||||
```
|
||||
|
||||
On macOS, the GUI app does not automatically inherit shell environment variables. Enable Nix mode via defaults instead:
|
||||
|
||||
```bash
|
||||
defaults write ai.openclaw.mac openclaw.nixMode -bool true
|
||||
```
|
||||
|
||||
### What changes in Nix mode
|
||||
|
||||
- Auto-install and self-mutation flows are disabled
|
||||
- Missing dependencies surface Nix-specific remediation messages
|
||||
- UI surfaces a read-only Nix mode banner
|
||||
|
||||
### Config and state paths
|
||||
|
||||
OpenClaw reads JSON5 config from `OPENCLAW_CONFIG_PATH` and stores mutable data in `OPENCLAW_STATE_DIR`. When running under Nix, set these explicitly to Nix-managed locations so runtime state and config stay out of the immutable store.
|
||||
|
||||
| Variable | Default |
|
||||
| ---------------------- | --------------------------------------- |
|
||||
| `OPENCLAW_HOME` | `HOME` / `USERPROFILE` / `os.homedir()` |
|
||||
| `OPENCLAW_STATE_DIR` | `~/.openclaw` |
|
||||
| `OPENCLAW_CONFIG_PATH` | `$OPENCLAW_STATE_DIR/openclaw.json` |
|
||||
|
||||
## Related
|
||||
|
||||
- [nix-openclaw](https://github.com/openclaw/nix-openclaw) -- full setup guide
|
||||
- [Wizard](/start/wizard) -- non-Nix CLI setup
|
||||
- [Docker](/install/docker) -- containerized setup
|
||||
144
openclaw/docs/install/node.md
Normal file
144
openclaw/docs/install/node.md
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
---
|
||||
title: "Node.js"
|
||||
summary: "Install and configure Node.js for OpenClaw — version requirements, install options, and PATH troubleshooting"
|
||||
read_when:
|
||||
- "You need to install Node.js before installing OpenClaw"
|
||||
- "You installed OpenClaw but `openclaw` is command not found"
|
||||
- "npm install -g fails with permissions or PATH issues"
|
||||
---
|
||||
|
||||
# Node.js
|
||||
|
||||
OpenClaw requires **Node 22.14 or newer**. **Node 24 is the default and recommended runtime** for installs, CI, and release workflows. Node 22 remains supported via the active LTS line. The [installer script](/install#alternative-install-methods) will detect and install Node automatically — this page is for when you want to set up Node yourself and make sure everything is wired up correctly (versions, PATH, global installs).
|
||||
|
||||
## Check your version
|
||||
|
||||
```bash
|
||||
node -v
|
||||
```
|
||||
|
||||
If this prints `v24.x.x` or higher, you're on the recommended default. If it prints `v22.14.x` or higher, you're on the supported Node 22 LTS path, but we still recommend upgrading to Node 24 when convenient. If Node isn't installed or the version is too old, pick an install method below.
|
||||
|
||||
## Install Node
|
||||
|
||||
<Tabs>
|
||||
<Tab title="macOS">
|
||||
**Homebrew** (recommended):
|
||||
|
||||
```bash
|
||||
brew install node
|
||||
```
|
||||
|
||||
Or download the macOS installer from [nodejs.org](https://nodejs.org/).
|
||||
|
||||
</Tab>
|
||||
<Tab title="Linux">
|
||||
**Ubuntu / Debian:**
|
||||
|
||||
```bash
|
||||
curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
|
||||
sudo apt-get install -y nodejs
|
||||
```
|
||||
|
||||
**Fedora / RHEL:**
|
||||
|
||||
```bash
|
||||
sudo dnf install nodejs
|
||||
```
|
||||
|
||||
Or use a version manager (see below).
|
||||
|
||||
</Tab>
|
||||
<Tab title="Windows">
|
||||
**winget** (recommended):
|
||||
|
||||
```powershell
|
||||
winget install OpenJS.NodeJS.LTS
|
||||
```
|
||||
|
||||
**Chocolatey:**
|
||||
|
||||
```powershell
|
||||
choco install nodejs-lts
|
||||
```
|
||||
|
||||
Or download the Windows installer from [nodejs.org](https://nodejs.org/).
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<Accordion title="Using a version manager (nvm, fnm, mise, asdf)">
|
||||
Version managers let you switch between Node versions easily. Popular options:
|
||||
|
||||
- [**fnm**](https://github.com/Schniz/fnm) — fast, cross-platform
|
||||
- [**nvm**](https://github.com/nvm-sh/nvm) — widely used on macOS/Linux
|
||||
- [**mise**](https://mise.jdx.dev/) — polyglot (Node, Python, Ruby, etc.)
|
||||
|
||||
Example with fnm:
|
||||
|
||||
```bash
|
||||
fnm install 24
|
||||
fnm use 24
|
||||
```
|
||||
|
||||
<Warning>
|
||||
Make sure your version manager is initialized in your shell startup file (`~/.zshrc` or `~/.bashrc`). If it isn't, `openclaw` may not be found in new terminal sessions because the PATH won't include Node's bin directory.
|
||||
</Warning>
|
||||
</Accordion>
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### `openclaw: command not found`
|
||||
|
||||
This almost always means npm's global bin directory isn't on your PATH.
|
||||
|
||||
<Steps>
|
||||
<Step title="Find your global npm prefix">
|
||||
```bash
|
||||
npm prefix -g
|
||||
```
|
||||
</Step>
|
||||
<Step title="Check if it's on your PATH">
|
||||
```bash
|
||||
echo "$PATH"
|
||||
```
|
||||
|
||||
Look for `<npm-prefix>/bin` (macOS/Linux) or `<npm-prefix>` (Windows) in the output.
|
||||
|
||||
</Step>
|
||||
<Step title="Add it to your shell startup file">
|
||||
<Tabs>
|
||||
<Tab title="macOS / Linux">
|
||||
Add to `~/.zshrc` or `~/.bashrc`:
|
||||
|
||||
```bash
|
||||
export PATH="$(npm prefix -g)/bin:$PATH"
|
||||
```
|
||||
|
||||
Then open a new terminal (or run `rehash` in zsh / `hash -r` in bash).
|
||||
</Tab>
|
||||
<Tab title="Windows">
|
||||
Add the output of `npm prefix -g` to your system PATH via Settings → System → Environment Variables.
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
### Permission errors on `npm install -g` (Linux)
|
||||
|
||||
If you see `EACCES` errors, switch npm's global prefix to a user-writable directory:
|
||||
|
||||
```bash
|
||||
mkdir -p "$HOME/.npm-global"
|
||||
npm config set prefix "$HOME/.npm-global"
|
||||
export PATH="$HOME/.npm-global/bin:$PATH"
|
||||
```
|
||||
|
||||
Add the `export PATH=...` line to your `~/.bashrc` or `~/.zshrc` to make it permanent.
|
||||
|
||||
## Related
|
||||
|
||||
- [Install Overview](/install) — all installation methods
|
||||
- [Updating](/install/updating) — keeping OpenClaw up to date
|
||||
- [Getting Started](/start/getting-started) — first steps after install
|
||||
42
openclaw/docs/install/northflank.mdx
Normal file
42
openclaw/docs/install/northflank.mdx
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
summary: "Deploy OpenClaw on Northflank with one-click template"
|
||||
read_when:
|
||||
- Deploying OpenClaw to Northflank
|
||||
- You want a one-click cloud deploy with browser-based Control UI
|
||||
title: "Northflank"
|
||||
---
|
||||
|
||||
Deploy OpenClaw on Northflank with a one-click template and access it through the web Control UI.
|
||||
This is the easiest "no terminal on the server" path: Northflank runs the Gateway for you.
|
||||
|
||||
## How to get started
|
||||
|
||||
1. Click [Deploy OpenClaw](https://northflank.com/stacks/deploy-openclaw) to open the template.
|
||||
2. Create an [account on Northflank](https://app.northflank.com/signup) if you don't already have one.
|
||||
3. Click **Deploy OpenClaw now**.
|
||||
4. Set the required environment variable: `OPENCLAW_GATEWAY_TOKEN` (use a strong random value).
|
||||
5. Click **Deploy stack** to build and run the OpenClaw template.
|
||||
6. Wait for the deployment to complete, then click **View resources**.
|
||||
7. Open the OpenClaw service.
|
||||
8. Open the public OpenClaw URL at `/openclaw` and connect using the configured shared secret. This template uses `OPENCLAW_GATEWAY_TOKEN` by default; if you replace it with password auth, use that password instead.
|
||||
|
||||
## What you get
|
||||
|
||||
- Hosted OpenClaw Gateway + Control UI
|
||||
- Persistent storage via Northflank Volume (`/data`) so `openclaw.json`,
|
||||
per-agent `auth-profiles.json`, channel/provider state, sessions, and
|
||||
workspace survive redeploys
|
||||
|
||||
## Connect a channel
|
||||
|
||||
Use the Control UI at `/openclaw` or run `openclaw onboard` via SSH for channel setup instructions:
|
||||
|
||||
- [Telegram](/channels/telegram) (fastest — just a bot token)
|
||||
- [Discord](/channels/discord)
|
||||
- [All channels](/channels)
|
||||
|
||||
## Next steps
|
||||
|
||||
- Set up messaging channels: [Channels](/channels)
|
||||
- Configure the Gateway: [Gateway configuration](/gateway/configuration)
|
||||
- Keep OpenClaw up to date: [Updating](/install/updating)
|
||||
158
openclaw/docs/install/oracle.md
Normal file
158
openclaw/docs/install/oracle.md
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
---
|
||||
summary: "Host OpenClaw on Oracle Cloud's Always Free ARM tier"
|
||||
read_when:
|
||||
- Setting up OpenClaw on Oracle Cloud
|
||||
- Looking for free VPS hosting for OpenClaw
|
||||
- Want 24/7 OpenClaw on a small server
|
||||
title: "Oracle Cloud"
|
||||
---
|
||||
|
||||
# Oracle Cloud
|
||||
|
||||
Run a persistent OpenClaw Gateway on Oracle Cloud's **Always Free** ARM tier (up to 4 OCPU, 24 GB RAM, 200 GB storage) at no cost.
|
||||
|
||||
## 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))
|
||||
- An SSH key pair
|
||||
- About 30 minutes
|
||||
|
||||
## Setup
|
||||
|
||||
<Steps>
|
||||
<Step title="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** and 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.
|
||||
</Tip>
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Connect and update the system">
|
||||
```bash
|
||||
ssh ubuntu@YOUR_PUBLIC_IP
|
||||
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
sudo apt install -y build-essential
|
||||
```
|
||||
|
||||
`build-essential` is required for ARM compilation of some dependencies.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Configure user and hostname">
|
||||
```bash
|
||||
sudo hostnamectl set-hostname openclaw
|
||||
sudo passwd ubuntu
|
||||
sudo loginctl enable-linger ubuntu
|
||||
```
|
||||
|
||||
Enabling linger keeps user services running after logout.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Install Tailscale">
|
||||
```bash
|
||||
curl -fsSL https://tailscale.com/install.sh | sh
|
||||
sudo tailscale up --ssh --hostname=openclaw
|
||||
```
|
||||
|
||||
From now on, connect via Tailscale: `ssh ubuntu@openclaw`.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="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**.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Configure the gateway">
|
||||
Use token auth with Tailscale Serve for secure remote access.
|
||||
|
||||
```bash
|
||||
openclaw config set gateway.bind loopback
|
||||
openclaw config set gateway.auth.mode token
|
||||
openclaw doctor --generate-gateway-token
|
||||
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.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Lock down VCN security">
|
||||
Block all traffic except Tailscale at the network edge:
|
||||
|
||||
1. Go to **Networking > Virtual Cloud Networks** in the OCI Console.
|
||||
2. Click your VCN, then **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. You can only connect via Tailscale from this point on.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Verify">
|
||||
```bash
|
||||
openclaw --version
|
||||
systemctl --user status openclaw-gateway.service
|
||||
tailscale serve status
|
||||
curl http://localhost:18789
|
||||
```
|
||||
|
||||
Access the Control UI from any device on your tailnet:
|
||||
|
||||
```
|
||||
https://openclaw.<tailnet-name>.ts.net/
|
||||
```
|
||||
|
||||
Replace `<tailnet-name>` with your tailnet name (visible in `tailscale status`).
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Fallback: SSH tunnel
|
||||
|
||||
If Tailscale Serve is not working, use an SSH tunnel from your local machine:
|
||||
|
||||
```bash
|
||||
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 a different availability domain or retry during off-peak hours.
|
||||
|
||||
**Tailscale will not connect** -- Run `sudo tailscale up --ssh --hostname=openclaw --reset` to re-authenticate.
|
||||
|
||||
**Gateway will not start** -- Run `openclaw doctor --non-interactive` and check logs with `journalctl --user -u openclaw-gateway.service -n 50`.
|
||||
|
||||
**ARM binary issues** -- Most npm packages work on ARM64. For native binaries, look for `linux-arm64` or `aarch64` releases. Verify architecture with `uname -m`.
|
||||
|
||||
## Next steps
|
||||
|
||||
- [Channels](/channels) -- connect Telegram, WhatsApp, Discord, and more
|
||||
- [Gateway configuration](/gateway/configuration) -- all config options
|
||||
- [Updating](/install/updating) -- keep OpenClaw up to date
|
||||
210
openclaw/docs/install/podman.md
Normal file
210
openclaw/docs/install/podman.md
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
---
|
||||
summary: "Run OpenClaw in a rootless Podman container"
|
||||
read_when:
|
||||
- You want a containerized gateway with Podman instead of Docker
|
||||
title: "Podman"
|
||||
---
|
||||
|
||||
# Podman
|
||||
|
||||
Run the OpenClaw Gateway in a rootless Podman container, managed by your current non-root user.
|
||||
|
||||
The intended model is:
|
||||
|
||||
- Podman runs the gateway container.
|
||||
- Your host `openclaw` CLI is the control plane.
|
||||
- Persistent state lives on the host under `~/.openclaw` by default.
|
||||
- Day-to-day management uses `openclaw --container <name> ...` instead of `sudo -u openclaw`, `podman exec`, or a separate service user.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Podman** in rootless mode
|
||||
- **OpenClaw CLI** installed on the host
|
||||
- **Optional:** `systemd --user` if you want Quadlet-managed auto-start
|
||||
- **Optional:** `sudo` only if you want `loginctl enable-linger "$(whoami)"` for boot persistence on a headless host
|
||||
|
||||
## Quick start
|
||||
|
||||
<Steps>
|
||||
<Step title="One-time setup">
|
||||
From the repo root, run `./scripts/podman/setup.sh`.
|
||||
</Step>
|
||||
|
||||
<Step title="Start the Gateway container">
|
||||
Start the container with `./scripts/run-openclaw-podman.sh launch`.
|
||||
</Step>
|
||||
|
||||
<Step title="Run onboarding inside the container">
|
||||
Run `./scripts/run-openclaw-podman.sh launch setup`, then open `http://127.0.0.1:18789/`.
|
||||
</Step>
|
||||
|
||||
<Step title="Manage the running container from the host CLI">
|
||||
Set `OPENCLAW_CONTAINER=openclaw`, then use normal `openclaw` commands from the host.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
Setup details:
|
||||
|
||||
- `./scripts/podman/setup.sh` builds `openclaw:local` in your rootless Podman store by default, or uses `OPENCLAW_IMAGE` / `OPENCLAW_PODMAN_IMAGE` if you set one.
|
||||
- It creates `~/.openclaw/openclaw.json` with `gateway.mode: "local"` if missing.
|
||||
- It creates `~/.openclaw/.env` with `OPENCLAW_GATEWAY_TOKEN` if missing.
|
||||
- For manual launches, the helper reads only a small allowlist of Podman-related keys from `~/.openclaw/.env` and passes explicit runtime env vars to the container; it does not hand the full env file to Podman.
|
||||
|
||||
Quadlet-managed setup:
|
||||
|
||||
```bash
|
||||
./scripts/podman/setup.sh --quadlet
|
||||
```
|
||||
|
||||
Quadlet is a Linux-only option because it depends on systemd user services.
|
||||
|
||||
You can also set `OPENCLAW_PODMAN_QUADLET=1`.
|
||||
|
||||
Optional build/setup env vars:
|
||||
|
||||
- `OPENCLAW_IMAGE` or `OPENCLAW_PODMAN_IMAGE` -- use an existing/pulled image instead of building `openclaw:local`
|
||||
- `OPENCLAW_DOCKER_APT_PACKAGES` -- install extra apt packages during image build
|
||||
- `OPENCLAW_EXTENSIONS` -- pre-install extension dependencies at build time
|
||||
|
||||
Container start:
|
||||
|
||||
```bash
|
||||
./scripts/run-openclaw-podman.sh launch
|
||||
```
|
||||
|
||||
The script starts the container as your current uid/gid with `--userns=keep-id` and bind-mounts your OpenClaw state into the container.
|
||||
|
||||
Onboarding:
|
||||
|
||||
```bash
|
||||
./scripts/run-openclaw-podman.sh launch setup
|
||||
```
|
||||
|
||||
Then open `http://127.0.0.1:18789/` and use the token from `~/.openclaw/.env`.
|
||||
|
||||
Host CLI default:
|
||||
|
||||
```bash
|
||||
export OPENCLAW_CONTAINER=openclaw
|
||||
```
|
||||
|
||||
Then commands such as these will run inside that container automatically:
|
||||
|
||||
```bash
|
||||
openclaw dashboard --no-open
|
||||
openclaw gateway status --deep # includes extra service scan
|
||||
openclaw doctor
|
||||
openclaw channels login
|
||||
```
|
||||
|
||||
On macOS, Podman machine may make the browser appear non-local to the gateway.
|
||||
If the Control UI reports device-auth errors after launch, use the Tailscale guidance in
|
||||
[Podman + Tailscale](#podman--tailscale).
|
||||
|
||||
<a id="podman--tailscale"></a>
|
||||
|
||||
## Podman + Tailscale
|
||||
|
||||
For HTTPS or remote browser access, follow the main Tailscale docs.
|
||||
|
||||
Podman-specific note:
|
||||
|
||||
- Keep the Podman publish host at `127.0.0.1`.
|
||||
- Prefer host-managed `tailscale serve` over `openclaw gateway --tailscale serve`.
|
||||
- On macOS, if local browser device-auth context is unreliable, use Tailscale access instead of ad hoc local tunnel workarounds.
|
||||
|
||||
See:
|
||||
|
||||
- [Tailscale](/gateway/tailscale)
|
||||
- [Control UI](/web/control-ui)
|
||||
|
||||
## Systemd (Quadlet, optional)
|
||||
|
||||
If you ran `./scripts/podman/setup.sh --quadlet`, setup installs a Quadlet file at:
|
||||
|
||||
```bash
|
||||
~/.config/containers/systemd/openclaw.container
|
||||
```
|
||||
|
||||
Useful commands:
|
||||
|
||||
- **Start:** `systemctl --user start openclaw.service`
|
||||
- **Stop:** `systemctl --user stop openclaw.service`
|
||||
- **Status:** `systemctl --user status openclaw.service`
|
||||
- **Logs:** `journalctl --user -u openclaw.service -f`
|
||||
|
||||
After editing the Quadlet file:
|
||||
|
||||
```bash
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user restart openclaw.service
|
||||
```
|
||||
|
||||
For boot persistence on SSH/headless hosts, enable lingering for your current user:
|
||||
|
||||
```bash
|
||||
sudo loginctl enable-linger "$(whoami)"
|
||||
```
|
||||
|
||||
## Config, env, and storage
|
||||
|
||||
- **Config dir:** `~/.openclaw`
|
||||
- **Workspace dir:** `~/.openclaw/workspace`
|
||||
- **Token file:** `~/.openclaw/.env`
|
||||
- **Launch helper:** `./scripts/run-openclaw-podman.sh`
|
||||
|
||||
The launch script and Quadlet bind-mount host state into the container:
|
||||
|
||||
- `OPENCLAW_CONFIG_DIR` -> `/home/node/.openclaw`
|
||||
- `OPENCLAW_WORKSPACE_DIR` -> `/home/node/.openclaw/workspace`
|
||||
|
||||
By default those are host directories, not anonymous container state, so
|
||||
`openclaw.json`, per-agent `auth-profiles.json`, channel/provider state,
|
||||
sessions, and workspace survive container replacement.
|
||||
The Podman setup also seeds `gateway.controlUi.allowedOrigins` for `127.0.0.1` and `localhost` on the published gateway port so the local dashboard works with the container's non-loopback bind.
|
||||
|
||||
Useful env vars for the manual launcher:
|
||||
|
||||
- `OPENCLAW_PODMAN_CONTAINER` -- container name (`openclaw` by default)
|
||||
- `OPENCLAW_PODMAN_IMAGE` / `OPENCLAW_IMAGE` -- image to run
|
||||
- `OPENCLAW_PODMAN_GATEWAY_HOST_PORT` -- host port mapped to container `18789`
|
||||
- `OPENCLAW_PODMAN_BRIDGE_HOST_PORT` -- host port mapped to container `18790`
|
||||
- `OPENCLAW_PODMAN_PUBLISH_HOST` -- host interface for published ports; default is `127.0.0.1`
|
||||
- `OPENCLAW_GATEWAY_BIND` -- gateway bind mode inside the container; default is `lan`
|
||||
- `OPENCLAW_PODMAN_USERNS` -- `keep-id` (default), `auto`, or `host`
|
||||
|
||||
The manual launcher reads `~/.openclaw/.env` before finalizing container/image defaults, so you can persist these there.
|
||||
|
||||
If you use a non-default `OPENCLAW_CONFIG_DIR` or `OPENCLAW_WORKSPACE_DIR`, set the same variables for both `./scripts/podman/setup.sh` and later `./scripts/run-openclaw-podman.sh launch` commands. The repo-local launcher does not persist custom path overrides across shells.
|
||||
|
||||
Quadlet note:
|
||||
|
||||
- The generated Quadlet service intentionally keeps a fixed, hardened default shape: `127.0.0.1` published ports, `--bind lan` inside the container, and `keep-id` user namespace.
|
||||
- It pins `OPENCLAW_NO_RESPAWN=1`, `Restart=on-failure`, and `TimeoutStartSec=300`.
|
||||
- It publishes both `127.0.0.1:18789:18789` (gateway) and `127.0.0.1:18790:18790` (bridge).
|
||||
- It reads `~/.openclaw/.env` as a runtime `EnvironmentFile` for values such as `OPENCLAW_GATEWAY_TOKEN`, but it does not consume the manual launcher's Podman-specific override allowlist.
|
||||
- If you need custom publish ports, publish host, or other container-run flags, use the manual launcher or edit `~/.config/containers/systemd/openclaw.container` directly, then reload and restart the service.
|
||||
|
||||
## Useful commands
|
||||
|
||||
- **Container logs:** `podman logs -f openclaw`
|
||||
- **Stop container:** `podman stop openclaw`
|
||||
- **Remove container:** `podman rm -f openclaw`
|
||||
- **Open dashboard URL from host CLI:** `openclaw dashboard --no-open`
|
||||
- **Health/status via host CLI:** `openclaw gateway status --deep` (RPC probe + extra
|
||||
service scan)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **Permission denied (EACCES) on config or workspace:** The container runs with `--userns=keep-id` and `--user <your uid>:<your gid>` by default. Ensure the host config/workspace paths are owned by your current user.
|
||||
- **Gateway start blocked (missing `gateway.mode=local`):** Ensure `~/.openclaw/openclaw.json` exists and sets `gateway.mode="local"`. `scripts/podman/setup.sh` creates this if missing.
|
||||
- **Container CLI commands hit the wrong target:** Use `openclaw --container <name> ...` explicitly, or export `OPENCLAW_CONTAINER=<name>` in your shell.
|
||||
- **`openclaw update` fails with `--container`:** Expected. Rebuild/pull the image, then restart the container or the Quadlet service.
|
||||
- **Quadlet service does not start:** Run `systemctl --user daemon-reload`, then `systemctl --user start openclaw.service`. On headless systems you may also need `sudo loginctl enable-linger "$(whoami)"`.
|
||||
- **SELinux blocks bind mounts:** Leave the default mount behavior alone; the launcher auto-adds `:Z` on Linux when SELinux is enforcing or permissive.
|
||||
|
||||
## Related
|
||||
|
||||
- [Docker](/install/docker)
|
||||
- [Gateway background process](/gateway/background-process)
|
||||
- [Gateway troubleshooting](/gateway/troubleshooting)
|
||||
90
openclaw/docs/install/railway.mdx
Normal file
90
openclaw/docs/install/railway.mdx
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
---
|
||||
summary: "Deploy OpenClaw on Railway with one-click template"
|
||||
read_when:
|
||||
- Deploying OpenClaw to Railway
|
||||
- You want a one-click cloud deploy with browser-based Control UI
|
||||
title: "Railway"
|
||||
---
|
||||
|
||||
Deploy OpenClaw on Railway with a one-click template and access it through the web Control UI.
|
||||
This is the easiest "no terminal on the server" path: Railway runs the Gateway for you.
|
||||
|
||||
## Quick checklist (new users)
|
||||
|
||||
1. Click **Deploy on Railway** (below).
|
||||
2. Add a **Volume** mounted at `/data`.
|
||||
3. Set the required **Variables** (at least `OPENCLAW_GATEWAY_PORT` and `OPENCLAW_GATEWAY_TOKEN`).
|
||||
4. Enable **HTTP Proxy** on port `8080`.
|
||||
5. Open `https://<your-railway-domain>/openclaw` and connect using the configured shared secret. This template uses `OPENCLAW_GATEWAY_TOKEN` by default; if you replace it with password auth, use that password instead.
|
||||
|
||||
## One-click deploy
|
||||
|
||||
<a href="https://railway.com/deploy/clawdbot-railway-template" target="_blank" rel="noreferrer">
|
||||
Deploy on Railway
|
||||
</a>
|
||||
|
||||
After deploy, find your public URL in **Railway → your service → Settings → Domains**.
|
||||
|
||||
Railway will either:
|
||||
|
||||
- give you a generated domain (often `https://<something>.up.railway.app`), or
|
||||
- use your custom domain if you attached one.
|
||||
|
||||
Then open:
|
||||
|
||||
- `https://<your-railway-domain>/openclaw` — Control UI
|
||||
|
||||
## What you get
|
||||
|
||||
- Hosted OpenClaw Gateway + Control UI
|
||||
- Persistent storage via Railway Volume (`/data`) so `openclaw.json`,
|
||||
per-agent `auth-profiles.json`, channel/provider state, sessions, and
|
||||
workspace survive redeploys
|
||||
|
||||
## Required Railway settings
|
||||
|
||||
### Public Networking
|
||||
|
||||
Enable **HTTP Proxy** for the service.
|
||||
|
||||
- Port: `8080`
|
||||
|
||||
### Volume (required)
|
||||
|
||||
Attach a volume mounted at:
|
||||
|
||||
- `/data`
|
||||
|
||||
### Variables
|
||||
|
||||
Set these variables on the service:
|
||||
|
||||
- `OPENCLAW_GATEWAY_PORT=8080` (required — must match the port in Public Networking)
|
||||
- `OPENCLAW_GATEWAY_TOKEN` (required; treat as an admin secret)
|
||||
- `OPENCLAW_STATE_DIR=/data/.openclaw` (recommended)
|
||||
- `OPENCLAW_WORKSPACE_DIR=/data/workspace` (recommended)
|
||||
|
||||
## Connect a channel
|
||||
|
||||
Use the Control UI at `/openclaw` or run `openclaw onboard` via Railway's shell for channel setup instructions:
|
||||
|
||||
- [Telegram](/channels/telegram) (fastest — just a bot token)
|
||||
- [Discord](/channels/discord)
|
||||
- [All channels](/channels)
|
||||
|
||||
## Backups & migration
|
||||
|
||||
Export your state, config, auth profiles, and workspace:
|
||||
|
||||
```bash
|
||||
openclaw backup create
|
||||
```
|
||||
|
||||
This creates a portable backup archive with OpenClaw state plus any configured
|
||||
workspace. See [Backup](/cli/backup) for details.
|
||||
|
||||
## Next steps
|
||||
|
||||
- Set up messaging channels: [Channels](/channels)
|
||||
- Configure the Gateway: [Gateway configuration](/gateway/configuration)
|
||||
- Keep OpenClaw up to date: [Updating](/install/updating)
|
||||
159
openclaw/docs/install/raspberry-pi.md
Normal file
159
openclaw/docs/install/raspberry-pi.md
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
---
|
||||
summary: "Host OpenClaw on a Raspberry Pi for always-on self-hosting"
|
||||
read_when:
|
||||
- Setting up OpenClaw on a Raspberry Pi
|
||||
- Running OpenClaw on ARM devices
|
||||
- Building a cheap always-on personal AI
|
||||
title: "Raspberry Pi"
|
||||
---
|
||||
|
||||
# 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.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Raspberry Pi 4 or 5 with 2 GB+ RAM (4 GB recommended)
|
||||
- MicroSD card (16 GB+) or USB SSD (better performance)
|
||||
- Official Pi power supply
|
||||
- Network connection (Ethernet or WiFi)
|
||||
- 64-bit Raspberry Pi OS (required -- do not use 32-bit)
|
||||
- About 30 minutes
|
||||
|
||||
## Setup
|
||||
|
||||
<Steps>
|
||||
<Step title="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. In the settings dialog, pre-configure:
|
||||
- Hostname: `gateway-host`
|
||||
- Enable SSH
|
||||
- Set username and password
|
||||
- Configure WiFi (if not using Ethernet)
|
||||
4. Flash to your SD card or USB drive, insert it, and boot the Pi.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Connect via SSH">
|
||||
```bash
|
||||
ssh user@gateway-host
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Update the system">
|
||||
```bash
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
sudo apt install -y git curl build-essential
|
||||
|
||||
# Set timezone (important for cron and reminders)
|
||||
sudo timedatectl set-timezone America/Chicago
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Install Node.js 24">
|
||||
```bash
|
||||
curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
|
||||
sudo apt install -y nodejs
|
||||
node --version
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Add swap (important for 2 GB or less)">
|
||||
```bash
|
||||
sudo fallocate -l 2G /swapfile
|
||||
sudo chmod 600 /swapfile
|
||||
sudo mkswap /swapfile
|
||||
sudo swapon /swapfile
|
||||
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
|
||||
|
||||
# Reduce swappiness for low-RAM devices
|
||||
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
|
||||
sudo sysctl -p
|
||||
```
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Install OpenClaw">
|
||||
```bash
|
||||
curl -fsSL https://openclaw.ai/install.sh | bash
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run onboarding">
|
||||
```bash
|
||||
openclaw onboard --install-daemon
|
||||
```
|
||||
|
||||
Follow the wizard. API keys are recommended over OAuth for headless devices. Telegram is the easiest channel to start with.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Verify">
|
||||
```bash
|
||||
openclaw status
|
||||
systemctl --user status openclaw-gateway.service
|
||||
journalctl --user -u openclaw-gateway.service -f
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Access the Control UI">
|
||||
On your computer, get a dashboard URL from the Pi:
|
||||
|
||||
```bash
|
||||
ssh user@gateway-host 'openclaw dashboard --no-open'
|
||||
```
|
||||
|
||||
Then create an SSH tunnel in another terminal:
|
||||
|
||||
```bash
|
||||
ssh -N -L 18789:127.0.0.1:18789 user@gateway-host
|
||||
```
|
||||
|
||||
Open the printed URL in your local browser. For always-on remote access, see [Tailscale integration](/gateway/tailscale).
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Performance tips
|
||||
|
||||
**Use a USB SSD** -- SD cards are slow and wear out. A USB SSD dramatically improves performance. See the [Pi USB boot guide](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#usb-mass-storage-boot).
|
||||
|
||||
**Enable module compile cache** -- Speeds up repeated CLI invocations on lower-power Pi hosts:
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
**Reduce memory usage** -- For headless setups, free GPU memory and disable unused services:
|
||||
|
||||
```bash
|
||||
echo 'gpu_mem=16' | sudo tee -a /boot/config.txt
|
||||
sudo systemctl disable bluetooth
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
||||
**Slow performance** -- Use a USB SSD instead of an SD card. Check for CPU throttling with `vcgencmd get_throttled` (should return `0x0`).
|
||||
|
||||
**Service will not start** -- Check logs with `journalctl --user -u openclaw-gateway.service --no-pager -n 100` and run `openclaw doctor --non-interactive`. If this is a headless Pi, also verify lingering is enabled: `sudo loginctl enable-linger "$(whoami)"`.
|
||||
|
||||
**ARM binary issues** -- If a skill fails with "exec format error", check whether the binary has an ARM64 build. Verify architecture with `uname -m` (should show `aarch64`).
|
||||
|
||||
**WiFi drops** -- Disable WiFi power management: `sudo iwconfig wlan0 power off`.
|
||||
|
||||
## Next steps
|
||||
|
||||
- [Channels](/channels) -- connect Telegram, WhatsApp, Discord, and more
|
||||
- [Gateway configuration](/gateway/configuration) -- all config options
|
||||
- [Updating](/install/updating) -- keep OpenClaw up to date
|
||||
165
openclaw/docs/install/render.mdx
Normal file
165
openclaw/docs/install/render.mdx
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
---
|
||||
summary: "Deploy OpenClaw on Render with Infrastructure-as-Code"
|
||||
read_when:
|
||||
- Deploying OpenClaw to Render
|
||||
- You want a declarative cloud deploy with Render Blueprints
|
||||
title: "Render"
|
||||
---
|
||||
|
||||
Deploy OpenClaw on Render using Infrastructure as Code. The included `render.yaml` Blueprint defines your entire stack declaratively, service, disk, environment variables, so you can deploy with a single click and version your infrastructure alongside your code.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- A [Render account](https://render.com) (free tier available)
|
||||
- An API key from your preferred [model provider](/providers)
|
||||
|
||||
## Deploy with a Render Blueprint
|
||||
|
||||
[Deploy to Render](https://render.com/deploy?repo=https://github.com/openclaw/openclaw)
|
||||
|
||||
Clicking this link will:
|
||||
|
||||
1. Create a new Render service from the `render.yaml` Blueprint at the root of this repo.
|
||||
2. Build the Docker image and deploy
|
||||
|
||||
Once deployed, your service URL follows the pattern `https://<service-name>.onrender.com`.
|
||||
|
||||
## Understanding the Blueprint
|
||||
|
||||
Render Blueprints are YAML files that define your infrastructure. The `render.yaml` in this
|
||||
repository configures everything needed to run OpenClaw:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
- type: web
|
||||
name: openclaw
|
||||
runtime: docker
|
||||
plan: starter
|
||||
healthCheckPath: /health
|
||||
envVars:
|
||||
- key: OPENCLAW_GATEWAY_PORT
|
||||
value: "8080"
|
||||
- key: OPENCLAW_STATE_DIR
|
||||
value: /data/.openclaw
|
||||
- key: OPENCLAW_WORKSPACE_DIR
|
||||
value: /data/workspace
|
||||
- key: OPENCLAW_GATEWAY_TOKEN
|
||||
generateValue: true # auto-generates a secure token
|
||||
disk:
|
||||
name: openclaw-data
|
||||
mountPath: /data
|
||||
sizeGB: 1
|
||||
```
|
||||
|
||||
Key Blueprint features used:
|
||||
|
||||
| Feature | Purpose |
|
||||
| --------------------- | ---------------------------------------------------------- |
|
||||
| `runtime: docker` | Builds from the repo's Dockerfile |
|
||||
| `healthCheckPath` | Render monitors `/health` and restarts unhealthy instances |
|
||||
| `generateValue: true` | Auto-generates a cryptographically secure value |
|
||||
| `disk` | Persistent storage that survives redeploys |
|
||||
|
||||
## Choosing a plan
|
||||
|
||||
| Plan | Spin-down | Disk | Best for |
|
||||
| --------- | ----------------- | ------------- | ----------------------------- |
|
||||
| Free | After 15 min idle | Not available | Testing, demos |
|
||||
| Starter | Never | 1GB+ | Personal use, small teams |
|
||||
| Standard+ | Never | 1GB+ | Production, multiple channels |
|
||||
|
||||
The Blueprint defaults to `starter`. To use free tier, change `plan: free` in
|
||||
your fork's `render.yaml` (but note: no persistent disk means OpenClaw state
|
||||
resets on each deploy).
|
||||
|
||||
## After deployment
|
||||
|
||||
### Access the Control UI
|
||||
|
||||
The web dashboard is available at `https://<your-service>.onrender.com/`.
|
||||
|
||||
Connect using the configured shared secret. This deploy template auto-generates
|
||||
`OPENCLAW_GATEWAY_TOKEN` (find it in **Dashboard → your service →
|
||||
Environment**); if you replace it with password auth, use that password
|
||||
instead.
|
||||
|
||||
## Render Dashboard features
|
||||
|
||||
### Logs
|
||||
|
||||
View real-time logs in **Dashboard → your service → Logs**. Filter by:
|
||||
|
||||
- Build logs (Docker image creation)
|
||||
- Deploy logs (service startup)
|
||||
- Runtime logs (application output)
|
||||
|
||||
### Shell access
|
||||
|
||||
For debugging, open a shell session via **Dashboard → your service → Shell**. The persistent disk is mounted at `/data`.
|
||||
|
||||
### Environment variables
|
||||
|
||||
Modify variables in **Dashboard → your service → Environment**. Changes trigger an automatic redeploy.
|
||||
|
||||
### Auto-deploy
|
||||
|
||||
If you use the original OpenClaw repository, Render will not auto-deploy your OpenClaw. To update it, run a manual Blueprint sync from the dashboard.
|
||||
|
||||
## Custom domain
|
||||
|
||||
1. Go to **Dashboard → your service → Settings → Custom Domains**
|
||||
2. Add your domain
|
||||
3. Configure DNS as instructed (CNAME to `*.onrender.com`)
|
||||
4. Render provisions a TLS certificate automatically
|
||||
|
||||
## Scaling
|
||||
|
||||
Render supports horizontal and vertical scaling:
|
||||
|
||||
- **Vertical**: Change the plan to get more CPU/RAM
|
||||
- **Horizontal**: Increase instance count (Standard plan and above)
|
||||
|
||||
For OpenClaw, vertical scaling is usually sufficient. Horizontal scaling requires sticky sessions or external state management.
|
||||
|
||||
## Backups and migration
|
||||
|
||||
Export your state, config, auth profiles, and workspace at any time using the
|
||||
shell access in the Render Dashboard:
|
||||
|
||||
```bash
|
||||
openclaw backup create
|
||||
```
|
||||
|
||||
This creates a portable backup archive with OpenClaw state plus any configured
|
||||
workspace. See [Backup](/cli/backup) for details.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Service will not start
|
||||
|
||||
Check the deploy logs in the Render Dashboard. Common issues:
|
||||
|
||||
- Missing `OPENCLAW_GATEWAY_TOKEN` — verify it is set in **Dashboard → Environment**
|
||||
- Port mismatch — ensure `OPENCLAW_GATEWAY_PORT=8080` is set so the gateway binds to the port Render expects
|
||||
|
||||
### Slow cold starts (free tier)
|
||||
|
||||
Free tier services spin down after 15 minutes of inactivity. The first request after spin-down takes a few seconds while the container starts. Upgrade to Starter plan for always-on.
|
||||
|
||||
### Data loss after redeploy
|
||||
|
||||
This happens on free tier (no persistent disk). Upgrade to a paid plan, or
|
||||
regularly export a full backup via `openclaw backup create` in the Render shell.
|
||||
|
||||
### Health check failures
|
||||
|
||||
Render expects a 200 response from `/health` within 30 seconds. If builds succeed but deploys fail, the service may be taking too long to start. Check:
|
||||
|
||||
- Build logs for errors
|
||||
- Whether the container runs locally with `docker build && docker run`
|
||||
|
||||
## Next steps
|
||||
|
||||
- Set up messaging channels: [Channels](/channels)
|
||||
- Configure the Gateway: [Gateway configuration](/gateway/configuration)
|
||||
- Keep OpenClaw up to date: [Updating](/install/updating)
|
||||
128
openclaw/docs/install/uninstall.md
Normal file
128
openclaw/docs/install/uninstall.md
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
---
|
||||
summary: "Uninstall OpenClaw completely (CLI, service, state, workspace)"
|
||||
read_when:
|
||||
- You want to remove OpenClaw from a machine
|
||||
- The gateway service is still running after uninstall
|
||||
title: "Uninstall"
|
||||
---
|
||||
|
||||
# Uninstall
|
||||
|
||||
Two paths:
|
||||
|
||||
- **Easy path** if `openclaw` is still installed.
|
||||
- **Manual service removal** if the CLI is gone but the service is still running.
|
||||
|
||||
## Easy path (CLI still installed)
|
||||
|
||||
Recommended: use the built-in uninstaller:
|
||||
|
||||
```bash
|
||||
openclaw uninstall
|
||||
```
|
||||
|
||||
Non-interactive (automation / npx):
|
||||
|
||||
```bash
|
||||
openclaw uninstall --all --yes --non-interactive
|
||||
npx -y openclaw uninstall --all --yes --non-interactive
|
||||
```
|
||||
|
||||
Manual steps (same result):
|
||||
|
||||
1. Stop the gateway service:
|
||||
|
||||
```bash
|
||||
openclaw gateway stop
|
||||
```
|
||||
|
||||
2. Uninstall the gateway service (launchd/systemd/schtasks):
|
||||
|
||||
```bash
|
||||
openclaw gateway uninstall
|
||||
```
|
||||
|
||||
3. Delete state + config:
|
||||
|
||||
```bash
|
||||
rm -rf "${OPENCLAW_STATE_DIR:-$HOME/.openclaw}"
|
||||
```
|
||||
|
||||
If you set `OPENCLAW_CONFIG_PATH` to a custom location outside the state dir, delete that file too.
|
||||
|
||||
4. Delete your workspace (optional, removes agent files):
|
||||
|
||||
```bash
|
||||
rm -rf ~/.openclaw/workspace
|
||||
```
|
||||
|
||||
5. Remove the CLI install (pick the one you used):
|
||||
|
||||
```bash
|
||||
npm rm -g openclaw
|
||||
pnpm remove -g openclaw
|
||||
bun remove -g openclaw
|
||||
```
|
||||
|
||||
6. If you installed the macOS app:
|
||||
|
||||
```bash
|
||||
rm -rf /Applications/OpenClaw.app
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- If you used profiles (`--profile` / `OPENCLAW_PROFILE`), repeat step 3 for each state dir (defaults are `~/.openclaw-<profile>`).
|
||||
- In remote mode, the state dir lives on the **gateway host**, so run steps 1-4 there too.
|
||||
|
||||
## Manual service removal (CLI not installed)
|
||||
|
||||
Use this if the gateway service keeps running but `openclaw` is missing.
|
||||
|
||||
### macOS (launchd)
|
||||
|
||||
Default label is `ai.openclaw.gateway` (or `ai.openclaw.<profile>`; legacy `com.openclaw.*` may still exist):
|
||||
|
||||
```bash
|
||||
launchctl bootout gui/$UID/ai.openclaw.gateway
|
||||
rm -f ~/Library/LaunchAgents/ai.openclaw.gateway.plist
|
||||
```
|
||||
|
||||
If you used a profile, replace the label and plist name with `ai.openclaw.<profile>`. Remove any legacy `com.openclaw.*` plists if present.
|
||||
|
||||
### Linux (systemd user unit)
|
||||
|
||||
Default unit name is `openclaw-gateway.service` (or `openclaw-gateway-<profile>.service`):
|
||||
|
||||
```bash
|
||||
systemctl --user disable --now openclaw-gateway.service
|
||||
rm -f ~/.config/systemd/user/openclaw-gateway.service
|
||||
systemctl --user daemon-reload
|
||||
```
|
||||
|
||||
### Windows (Scheduled Task)
|
||||
|
||||
Default task name is `OpenClaw Gateway` (or `OpenClaw Gateway (<profile>)`).
|
||||
The task script lives under your state dir.
|
||||
|
||||
```powershell
|
||||
schtasks /Delete /F /TN "OpenClaw Gateway"
|
||||
Remove-Item -Force "$env:USERPROFILE\.openclaw\gateway.cmd"
|
||||
```
|
||||
|
||||
If you used a profile, delete the matching task name and `~\.openclaw-<profile>\gateway.cmd`.
|
||||
|
||||
## Normal install vs source checkout
|
||||
|
||||
### Normal install (install.sh / npm / pnpm / bun)
|
||||
|
||||
If you used `https://openclaw.ai/install.sh` or `install.ps1`, the CLI was installed with `npm install -g openclaw@latest`.
|
||||
Remove it with `npm rm -g openclaw` (or `pnpm remove -g` / `bun remove -g` if you installed that way).
|
||||
|
||||
### Source checkout (git clone)
|
||||
|
||||
If you run from a repo checkout (`git clone` + `openclaw ...` / `bun run openclaw ...`):
|
||||
|
||||
1. Uninstall the gateway service **before** deleting the repo (use the easy path above or manual service removal).
|
||||
2. Delete the repo directory.
|
||||
3. Remove state + workspace as shown above.
|
||||
143
openclaw/docs/install/updating.md
Normal file
143
openclaw/docs/install/updating.md
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
---
|
||||
summary: "Updating OpenClaw safely (global install or source), plus rollback strategy"
|
||||
read_when:
|
||||
- Updating OpenClaw
|
||||
- Something breaks after an update
|
||||
title: "Updating"
|
||||
---
|
||||
|
||||
# Updating
|
||||
|
||||
Keep OpenClaw up to date.
|
||||
|
||||
## Recommended: `openclaw update`
|
||||
|
||||
The fastest way to update. It detects your install type (npm or git), fetches the latest version, runs `openclaw doctor`, and restarts the gateway.
|
||||
|
||||
```bash
|
||||
openclaw update
|
||||
```
|
||||
|
||||
To switch channels or target a specific version:
|
||||
|
||||
```bash
|
||||
openclaw update --channel beta
|
||||
openclaw update --tag main
|
||||
openclaw update --dry-run # preview without applying
|
||||
```
|
||||
|
||||
`--channel beta` prefers beta, but the runtime falls back to stable/latest when
|
||||
the beta tag is missing or older than the latest stable release. Use `--tag beta`
|
||||
if you want the raw npm beta dist-tag for a one-off package update.
|
||||
|
||||
See [Development channels](/install/development-channels) for channel semantics.
|
||||
|
||||
## Alternative: re-run the installer
|
||||
|
||||
```bash
|
||||
curl -fsSL https://openclaw.ai/install.sh | bash
|
||||
```
|
||||
|
||||
Add `--no-onboard` to skip onboarding. For source installs, pass `--install-method git --no-onboard`.
|
||||
|
||||
## Alternative: manual npm, pnpm, or bun
|
||||
|
||||
```bash
|
||||
npm i -g openclaw@latest
|
||||
```
|
||||
|
||||
```bash
|
||||
pnpm add -g openclaw@latest
|
||||
```
|
||||
|
||||
```bash
|
||||
bun add -g openclaw@latest
|
||||
```
|
||||
|
||||
## Auto-updater
|
||||
|
||||
The auto-updater is off by default. Enable it in `~/.openclaw/openclaw.json`:
|
||||
|
||||
```json5
|
||||
{
|
||||
update: {
|
||||
channel: "stable",
|
||||
auto: {
|
||||
enabled: true,
|
||||
stableDelayHours: 6,
|
||||
stableJitterHours: 12,
|
||||
betaCheckIntervalHours: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
| Channel | Behavior |
|
||||
| -------- | ------------------------------------------------------------------------------------------------------------- |
|
||||
| `stable` | Waits `stableDelayHours`, then applies with deterministic jitter across `stableJitterHours` (spread rollout). |
|
||||
| `beta` | Checks every `betaCheckIntervalHours` (default: hourly) and applies immediately. |
|
||||
| `dev` | No automatic apply. Use `openclaw update` manually. |
|
||||
|
||||
The gateway also logs an update hint on startup (disable with `update.checkOnStart: false`).
|
||||
|
||||
## After updating
|
||||
|
||||
<Steps>
|
||||
|
||||
### Run doctor
|
||||
|
||||
```bash
|
||||
openclaw doctor
|
||||
```
|
||||
|
||||
Migrates config, audits DM policies, and checks gateway health. Details: [Doctor](/gateway/doctor)
|
||||
|
||||
### Restart the gateway
|
||||
|
||||
```bash
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
### Verify
|
||||
|
||||
```bash
|
||||
openclaw health
|
||||
```
|
||||
|
||||
</Steps>
|
||||
|
||||
## Rollback
|
||||
|
||||
### Pin a version (npm)
|
||||
|
||||
```bash
|
||||
npm i -g openclaw@<version>
|
||||
openclaw doctor
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
Tip: `npm view openclaw version` shows the current published version.
|
||||
|
||||
### Pin a commit (source)
|
||||
|
||||
```bash
|
||||
git fetch origin
|
||||
git checkout "$(git rev-list -n 1 --before=\"2026-01-01\" origin/main)"
|
||||
pnpm install && pnpm build
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
To return to latest: `git checkout main && git pull`.
|
||||
|
||||
## If you are stuck
|
||||
|
||||
- Run `openclaw doctor` again and read the output carefully.
|
||||
- For `openclaw update --channel dev` on source checkouts, the updater auto-bootstraps `pnpm` when needed. If you see a pnpm/corepack bootstrap error, install `pnpm` manually (or re-enable `corepack`) and rerun the update.
|
||||
- Check: [Troubleshooting](/gateway/troubleshooting)
|
||||
- Ask in Discord: [https://discord.gg/clawd](https://discord.gg/clawd)
|
||||
|
||||
## Related
|
||||
|
||||
- [Install Overview](/install) — all installation methods
|
||||
- [Doctor](/gateway/doctor) — health checks after updates
|
||||
- [Migrating](/install/migrating) — major version migration guides
|
||||
Loading…
Add table
Add a link
Reference in a new issue