diff --git a/docs/install/azure.md b/docs/install/azure.md index f3a01c331ea8..1ec5048cf723 100644 --- a/docs/install/azure.md +++ b/docs/install/azure.md @@ -265,6 +265,7 @@ Set up an Azure Linux VM with the Azure CLI, apply Network Security Group (NSG) After onboarding completes: ```bash + openclaw doctor --json openclaw gateway status ``` diff --git a/docs/install/daytona.md b/docs/install/daytona.md index 8e530fd39131..0aa9c615b445 100644 --- a/docs/install/daytona.md +++ b/docs/install/daytona.md @@ -190,10 +190,14 @@ Create a bot with [@BotFather](https://t.me/botfather) (`/newbot`), copy the token, then configure OpenClaw from the sandbox SSH session: ```bash -openclaw config set channels.telegram.enabled true -openclaw config set channels.telegram.botToken YOUR_BOT_TOKEN +export TELEGRAM_BOT_TOKEN="" +openclaw channels add --channel telegram --use-env ``` +Also store `TELEGRAM_BOT_TOKEN=` in `~/.openclaw/.env` so the +background Gateway receives it after a restart. `--use-env` validates the token +without copying it into `openclaw.json`. + Restart the Gateway (see above), send your bot a DM, then approve the pairing code it reports: diff --git a/docs/install/digitalocean.md b/docs/install/digitalocean.md index 8b5225810878..aa0bea13a06c 100644 --- a/docs/install/digitalocean.md +++ b/docs/install/digitalocean.md @@ -75,11 +75,11 @@ DigitalOcean is a straightforward paid VPS path. For cheaper or free options: ```bash - fallocate -l 2G /swapfile - chmod 600 /swapfile - mkswap /swapfile - swapon /swapfile - echo '/swapfile none swap sw 0 0' >> /etc/fstab + 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 ``` @@ -130,9 +130,13 @@ These survive Droplet reboots. To take a portable snapshot: ```bash openclaw backup create +openclaw backup restore --target ``` -DigitalOcean snapshots back up the whole Droplet; `openclaw backup create` is portable across hosts. +DigitalOcean snapshots back up the whole Droplet; `openclaw backup create` is +portable across hosts. Restore verifies and extracts into a fresh staging +directory; activation is a separate offline step. See [Restore a full archive](/install/backups#restore-a-full-archive) +for the rollback warnings and activation sequence. ## 1 GB RAM tips diff --git a/docs/install/docker-vm-runtime.md b/docs/install/docker-vm-runtime.md index 52bc6a0cb4bc..5d219bfa4d64 100644 --- a/docs/install/docker-vm-runtime.md +++ b/docs/install/docker-vm-runtime.md @@ -20,61 +20,30 @@ The examples below cover three binaries only, alphabetically: - `goplaces` for Google Places - `wacli` for WhatsApp -These are examples, not a complete list. Install as many binaries as your -skills need using the same pattern. When you add a skill that needs a new -binary later: +These are examples, not a complete list. Docker Compose builds the repo-root +`Dockerfile`, so extend that file rather than creating a standalone example or +replacing its contents. The repository Dockerfile has required +`workspace-deps`, build, runtime-assets, and final runtime stages. Its manifest +extraction covers the `packages/*` and selected `extensions/*` workspaces before +`pnpm install --frozen-lockfile`. -1. Update the Dockerfile. -2. Rebuild the image. -3. Restart the containers. +For Debian packages, prefer the existing build argument: -**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 (gogcli — installs as `gog`) -# Copy the current Linux asset URL from https://github.com/steipete/gogcli/releases -RUN curl -L https://github.com/steipete/gogcli/releases/latest/download/gogcli_linux_amd64.tar.gz \ - | tar -xzO gog > /usr/local/bin/gog; \ - chmod +x /usr/local/bin/gog - -# Example binary 2: Google Places CLI -# Copy the current Linux asset URL from https://github.com/steipete/goplaces/releases -RUN curl -L https://github.com/steipete/goplaces/releases/latest/download/goplaces_linux_amd64.tar.gz \ - | tar -xzO goplaces > /usr/local/bin/goplaces; \ - chmod +x /usr/local/bin/goplaces - -# Example binary 3: WhatsApp CLI -# Copy the current Linux asset URL from https://github.com/steipete/wacli/releases -RUN curl -L https://github.com/steipete/wacli/releases/latest/download/wacli-linux-amd64.tar.gz \ - | tar -xzO wacli > /usr/local/bin/wacli; \ - 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"] +```bash +export OPENCLAW_IMAGE_APT_PACKAGES="socat" ``` +For downloaded release binaries such as `gog`, `goplaces`, or `wacli`, add the +download and install commands to the repo-root `Dockerfile` final runtime stage, +after its package-install blocks and before `USER node`. Preserve the existing +non-root uid 1000 setup, `tini` entrypoint, health check, and `openclaw` symlink. +Then rebuild and restart the containers. + -The URLs above are examples. For ARM-based VMs, choose the `arm64` assets. For reproducible builds, pin versioned release URLs. +The repository Dockerfile digest-pins its Node and Bun base images. Keep those +reviewed pins instead of changing them to floating `FROM node:24-bookworm` +references. For ARM-based VMs, choose `arm64` release assets for extra binaries; +for reproducible builds, use versioned asset URLs and verify their checksums. ## Build and launch diff --git a/docs/install/docker.md b/docs/install/docker.md index 56019b087937..b02e5f5d7d28 100644 --- a/docs/install/docker.md +++ b/docs/install/docker.md @@ -180,6 +180,13 @@ After doctor finishes, restart the gateway container with its default command. In Kubernetes, run the same command in a one-off Job or debug pod mounted to the same PVC, then restart the Deployment or StatefulSet. +After the container is running again, run the read-only deployment preflight +against the same mounted state: + +```bash +docker compose run --rm openclaw-cli doctor --json +``` + ### Environment variables Optional variables accepted by `scripts/docker/setup.sh` (and, for the gateway container, by `docker-compose.yml` directly): @@ -514,25 +521,17 @@ If you installed from the older `scripts/shell-helpers/clawdock-helpers.sh` path - Order your Dockerfile so dependency layers are cached, avoiding a `pnpm install` rerun unless lockfiles change: + Use the repo-root `Dockerfile` instead of replacing it with a shortened + single-stage example. Its `workspace-deps` stage extracts the package + manifests required by `pnpm-workspace.yaml`, then the build stage copies + those manifests before `pnpm install --frozen-lockfile`. This keeps the + dependency layer cacheable without omitting `packages/*`, selected + `extensions/*`, or other required workspace metadata. - ```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"] - ``` + The same Dockerfile preserves the production runtime contract: digest-pinned + Node and Bun bases, non-root uid 1000, `tini`, the built-in health check, and + the `/usr/local/bin/openclaw` symlink. Dependabot refreshes the reviewed base + digests; do not replace them with floating `FROM node:24-bookworm` tags. diff --git a/docs/install/exe-dev.md b/docs/install/exe-dev.md index c8be9746de1c..c0bbd5d4913d 100644 --- a/docs/install/exe-dev.md +++ b/docs/install/exe-dev.md @@ -28,7 +28,7 @@ This guide assumes exe.dev's default **exeuntu** image. Map packages accordingly Shelley, exe.dev's agent, can install OpenClaw from a prompt: ```text -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 ". 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 .exe.xyz, without port specification. +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. Set gateway.controlUi.allowedOrigins to the exact https://.exe.xyz origin, and set gateway.trustedProxies to ["127.0.0.1"] because nginx connects to the Gateway over loopback and overwrites X-Forwarded-For. Pairing is done by "openclaw devices list" and "openclaw devices approve ". 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 .exe.xyz, without port specification. ``` ## Manual installation @@ -103,6 +103,22 @@ Set up OpenClaw (https://docs.openclaw.ai/install) on this VM. Use the non-inter + + Configure the exact public origin and trust only the loopback nginx hop: + + ```bash + openclaw config set gateway.controlUi.allowedOrigins '["https://.exe.xyz"]' --strict-json + openclaw config set gateway.trustedProxies '["127.0.0.1"]' --strict-json + openclaw gateway restart + ``` + + The browser origin check is fail-closed for public hostnames. The proxy + allowlist lets OpenClaw use nginx's overwritten `X-Forwarded-For` value + instead of treating every request as if it originated from the loopback + proxy. Keep this list limited to proxies you control. + + + Open `https://.exe.xyz/` (see the Control UI output from onboarding). If it prompts for auth, paste the configured shared secret from the VM. diff --git a/docs/install/gcp.md b/docs/install/gcp.md index 4aeff17c8bc1..308a18f23f35 100644 --- a/docs/install/gcp.md +++ b/docs/install/gcp.md @@ -180,15 +180,19 @@ This guide uses Debian on GCP Compute Engine. Ubuntu also works; map packages ac 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 + HOME: /home/node + NODE_ENV: production + TERM: xterm-256color + OPENCLAW_STATE_DIR: /home/node/.openclaw + OPENCLAW_CONFIG_PATH: /home/node/.openclaw/openclaw.json + OPENCLAW_CONFIG_DIR: /home/node/.openclaw + OPENCLAW_WORKSPACE_DIR: /home/node/.openclaw/workspace + 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 @@ -207,10 +211,40 @@ This guide uses Debian on GCP Compute Engine. Ubuntu also works; map packages ac "${OPENCLAW_GATEWAY_PORT}", "--allow-unconfigured", ] + + openclaw-cli: + image: ${OPENCLAW_IMAGE} + network_mode: "service:openclaw-gateway" + env_file: + - .env + environment: + HOME: /home/node + TERM: xterm-256color + OPENCLAW_STATE_DIR: /home/node/.openclaw + OPENCLAW_CONFIG_PATH: /home/node/.openclaw/openclaw.json + OPENCLAW_CONFIG_DIR: /home/node/.openclaw + OPENCLAW_WORKSPACE_DIR: /home/node/.openclaw/workspace + 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 + stdin_open: true + tty: true + init: true + entrypoint: ["node", "dist/index.js"] + depends_on: + - openclaw-gateway ``` `--allow-unconfigured` is only for bootstrap convenience, not a substitute for real gateway configuration. Still set auth (`gateway.auth.token` or password) and a safe bind mode for your deployment. + The `.env` paths are host-side bind-mount sources. Both services override + those variables with `/home/node/...` paths inside the container so the + non-root `node` user never tries to write to a host-only path. + diff --git a/docs/install/hetzner.md b/docs/install/hetzner.md index 5957d7d4577a..40ae40dbaaef 100644 --- a/docs/install/hetzner.md +++ b/docs/install/hetzner.md @@ -137,15 +137,19 @@ This guide assumes Ubuntu or Debian on Hetzner. On another Linux VPS, map packag 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 + HOME: /home/node + NODE_ENV: production + TERM: xterm-256color + OPENCLAW_STATE_DIR: /home/node/.openclaw + OPENCLAW_CONFIG_PATH: /home/node/.openclaw/openclaw.json + OPENCLAW_CONFIG_DIR: /home/node/.openclaw + OPENCLAW_WORKSPACE_DIR: /home/node/.openclaw/workspace + 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 @@ -166,6 +170,10 @@ This guide assumes Ubuntu or Debian on Hetzner. On another Linux VPS, map packag ] ``` + The `.env` paths are host-side bind-mount sources. The service overrides + them with `/home/node/...` paths inside the container so the non-root + `node` user never tries to write to a host-only path. + `--allow-unconfigured` is only for bootstrap convenience, not a substitute for real gateway configuration. Still set auth (`gateway.auth.token` or password) and a safe bind mode for your deployment. diff --git a/docs/install/index.md b/docs/install/index.md index 73f52c6dd1cb..07a617618642 100644 --- a/docs/install/index.md +++ b/docs/install/index.md @@ -151,21 +151,24 @@ curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s - ### Containers and package managers - - Containerized or headless deployments. - - - Rootless container alternative to Docker. - - - Declarative install via Nix flake. - Automated fleet provisioning. Optional dependency installer and package-script runner. + + Community Docker Compose setup and shell helpers. + + + Containerized or headless deployments. + + + Declarative install via Nix flake. + + + Rootless container alternative to Docker. + ## Verify the install @@ -194,20 +197,29 @@ template. Experimental Worker + Container deployment. - - Pick a provider. - Shared Docker steps. K8s deployment. + + Isolated local or hosted macOS deployment. + + + Managed Linux host with SSH-tunneled access. + + + Pick a provider. + -## Update, migrate, or uninstall +## Back up, update, migrate, or uninstall + + Create, verify, and restore state archives. + Keep OpenClaw up to date. diff --git a/docs/install/installer.md b/docs/install/installer.md index 0d92f90a49a0..618664b77d06 100644 --- a/docs/install/installer.md +++ b/docs/install/installer.md @@ -256,7 +256,9 @@ by default, plus git-checkout installs under the same prefix flow. | `--npm` | Shortcut for npm method | | `--git \| --github` | Shortcut for git method | | `--git-dir \| --dir ` | Git checkout directory (default: `~/openclaw`) | +| `--no-git-update` | Skip `git pull` for an existing git checkout | | `--version ` | OpenClaw version or dist-tag (default: `latest`) | +| `--compatible-with ` | Refuse a CLI that cannot modify config written by `` | | `--node-version ` | Node version (default: `24.15.0`; `22.22.3` on Linux ARMv7) | | `--json` | Emit NDJSON events | | `--onboard` | Run `openclaw onboard` after install | diff --git a/docs/install/kubernetes.md b/docs/install/kubernetes.md index ca00f182b867..4dba571362f0 100644 --- a/docs/install/kubernetes.md +++ b/docs/install/kubernetes.md @@ -26,7 +26,7 @@ export _API_KEY="..." ./scripts/k8s/deploy.sh kubectl port-forward svc/openclaw 18789:18789 -n openclaw -open http://localhost:18789 +open http://127.0.0.1:18789 ``` `deploy.sh` creates token auth by default. Retrieve the generated gateway token for the Control UI: @@ -76,7 +76,7 @@ Add `--show-token` to either command to print the token to stdout for local test ```bash kubectl port-forward svc/openclaw 18789:18789 -n openclaw -open http://localhost:18789 +open http://127.0.0.1:18789 ``` ## What gets deployed diff --git a/docs/install/macos-vm.md b/docs/install/macos-vm.md index 1567aebeca2c..436358f44a28 100644 --- a/docs/install/macos-vm.md +++ b/docs/install/macos-vm.md @@ -127,32 +127,22 @@ Follow the onboarding prompts to set up your model provider (Anthropic, OpenAI, ## 7) Configure channels -Edit the config file: +Keep the Telegram token in the Gateway environment rather than copying it into +`openclaw.json`. Add `TELEGRAM_BOT_TOKEN=` to +`~/.openclaw/.env`, then load it in the current shell and add the channel: ```bash -nano ~/.openclaw/openclaw.json +export TELEGRAM_BOT_TOKEN="" +openclaw channels add --channel telegram --use-env ``` -Add your channels: - -```json5 -{ - channels: { - telegram: { - botToken: "YOUR_BOT_TOKEN", - }, - whatsapp: { - dmPolicy: "allowlist", - allowFrom: ["+15551234567"], - }, - }, -} -``` - -Then log in to WhatsApp (scan QR): +The managed Gateway reads the same state-directory `.env` after restart. For +WhatsApp, configure your allowlist and then scan the login QR code: ```bash -openclaw channels login +openclaw config set channels.whatsapp.dmPolicy allowlist +openclaw config set channels.whatsapp.allowFrom '["+15551234567"]' --strict-json +openclaw channels login --channel whatsapp ``` ## 8) Run the VM headlessly diff --git a/docs/install/migrating.md b/docs/install/migrating.md index db026d73d876..20682d7c89f1 100644 --- a/docs/install/migrating.md +++ b/docs/install/migrating.md @@ -42,15 +42,19 @@ Run `openclaw status` on the old machine to confirm your state directory path. C - On the **old** machine, stop the gateway so files are not changing mid-copy, then archive: + On the **old** machine, stop the Gateway, then create and verify a portable + archive: ```bash openclaw gateway stop - cd ~ - tar -czf openclaw-state.tgz .openclaw + mkdir -p ~/Backups/openclaw + openclaw backup create --output ~/Backups/openclaw --verify ``` - If you use multiple profiles (for example `~/.openclaw-work`), archive each separately. + Stop the Gateway before taking a machine-move snapshot. A raw copy of a + changing SQLite database can capture mismatched database and WAL files; + quiescing the Gateway also keeps the rest of the state tree stable. If you + use multiple profiles, run the command once with each profile selected. @@ -58,15 +62,25 @@ Run `openclaw status` on the old machine to confirm your state directory path. C [Install](/install) the CLI (and Node if needed) on the new machine. It is fine if onboarding creates a fresh `~/.openclaw/` — you overwrite it next. - - Transfer the archive via `scp`, `rsync -a`, or an external drive, then extract: + + Transfer the generated `.tar.gz` archive via `scp`, an external drive, or + another protected channel. On the new machine, restore it to a fresh + staging directory: ```bash - cd ~ - tar -xzf openclaw-state.tgz + openclaw backup restore --target ~/openclaw-restored ``` - Confirm hidden directories were included and file ownership matches the user that will run the gateway. + Restore never activates in place. With the Gateway stopped, use the + restored `manifest.json` mapping to move the state and workspace assets to + their recorded destinations, or point `OPENCLAW_STATE_DIR` at the restored + state asset. Confirm ownership matches the user that will run the Gateway. + + + Restoring older channel state can desynchronize ratcheting credentials such + as WhatsApp. Approvals and delivery/dedupe state also roll back, and plugin + `node_modules` trees must be reinstalled. See [Restore a full archive](/install/backups#restore-a-full-archive). + diff --git a/docs/install/northflank.mdx b/docs/install/northflank.mdx index d8cb9e0a8c5a..59089327ca6f 100644 --- a/docs/install/northflank.mdx +++ b/docs/install/northflank.mdx @@ -13,12 +13,21 @@ Deploy OpenClaw on Northflank with a one-click template and access it through th 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). +4. Set these required environment variables: + - `OPENCLAW_GATEWAY_TOKEN` (use a strong random value) + - `OPENCLAW_STATE_DIR=/data/.openclaw` + - `OPENCLAW_WORKSPACE_DIR=/data/workspace` 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. +From the Northflank shell, run the read-only deployment preflight: + +```bash +openclaw doctor --json +``` + ## What you get - Hosted OpenClaw Gateway + Control UI diff --git a/docs/install/oracle.md b/docs/install/oracle.md index de5acce616bf..afd15245ff14 100644 --- a/docs/install/oracle.md +++ b/docs/install/oracle.md @@ -91,6 +91,7 @@ Run a persistent OpenClaw Gateway on Oracle Cloud's **Always Free** ARM tier (up openclaw config set gateway.tailscale.mode serve openclaw config set gateway.trustedProxies '["127.0.0.1"]' + openclaw gateway install systemctl --user restart openclaw-gateway.service ``` @@ -183,8 +184,13 @@ These survive reboots. To take a portable snapshot: ```bash openclaw backup create +openclaw backup restore --target ``` +Restore verifies and extracts into a fresh staging directory; activation is a +separate offline step. See [Restore a full archive](/install/backups#restore-a-full-archive) +for the rollback warnings and activation sequence. + ## Fallback: SSH tunnel If Tailscale Serve is not working, use an SSH tunnel from your local machine: diff --git a/docs/install/podman.md b/docs/install/podman.md index 387f43842d99..c67a85e8019f 100644 --- a/docs/install/podman.md +++ b/docs/install/podman.md @@ -190,6 +190,14 @@ podman run --rm -it \ On SELinux hosts, add `,Z` to both bind mounts if Podman blocks access to the mounted state. +After restarting the Gateway with the updated image, run the read-only +deployment preflight through the container-aware host CLI: + +```bash +export OPENCLAW_CONTAINER=openclaw +openclaw doctor --json +``` + ## Useful commands - **Container logs:** `podman logs -f openclaw` diff --git a/docs/install/railway.mdx b/docs/install/railway.mdx index 733f47395ad6..da7c8ef7dda7 100644 --- a/docs/install/railway.mdx +++ b/docs/install/railway.mdx @@ -28,8 +28,8 @@ Deploy OpenClaw on Railway with a one-click template and access it through the w - `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) + - `OPENCLAW_STATE_DIR=/data/.openclaw` (required for persistent state) + - `OPENCLAW_WORKSPACE_DIR=/data/workspace` (required for a persistent workspace) @@ -45,6 +45,12 @@ Deploy OpenClaw on Railway with a one-click template and access it through the w +From the Railway shell, run the read-only deployment preflight: + +```bash +openclaw doctor --json +``` + ## What you get - Hosted OpenClaw Gateway + Control UI @@ -64,9 +70,12 @@ Export your state, config, auth profiles, and workspace: ```bash openclaw backup create +openclaw backup restore --target ``` -This creates a portable backup archive with OpenClaw state plus any configured workspace. See [Backup](/cli/backup) for details. +Restore verifies and extracts into a fresh staging directory; activation is a +separate offline step. See [Restore a full archive](/install/backups#restore-a-full-archive) +for the rollback warnings and activation sequence. ## Next steps diff --git a/docs/install/raspberry-pi.md b/docs/install/raspberry-pi.md index 4db79399e7d8..06338de602c7 100644 --- a/docs/install/raspberry-pi.md +++ b/docs/install/raspberry-pi.md @@ -203,8 +203,13 @@ These survive reboots and benefit from SSD over SD card for both performance and ```bash openclaw backup create +openclaw backup restore --target ``` +Restore verifies and extracts into a fresh staging directory; activation is a +separate offline step. See [Restore a full archive](/install/backups#restore-a-full-archive) +for the rollback warnings and activation sequence. + ## 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. diff --git a/docs/install/render.mdx b/docs/install/render.mdx index 8e9ddf3ca7b2..7b0e3f4e8cc0 100644 --- a/docs/install/render.mdx +++ b/docs/install/render.mdx @@ -101,9 +101,12 @@ From the Render Dashboard shell, export state, config, auth profiles, and worksp ```bash openclaw backup create +openclaw backup restore --target ``` -This creates a portable backup archive. See [Backup](/cli/backup). +Restore verifies and extracts into a fresh staging directory; activation is a +separate offline step. See [Restore a full archive](/install/backups#restore-a-full-archive) +for the rollback warnings and activation sequence. ## Troubleshooting diff --git a/docs/install/uninstall.md b/docs/install/uninstall.md index 95aef222e420..88f5bf1776e8 100644 --- a/docs/install/uninstall.md +++ b/docs/install/uninstall.md @@ -36,7 +36,10 @@ npx -y openclaw uninstall --all --yes --non-interactive Flags: `--service`, `--state`, `--workspace`, `--app` select individual scopes; `--all` selects all four. -Manual steps (same result): +Manual steps provide a complete removal path, but a raw state-directory deletion +does not have the built-in uninstaller's workspace-preservation behavior. If +you want the equivalent of `openclaw uninstall --state`, preserve every +configured workspace before deleting state. 1. Stop the gateway service: @@ -50,22 +53,32 @@ openclaw gateway stop openclaw gateway uninstall ``` -3. Delete state + config: +3. Decide whether to preserve the workspace. + +`openclaw uninstall --state` deliberately preserves configured workspace +directories, including the default `~/.openclaw/workspace`. Before using the +manual `rm -rf` below, move any workspace you want to keep outside the state +directory. If you want to remove it too, no separate deletion is needed when it +lives inside the state directory. + +4. 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. -If you want to keep a workspace inside the state dir, such as `~/.openclaw/workspace`, move it aside before running `rm -rf` or delete state contents selectively. +Restore any preserved workspace to its configured path after recreating the +parent directory, or update the workspace path in your next installation. -4. Delete your workspace (optional, removes agent files): +5. Delete a workspace stored outside the state directory only if you want to + remove its agent files too: ```bash -rm -rf ~/.openclaw/workspace +rm -rf /path/to/external/workspace ``` -5. Remove the CLI install (pick the one you used): +6. Remove the CLI install (pick the one you used): ```bash npm rm -g openclaw @@ -73,7 +86,7 @@ pnpm remove -g openclaw bun remove -g openclaw ``` -6. If you installed the macOS app: +7. If you installed the macOS app: ```bash rm -rf /Applications/OpenClaw.app @@ -81,7 +94,7 @@ rm -rf /Applications/OpenClaw.app Notes: -- If you used profiles (`--profile` / `OPENCLAW_PROFILE`), repeat step 3 for each state dir (defaults are `~/.openclaw-`). +- If you used profiles (`--profile` / `OPENCLAW_PROFILE`), repeat steps 3-4 for each state dir (defaults are `~/.openclaw-`). - In remote mode, the state dir lives on the **gateway host**, so run steps 1-4 there too. ## Manual service removal (CLI not installed) diff --git a/docs/install/updating.md b/docs/install/updating.md index 465d02c9011f..f85102ce8cd1 100644 --- a/docs/install/updating.md +++ b/docs/install/updating.md @@ -481,12 +481,24 @@ Gateway and restore the verified pre-update filesystem, volume, or VM snapshot. Preserve the current state separately before restoring because this removes changes made after the snapshot. -Broad `openclaw backup create` archives support creation and verification, but -not in-place whole-archive activation. Extract a broad archive into a staging -directory and use its `manifest.json` source-to-archive mapping for an offline -restore. `openclaw backup sqlite restore` likewise writes a verified database -to a fresh target; activating that target remains an explicit offline operator -step. +Restore a broad archive to a fresh staging directory with the current CLI: + +```bash +openclaw backup restore --target +``` + +The command verifies the archive and its SQLite databases before extraction. +Activation remains an explicit offline step: stop the Gateway, move the +restored asset tree into place or point `OPENCLAW_STATE_DIR` at the restored +state asset, run `openclaw doctor`, then restart. + +Treat a state restore as time travel. Ratcheting channel credentials, especially +WhatsApp, can desynchronize and require relinking. Approvals and +delivery/dedupe state roll back too, and plugin `node_modules` trees are not +archived. See [Restore a full archive](/install/backups#restore-a-full-archive) +for the complete activation and recovery sequence. `openclaw backup sqlite +restore` likewise writes a verified database to a fresh target; activating that +target remains an explicit offline operator step. ### Verify the rollback diff --git a/docs/install/upstash.md b/docs/install/upstash.md index 722666a05f26..a46b6a3cdc83 100644 --- a/docs/install/upstash.md +++ b/docs/install/upstash.md @@ -48,18 +48,20 @@ sudo npm install -g openclaw ## Run onboarding ```bash -openclaw onboard --install-daemon +openclaw onboard --no-install-daemon ``` Follow the prompts. Copy the dashboard URL and token when onboarding finishes. ## Start the Gateway -Configure the Gateway for the Box network and start it in the background: +Keep the Gateway on loopback for the SSH tunnel, then start one unsupervised +process in the background: ```bash -openclaw config set gateway.bind lan -nohup openclaw gateway > gateway.log 2>&1 & +openclaw config set gateway.bind loopback +nohup openclaw gateway run > gateway.log 2>&1 & +openclaw doctor --json ``` With the SSH tunnel active, open the dashboard URL locally: @@ -74,9 +76,13 @@ Set this command as the Box init script so the Gateway restarts when the Box starts: ```bash -nohup openclaw gateway > gateway.log 2>&1 & +nohup openclaw gateway run > gateway.log 2>&1 & ``` +Onboarding deliberately skips daemon installation in this guide. The Box init +script is the single owner of Gateway startup, so two processes do not contend +for the same lock and port. + ## Troubleshooting If SSH freezes during onboarding, reconnect with a clean SSH config and