mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
docs(hosting): fix unsafe deployment instructions
This commit is contained in:
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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="<bot-token>"
|
||||
openclaw channels add --channel telegram --use-env
|
||||
```
|
||||
|
||||
Also store `TELEGRAM_BOT_TOKEN=<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:
|
||||
|
||||
|
||||
@@ -75,11 +75,11 @@ DigitalOcean is a straightforward paid VPS path. For cheaper or free options:
|
||||
|
||||
<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
|
||||
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
|
||||
```
|
||||
</Step>
|
||||
|
||||
@@ -130,9 +130,13 @@ These survive Droplet reboots. To take a portable snapshot:
|
||||
|
||||
```bash
|
||||
openclaw backup create
|
||||
openclaw backup restore <archive.tar.gz> --target <fresh-directory>
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
<Note>
|
||||
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.
|
||||
</Note>
|
||||
|
||||
## Build and launch
|
||||
|
||||
+17
-18
@@ -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
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Faster rebuilds">
|
||||
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.
|
||||
|
||||
</Accordion>
|
||||
|
||||
|
||||
+17
-1
@@ -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 <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.
|
||||
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://<vm-name>.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 <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
|
||||
@@ -103,6 +103,22 @@ Set up OpenClaw (https://docs.openclaw.ai/install) on this VM. Use the non-inter
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Trust nginx and allow the public browser origin">
|
||||
Configure the exact public origin and trust only the loopback nginx hop:
|
||||
|
||||
```bash
|
||||
openclaw config set gateway.controlUi.allowedOrigins '["https://<vm-name>.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.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Access OpenClaw and approve devices">
|
||||
Open `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.
|
||||
|
||||
|
||||
+43
-9
@@ -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.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Shared Docker VM runtime steps">
|
||||
|
||||
+17
-9
@@ -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.
|
||||
|
||||
</Step>
|
||||
|
||||
+25
-13
@@ -151,21 +151,24 @@ curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -
|
||||
### 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">
|
||||
Optional dependency installer and package-script runner.
|
||||
</Card>
|
||||
<Card title="ClawDock" href="/install/clawdock" icon="container">
|
||||
Community Docker Compose setup and shell helpers.
|
||||
</Card>
|
||||
<Card title="Docker" href="/install/docker" icon="container">
|
||||
Containerized or headless deployments.
|
||||
</Card>
|
||||
<Card title="Nix" href="/install/nix" icon="snowflake">
|
||||
Declarative install via Nix flake.
|
||||
</Card>
|
||||
<Card title="Podman" href="/install/podman" icon="container">
|
||||
Rootless container alternative to Docker.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Verify the install
|
||||
@@ -194,20 +197,29 @@ template.
|
||||
<Card title="Cloudflare" href="/install/cloudflare">
|
||||
Experimental Worker + Container deployment.
|
||||
</Card>
|
||||
<Card title="VPS" href="/vps">
|
||||
Pick a provider.
|
||||
</Card>
|
||||
<Card title="Docker VM" href="/install/docker-vm-runtime">
|
||||
Shared Docker steps.
|
||||
</Card>
|
||||
<Card title="Kubernetes" href="/install/kubernetes">
|
||||
K8s deployment.
|
||||
</Card>
|
||||
<Card title="macOS VM" href="/install/macos-vm">
|
||||
Isolated local or hosted macOS deployment.
|
||||
</Card>
|
||||
<Card title="Upstash Box" href="/install/upstash">
|
||||
Managed Linux host with SSH-tunneled access.
|
||||
</Card>
|
||||
<Card title="VPS" href="/vps">
|
||||
Pick a provider.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Update, migrate, or uninstall
|
||||
## Back up, update, migrate, or uninstall
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Backups" href="/install/backups" icon="archive">
|
||||
Create, verify, and restore state archives.
|
||||
</Card>
|
||||
<Card title="Updating" href="/install/updating" icon="refresh-cw">
|
||||
Keep OpenClaw up to date.
|
||||
</Card>
|
||||
|
||||
@@ -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 <path>` | Git checkout directory (default: `~/openclaw`) |
|
||||
| `--no-git-update` | Skip `git pull` for an existing git checkout |
|
||||
| `--version <ver>` | OpenClaw version or dist-tag (default: `latest`) |
|
||||
| `--compatible-with <ver>` | Refuse a CLI that cannot modify config written by `<ver>` |
|
||||
| `--node-version <ver>` | Node version (default: `24.15.0`; `22.22.3` on Linux ARMv7) |
|
||||
| `--json` | Emit NDJSON events |
|
||||
| `--onboard` | Run `openclaw onboard` after install |
|
||||
|
||||
@@ -26,7 +26,7 @@ export <PROVIDER>_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
|
||||
|
||||
+10
-20
@@ -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=<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="<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
|
||||
|
||||
@@ -42,15 +42,19 @@ Run `openclaw status` on the old machine to confirm your state directory path. C
|
||||
|
||||
<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:
|
||||
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.
|
||||
|
||||
</Step>
|
||||
|
||||
@@ -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.
|
||||
</Step>
|
||||
|
||||
<Step title="Copy state directory and workspace">
|
||||
Transfer the archive via `scp`, `rsync -a`, or an external drive, then extract:
|
||||
<Step title="Transfer and restore to staging">
|
||||
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 <archive.tar.gz> --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.
|
||||
|
||||
<Warning>
|
||||
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).
|
||||
</Warning>
|
||||
|
||||
</Step>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <archive.tar.gz> --target <fresh-directory>
|
||||
```
|
||||
|
||||
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:
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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)
|
||||
|
||||
</Step>
|
||||
|
||||
@@ -45,6 +45,12 @@ Deploy OpenClaw on Railway with a one-click template and access it through the w
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
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 <archive.tar.gz> --target <fresh-directory>
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -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 <archive.tar.gz> --target <fresh-directory>
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
@@ -101,9 +101,12 @@ From the Render Dashboard shell, export state, config, auth profiles, and worksp
|
||||
|
||||
```bash
|
||||
openclaw backup create
|
||||
openclaw backup restore <archive.tar.gz> --target <fresh-directory>
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -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-<profile>`).
|
||||
- If you used profiles (`--profile` / `OPENCLAW_PROFILE`), repeat steps 3-4 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)
|
||||
|
||||
@@ -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 <archive.tar.gz> --target <fresh-directory>
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
|
||||
+11
-5
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user