From e466b5566147c050e60f866bf515728c667b0c0c Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Thu, 19 Mar 2026 11:56:49 -0700 Subject: [PATCH] docs: convert Fly, Hetzner, GCP, Azure hosting pages to Mintlify Steps --- docs/install/azure.md | 207 ++++++++++---------- docs/install/fly.md | 330 ++++++++++++++++---------------- docs/install/gcp.md | 406 ++++++++++++++++++++-------------------- docs/install/hetzner.md | 234 +++++++++++------------ 4 files changed, 591 insertions(+), 586 deletions(-) diff --git a/docs/install/azure.md b/docs/install/azure.md index a257059f75d..615049ef937 100644 --- a/docs/install/azure.md +++ b/docs/install/azure.md @@ -27,139 +27,148 @@ You’ll 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) -## 1) Sign in to Azure CLI + + + ```bash + az login # Sign in and select your Azure subscription + az extension add -n ssh # Extension required for Azure Bastion SSH management + ``` + -```bash -az login # Sign in and select your Azure subscription -az extension add -n ssh # Extension required for Azure Bastion SSH management -``` + + ```bash + az provider register --namespace Microsoft.Compute + az provider register --namespace Microsoft.Network + ``` -## 2) Register required resource providers (one-time) + Verify Azure resource provider registration. Wait until both show `Registered`. -```bash -az provider register --namespace Microsoft.Compute -az provider register --namespace Microsoft.Network -``` + ```bash + az provider show --namespace Microsoft.Compute --query registrationState -o tsv + az provider show --namespace Microsoft.Network --query registrationState -o tsv + ``` -Verify Azure resource provider 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 -``` + + ```bash + RG="rg-openclaw" + LOCATION="westus2" + TEMPLATE_URI="https://raw.githubusercontent.com/openclaw/openclaw/main/infra/azure/templates/azuredeploy.json" + PARAMS_URI="https://raw.githubusercontent.com/openclaw/openclaw/main/infra/azure/templates/azuredeploy.parameters.json" + ``` + -## 3) Set deployment variables + + Use your existing public key if you have one: -```bash -RG="rg-openclaw" -LOCATION="westus2" -TEMPLATE_URI="https://raw.githubusercontent.com/openclaw/openclaw/main/infra/azure/templates/azuredeploy.json" -PARAMS_URI="https://raw.githubusercontent.com/openclaw/openclaw/main/infra/azure/templates/azuredeploy.parameters.json" -``` + ```bash + SSH_PUB_KEY="$(cat ~/.ssh/id_ed25519.pub)" + ``` -## 4) Select SSH key + If you don’t have an SSH key yet, run the following: -Use your existing public key if you have one: + ```bash + ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519 -C "you@example.com" + SSH_PUB_KEY="$(cat ~/.ssh/id_ed25519.pub)" + ``` -```bash -SSH_PUB_KEY="$(cat ~/.ssh/id_ed25519.pub)" -``` + -If you don’t have an SSH key yet, run the following: + + Set VM and disk sizing variables: -```bash -ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519 -C "you@example.com" -SSH_PUB_KEY="$(cat ~/.ssh/id_ed25519.pub)" -``` + ```bash + VM_SIZE="Standard_B2as_v2" + OS_DISK_SIZE_GB=64 + ``` -## 5) Select VM size and OS disk size + Choose a VM size and OS disk size that are available in your Azure subscription/region and matches your workload: -Set VM and disk sizing variables: + - Start smaller for light usage and scale up later + - Use more vCPU/RAM/OS disk size 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 -```bash -VM_SIZE="Standard_B2as_v2" -OS_DISK_SIZE_GB=64 -``` + List VM sizes available in your target region: -Choose a VM size and OS disk size that are available in your Azure subscription/region and matches your workload: + ```bash + az vm list-skus --location "${LOCATION}" --resource-type virtualMachines -o table + ``` -- Start smaller for light usage and scale up later -- Use more vCPU/RAM/OS disk size 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 + Check your current VM vCPU and OS disk size usage/quota: -List VM sizes available in your target region: + ```bash + az vm list-usage --location "${LOCATION}" -o table + ``` -```bash -az vm list-skus --location "${LOCATION}" --resource-type virtualMachines -o table -``` + -Check your current VM vCPU and OS disk size usage/quota: + + ```bash + az group create -n "${RG}" -l "${LOCATION}" + ``` + -```bash -az vm list-usage --location "${LOCATION}" -o table -``` + + This command applies your selected SSH key, VM size, and OS disk size. -## 6) Create the resource group + ```bash + az deployment group create \ + -g "${RG}" \ + --template-uri "${TEMPLATE_URI}" \ + --parameters "${PARAMS_URI}" \ + --parameters location="${LOCATION}" \ + --parameters vmSize="${VM_SIZE}" \ + --parameters osDiskSizeGb="${OS_DISK_SIZE_GB}" \ + --parameters sshPublicKey="${SSH_PUB_KEY}" + ``` -```bash -az group create -n "${RG}" -l "${LOCATION}" -``` + -## 7) Deploy resources + + ```bash + RG="rg-openclaw" + VM_NAME="vm-openclaw" + BASTION_NAME="bas-openclaw" + ADMIN_USERNAME="openclaw" + VM_ID="$(az vm show -g "${RG}" -n "${VM_NAME}" --query id -o tsv)" -This command applies your selected SSH key, VM size, and OS disk size. + 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 + ``` -```bash -az deployment group create \ - -g "${RG}" \ - --template-uri "${TEMPLATE_URI}" \ - --parameters "${PARAMS_URI}" \ - --parameters location="${LOCATION}" \ - --parameters vmSize="${VM_SIZE}" \ - --parameters osDiskSizeGb="${OS_DISK_SIZE_GB}" \ - --parameters sshPublicKey="${SSH_PUB_KEY}" -``` + -## 8) SSH into the VM through Azure Bastion + + ```bash + curl -fsSL https://openclaw.ai/install.sh -o /tmp/openclaw-install.sh + bash /tmp/openclaw-install.sh + rm -f /tmp/openclaw-install.sh + openclaw --version + ``` -```bash -RG="rg-openclaw" -VM_NAME="vm-openclaw" -BASTION_NAME="bas-openclaw" -ADMIN_USERNAME="openclaw" -VM_ID="$(az vm show -g "${RG}" -n "${VM_NAME}" --query id -o tsv)" + The installer script handles Node detection/installation and runs onboarding by default. -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 -``` + -## 9) Install OpenClaw (in the VM shell) + + After onboarding completes: -```bash -curl -fsSL https://openclaw.ai/install.sh -o /tmp/openclaw-install.sh -bash /tmp/openclaw-install.sh -rm -f /tmp/openclaw-install.sh -openclaw --version -``` + ```bash + openclaw gateway status + ``` -The installer script handles Node detection/installation and runs onboarding by default. + 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). -## 10) Verify the Gateway + The included ARM template uses Ubuntu image `version: "latest"` for convenience. If you need reproducible builds, pin a specific image version in `infra/azure/templates/azuredeploy.json` (you can list versions with `az vm image list --publisher Canonical --offer ubuntu-24_04-lts --sku server --all -o table`). -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). - -The included ARM template uses Ubuntu image `version: "latest"` for convenience. If you need reproducible builds, pin a specific image version in `infra/azure/templates/azuredeploy.json` (you can list versions with `az vm image list --publisher Canonical --offer ubuntu-24_04-lts --sku server --all -o table`). + + ## Next steps diff --git a/docs/install/fly.md b/docs/install/fly.md index 1c01c7f63fa..aacfa484670 100644 --- a/docs/install/fly.md +++ b/docs/install/fly.md @@ -25,220 +25,228 @@ read_when: 3. Deploy with `fly deploy` 4. SSH in to create config or use Control UI -## 1) Create the Fly app + + + ```bash + # Clone the repo + git clone https://github.com/openclaw/openclaw.git + cd openclaw -```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 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 + ``` -# 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). -**Tip:** Choose a region close to you. Common options: `lhr` (London), `iad` (Virginia), `sjc` (San Jose). + -## 2) Configure fly.toml + + Edit `fly.toml` to match your app name and requirements. -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`. -**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" -```toml -app = "my-openclaw" # Your app name -primary_region = "iad" + [build] + dockerfile = "Dockerfile" -[build] - dockerfile = "Dockerfile" + [env] + NODE_ENV = "production" + OPENCLAW_PREFER_PNPM = "1" + OPENCLAW_STATE_DIR = "/data" + NODE_OPTIONS = "--max-old-space-size=1536" -[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" -[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"] -[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" -[[vm]] - size = "shared-cpu-2x" - memory = "2048mb" + [mounts] + source = "openclaw_data" + destination = "/data" + ``` -[mounts] - source = "openclaw_data" - destination = "/data" -``` + **Key settings:** -**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 | -| 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 | + -## 3) Set secrets + + ```bash + # Required: Gateway token (for non-loopback binding) + fly secrets set OPENCLAW_GATEWAY_TOKEN=$(openssl rand -hex 32) -```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-... -# 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=... -# 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... + ``` -# Channel tokens -fly secrets set DISCORD_BOT_TOKEN=MTQ... -``` + **Notes:** -**Notes:** + - Non-loopback binds (`--bind lan`) require `OPENCLAW_GATEWAY_TOKEN` for security. + - 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. -- Non-loopback binds (`--bind lan`) require `OPENCLAW_GATEWAY_TOKEN` for security. -- 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. + -## 4) Deploy + + ```bash + fly deploy + ``` -```bash -fly deploy -``` + First deploy builds the Docker image (~2-3 minutes). Subsequent deploys are faster. -First deploy builds the Docker image (~2-3 minutes). Subsequent deploys are faster. + After deployment, verify: -After deployment, verify: + ```bash + fly status + fly logs + ``` -```bash -fly status -fly logs -``` + You should see: -You should see: + ``` + [gateway] listening on ws://0.0.0.0:3000 (PID xxx) + [discord] logged in to discord as xxx + ``` -``` -[gateway] listening on ws://0.0.0.0:3000 (PID xxx) -[discord] logged in to discord as xxx -``` + -## 5) Create config file + + SSH into the machine to create a proper config: -SSH into the machine to create a proper config: + ```bash + fly ssh console + ``` -```bash -fly ssh console -``` + Create the config directory and file: -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-4o"] - }, - "maxConcurrent": 4 - }, - "list": [ - { - "id": "main", - "default": true - } - ] - }, - "auth": { - "profiles": { - "anthropic:default": { "mode": "token", "provider": "anthropic" }, - "openai:default": { "mode": "token", "provider": "openai" } - } - }, - "bindings": [ + ```bash + mkdir -p /data + cat > /data/openclaw.json << 'EOF' { - "agentId": "main", - "match": { "channel": "discord" } - } - ], - "channels": { - "discord": { - "enabled": true, - "groupPolicy": "allowlist", - "guilds": { - "YOUR_GUILD_ID": { - "channels": { "general": { "allow": true } }, - "requireMention": false + "agents": { + "defaults": { + "model": { + "primary": "anthropic/claude-opus-4-6", + "fallbacks": ["anthropic/claude-sonnet-4-6", "openai/gpt-4o"] + }, + "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": {} } - }, - "gateway": { - "mode": "local", - "bind": "auto" - }, - "meta": {} -} -EOF -``` + EOF + ``` -**Note:** With `OPENCLAW_STATE_DIR=/data`, the config path is `/data/openclaw.json`. + **Note:** With `OPENCLAW_STATE_DIR=/data`, the config path is `/data/openclaw.json`. -**Note:** The Discord token can come from either: + **Note:** The Discord token can come from either: -- Environment variable: `DISCORD_BOT_TOKEN` (recommended for secrets) -- Config file: `channels.discord.token` + - 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. + If using env var, no need to add token to config. The gateway reads `DISCORD_BOT_TOKEN` automatically. -Restart to apply: + Restart to apply: -```bash -exit -fly machine restart -``` + ```bash + exit + fly machine restart + ``` -## 6) Access the Gateway + -### Control UI + + ### Control UI -Open in browser: + Open in browser: -```bash -fly open -``` + ```bash + fly open + ``` -Or visit `https://my-openclaw.fly.dev/` + Or visit `https://my-openclaw.fly.dev/` -Paste your gateway token (the one from `OPENCLAW_GATEWAY_TOKEN`) to authenticate. + Paste your gateway token (the one from `OPENCLAW_GATEWAY_TOKEN`) to authenticate. -### Logs + ### Logs -```bash -fly logs # Live logs -fly logs --no-tail # Recent logs -``` + ```bash + fly logs # Live logs + fly logs --no-tail # Recent logs + ``` -### SSH Console + ### SSH Console -```bash -fly ssh console -``` + ```bash + fly ssh console + ``` + + + ## Troubleshooting diff --git a/docs/install/gcp.md b/docs/install/gcp.md index e997aed1cb1..3714d9bcb1b 100644 --- a/docs/install/gcp.md +++ b/docs/install/gcp.md @@ -65,277 +65,271 @@ For the generic Docker flow, see [Docker](/install/docker). --- -## 1) Install gcloud CLI (or use Console) + + + **Option A: gcloud CLI** (recommended for automation) -**Option A: gcloud CLI** (recommended for automation) + Install from [https://cloud.google.com/sdk/docs/install](https://cloud.google.com/sdk/docs/install) -Install from [https://cloud.google.com/sdk/docs/install](https://cloud.google.com/sdk/docs/install) + Initialize and authenticate: -Initialize and authenticate: + ```bash + gcloud init + gcloud auth login + ``` -```bash -gcloud init -gcloud auth login -``` + **Option B: Cloud Console** -**Option B: Cloud Console** + All steps can be done via the web UI at [https://console.cloud.google.com](https://console.cloud.google.com) -All steps can be done via the web UI at [https://console.cloud.google.com](https://console.cloud.google.com) + ---- + + **CLI:** -## 2) Create a GCP project + ```bash + gcloud projects create my-openclaw-project --name="OpenClaw Gateway" + gcloud config set project my-openclaw-project + ``` -**CLI:** + Enable billing at [https://console.cloud.google.com/billing](https://console.cloud.google.com/billing) (required for Compute Engine). -```bash -gcloud projects create my-openclaw-project --name="OpenClaw Gateway" -gcloud config set project my-openclaw-project -``` + Enable the Compute Engine API: -Enable billing at [https://console.cloud.google.com/billing](https://console.cloud.google.com/billing) (required for Compute Engine). + ```bash + gcloud services enable compute.googleapis.com + ``` -Enable the Compute Engine API: + **Console:** -```bash -gcloud services enable compute.googleapis.com -``` + 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 -**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 + + **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) | -## 3) Create the VM + **CLI:** -**Machine types:** + ```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 + ``` -| 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) | + **Console:** -**CLI:** + 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 -```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:** + + **CLI:** -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 + ```bash + gcloud compute ssh openclaw-gateway --zone=us-central1-a + ``` ---- + **Console:** -## 4) SSH into the VM + Click the "SSH" button next to your VM in the Compute Engine dashboard. -**CLI:** + Note: SSH key propagation can take 1-2 minutes after VM creation. If connection is refused, wait and retry. -```bash -gcloud compute ssh openclaw-gateway --zone=us-central1-a -``` + -**Console:** + + ```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 + ``` -Click the "SSH" button next to your VM in the Compute Engine dashboard. + Log out and back in for the group change to take effect: -Note: SSH key propagation can take 1-2 minutes after VM creation. If connection is refused, wait and retry. + ```bash + exit + ``` ---- + Then SSH back in: -## 5) Install Docker (on the VM) + ```bash + gcloud compute ssh openclaw-gateway --zone=us-central1-a + ``` -```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 -``` + Verify: -Log out and back in for the group change to take effect: + ```bash + docker --version + docker compose version + ``` -```bash -exit -``` + -Then SSH back in: + + ```bash + git clone https://github.com/openclaw/openclaw.git + cd openclaw + ``` -```bash -gcloud compute ssh openclaw-gateway --zone=us-central1-a -``` + This guide assumes you will build a custom image to guarantee binary persistence. -Verify: + -```bash -docker --version -docker compose version -``` + + Docker containers are ephemeral. + All long-lived state must live on the host. ---- + ```bash + mkdir -p ~/.openclaw + mkdir -p ~/.openclaw/workspace + ``` -## 6) Clone the OpenClaw repository + -```bash -git clone https://github.com/openclaw/openclaw.git -cd openclaw -``` + + Create `.env` in the repository root. -This guide assumes you will build a custom image to guarantee binary persistence. + ```bash + OPENCLAW_IMAGE=openclaw:latest + OPENCLAW_GATEWAY_TOKEN=change-me-now + OPENCLAW_GATEWAY_BIND=lan + OPENCLAW_GATEWAY_PORT=18789 ---- + OPENCLAW_CONFIG_DIR=/home/$USER/.openclaw + OPENCLAW_WORKSPACE_DIR=/home/$USER/.openclaw/workspace -## 7) Create persistent host directories + GOG_KEYRING_PASSWORD=change-me-now + XDG_CONFIG_HOME=/home/node/.openclaw + ``` -Docker containers are ephemeral. -All long-lived state must live on the host. + Generate strong secrets: -```bash -mkdir -p ~/.openclaw -mkdir -p ~/.openclaw/workspace -``` + ```bash + openssl rand -hex 32 + ``` ---- + **Do not commit this file.** -## 8) Configure environment variables + -Create `.env` in the repository root. + + Create or update `docker-compose.yml`. -```bash -OPENCLAW_IMAGE=openclaw:latest -OPENCLAW_GATEWAY_TOKEN=change-me-now -OPENCLAW_GATEWAY_BIND=lan -OPENCLAW_GATEWAY_PORT=18789 + ```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", + ] + ``` -OPENCLAW_CONFIG_DIR=/home/$USER/.openclaw -OPENCLAW_WORKSPACE_DIR=/home/$USER/.openclaw/workspace + `--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. -GOG_KEYRING_PASSWORD=change-me-now -XDG_CONFIG_HOME=/home/node/.openclaw -``` + -Generate strong secrets: + + Use the shared runtime guide for the common Docker host flow: -```bash -openssl rand -hex 32 -``` + - [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) -**Do not commit this file.** + ---- + + 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. -## 9) Docker Compose configuration + When binding to LAN (`OPENCLAW_GATEWAY_BIND=lan`), configure a trusted browser origin before continuing: -Create or update `docker-compose.yml`. + ```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. -```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", - ] -``` + + + + Create an SSH tunnel to forward the Gateway port: -`--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. + ```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/` + + Fetch a fresh tokenized dashboard link: -## 10) Shared Docker VM runtime steps + ```bash + docker compose run --rm openclaw-cli dashboard --no-open + ``` -Use the shared runtime guide for the common Docker host flow: + Paste the token from that URL. + + If Control UI shows `unauthorized` or `disconnected (1008): pairing required`, approve the browser device: -- [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) - ---- - -## 11) 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. - -## 12) 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/` - -Fetch a fresh tokenized dashboard link: - -```bash -docker compose run --rm openclaw-cli dashboard --no-open -``` - -Paste the token from that URL. - -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 -``` - -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). + ```bash + docker compose run --rm openclaw-cli devices list + docker compose run --rm openclaw-cli devices approve + ``` + + 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). + + + --- diff --git a/docs/install/hetzner.md b/docs/install/hetzner.md index 906ac7969a4..b123b3d92f6 100644 --- a/docs/install/hetzner.md +++ b/docs/install/hetzner.md @@ -72,162 +72,156 @@ For the generic Docker flow, see [Docker](/install/docker). --- -## 1) Provision the VPS + + + Create an Ubuntu or Debian VPS in Hetzner. -Create an Ubuntu or Debian VPS in Hetzner. + Connect as root: -Connect as root: + ```bash + ssh root@YOUR_VPS_IP + ``` -```bash -ssh root@YOUR_VPS_IP -``` + This guide assumes the VPS is stateful. + Do not treat it as disposable infrastructure. -This guide assumes the VPS is stateful. -Do not treat it as disposable infrastructure. + ---- + + ```bash + apt-get update + apt-get install -y git curl ca-certificates + curl -fsSL https://get.docker.com | sh + ``` -## 2) Install Docker (on the VPS) + Verify: -```bash -apt-get update -apt-get install -y git curl ca-certificates -curl -fsSL https://get.docker.com | sh -``` + ```bash + docker --version + docker compose version + ``` -Verify: + -```bash -docker --version -docker compose version -``` + + ```bash + git clone https://github.com/openclaw/openclaw.git + cd openclaw + ``` ---- + This guide assumes you will build a custom image to guarantee binary persistence. -## 3) Clone the OpenClaw repository + -```bash -git clone https://github.com/openclaw/openclaw.git -cd openclaw -``` + + Docker containers are ephemeral. + All long-lived state must live on the host. -This guide assumes you will build a custom image to guarantee binary persistence. + ```bash + mkdir -p /root/.openclaw/workspace ---- + # Set ownership to the container user (uid 1000): + chown -R 1000:1000 /root/.openclaw + ``` -## 4) Create persistent host directories + -Docker containers are ephemeral. -All long-lived state must live on the host. + + Create `.env` in the repository root. -```bash -mkdir -p /root/.openclaw/workspace + ```bash + OPENCLAW_IMAGE=openclaw:latest + OPENCLAW_GATEWAY_TOKEN=change-me-now + OPENCLAW_GATEWAY_BIND=lan + OPENCLAW_GATEWAY_PORT=18789 -# Set ownership to the container user (uid 1000): -chown -R 1000:1000 /root/.openclaw -``` + OPENCLAW_CONFIG_DIR=/root/.openclaw + OPENCLAW_WORKSPACE_DIR=/root/.openclaw/workspace ---- + GOG_KEYRING_PASSWORD=change-me-now + XDG_CONFIG_HOME=/home/node/.openclaw + ``` -## 5) Configure environment variables + Generate strong secrets: -Create `.env` in the repository root. + ```bash + openssl rand -hex 32 + ``` -```bash -OPENCLAW_IMAGE=openclaw:latest -OPENCLAW_GATEWAY_TOKEN=change-me-now -OPENCLAW_GATEWAY_BIND=lan -OPENCLAW_GATEWAY_PORT=18789 + **Do not commit this file.** -OPENCLAW_CONFIG_DIR=/root/.openclaw -OPENCLAW_WORKSPACE_DIR=/root/.openclaw/workspace + -GOG_KEYRING_PASSWORD=change-me-now -XDG_CONFIG_HOME=/home/node/.openclaw -``` + + Create or update `docker-compose.yml`. -Generate strong secrets: + ```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", + ] + ``` -```bash -openssl rand -hex 32 -``` + `--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. -**Do not commit this file.** + ---- + + Use the shared runtime guide for the common Docker host flow: -## 6) Docker Compose configuration + - [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) -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", - ] -``` + + After the shared build and launch steps, tunnel from your laptop: -`--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. + ```bash + ssh -N -L 18789:127.0.0.1:18789 root@YOUR_VPS_IP + ``` ---- + Open: -## 7) Shared Docker VM runtime steps + `http://127.0.0.1:18789/` -Use the shared runtime guide for the common Docker host flow: + Paste your gateway token. -- [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) - ---- - -## 8) 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 your gateway token. - ---- + + The shared persistence map lives in [Docker VM Runtime](/install/docker-vm-runtime#what-persists-where).