--- title: "Remote Management and OTA Updates for Edge Devices" summary: "Practical guide for managing and updating OpenClaw on Pi, phones, and other always-on edge devices without physical access" read_when: - Setting up a headless Pi or cheap-phone gateway - Updating OpenClaw on an edge device remotely - Automating OTA updates with version pinning - Rolling back a broken update on a remote device --- # Remote Management and OTA Updates for Edge Devices OpenClaw runs well on always-on edge devices: Raspberry Pi boards, cheap Android phones running Termux, low-power ARM servers, and VPS instances. This guide covers how to manage and update those devices without physically touching them. ## 1. Remote Access Setup ### Tailscale (recommended) Tailscale is the lowest-friction way to reach edge devices across NAT, firewalls, or carrier-grade networks. **Install and authenticate on the device:** ```bash curl -fsSL https://tailscale.com/install.sh | sh sudo tailscale up ``` After authentication the device appears in your tailnet with a stable MagicDNS name (e.g., `gateway-pi.tail1234.ts.net`). **Expose the OpenClaw Control UI over Tailscale Serve:** ```json5 // ~/.openclaw/openclaw.json { gateway: { bind: "loopback", tailscale: { mode: "serve" }, }, } ``` Then restart the gateway: ```bash openclaw gateway restart ``` Access the Control UI from any tailnet device at `https://gateway-pi.tail1234.ts.net/`. If you prefer a direct Tailnet IP bind instead of Serve: ```json5 { gateway: { bind: "tailnet", auth: { mode: "token", token: "replace-with-your-token" }, }, } ``` See [Tailscale](/gateway/tailscale) for full config options. ### SSH Key Setup Passwordless SSH is required for unattended remote operations (cron-based updates, automated health checks). **On the device, add your control machine's public key:** ```bash mkdir -p ~/.ssh cat >> ~/.ssh/authorized_keys << 'EOF' ssh-ed25519 AAAA... user@control-machine EOF chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys ``` **Test from your control machine:** ```bash ssh user@gateway-host 'openclaw --version' ``` Once SSH is working, you can also forward the gateway port for CLI use: ```bash ssh -N -L 18789:127.0.0.1:18789 user@gateway-host # Then from the control machine: openclaw health openclaw status --deep ``` ### SSH Hardening (edge devices) On a headless Pi or phone, reduce the attack surface: ```bash # /etc/ssh/sshd_config additions PasswordAuthentication no PermitRootLogin no AllowUsers youruser ``` Restart sshd after editing: `sudo systemctl restart sshd` --- ## 2. OTA Update Strategy ### Recommended: re-run the website installer The safest update path for global npm installs is re-running the official installer. It upgrades in place and runs `openclaw doctor` automatically: ```bash ssh user@gateway-host 'curl -fsSL https://openclaw.ai/install.sh | bash -s -- --no-onboard' ``` For **global npm installs** (most edge deployments), the update is: ```bash ssh user@gateway-host 'sudo npm i -g openclaw@latest && openclaw doctor --yes && openclaw gateway restart' ``` Notes: - Global installs on most Linux systems require `sudo` because the binary lives under `/usr/lib/node_modules`. - `openclaw doctor --yes` accepts default repair prompts non-interactively; it handles config migrations and supervisor config audits. - `openclaw gateway restart` restarts the managed service (systemd user service on Linux). ### Source installs (git checkout) ```bash ssh user@gateway-host 'cd /path/to/openclaw && openclaw update --no-restart && openclaw doctor --yes && openclaw gateway restart' ``` `openclaw update` requires a clean worktree, runs `git pull --rebase`, installs deps, builds, and runs doctor. Use `--no-restart` to control the restart order yourself. ### Manual equivalent (source install) ```bash ssh user@gateway-host << 'EOF' cd /path/to/openclaw git pull --rebase origin main pnpm install pnpm build openclaw doctor --yes openclaw gateway restart EOF ``` ### After every update: verify ```bash ssh user@gateway-host << 'EOF' openclaw --version openclaw health openclaw channels status --probe EOF ``` --- ## 3. Health Monitoring ### Quick status check ```bash ssh user@gateway-host 'openclaw status' ``` For a deeper probe (runs per-channel connectivity checks): ```bash ssh user@gateway-host 'openclaw status --deep' ``` ### Gateway health endpoint ```bash ssh user@gateway-host 'openclaw health --json' ``` Returns a full health snapshot including channel probe summaries, auth age, session-store summary, and probe duration. Exits non-zero if the gateway is unreachable or any probe fails. ### Systemd service monitoring On Linux, the gateway runs as a systemd **user** service: ```bash # Service status ssh user@gateway-host 'systemctl --user status openclaw-gateway' # Tail live logs ssh user@gateway-host 'journalctl --user -u openclaw-gateway -f' # Last 50 lines ssh user@gateway-host 'journalctl --user -u openclaw-gateway -n 50' # Filter errors only ssh user@gateway-host 'journalctl --user -u openclaw-gateway -p err --since "1 hour ago"' ``` ### Systemd user linger (gateway survives logout) On a headless device, ensure the user service stays alive after SSH disconnects: ```bash ssh user@gateway-host 'sudo loginctl enable-linger $USER' ``` `openclaw doctor` will also check this and offer to enable it. ### Watchdog: simple cron health check Add to the device's crontab (`crontab -e` on the device, or via the SSH heredoc below) to detect silent failures: ```bash # Check gateway health every 15 minutes; restart if unhealthy */15 * * * * openclaw health || (openclaw gateway restart && echo "restarted $(date)" >> /tmp/openclaw-watchdog.log) ``` For a more robust watchdog with alerting (e.g., Telegram message on failure), see the [Automation](/gateway/automation) docs. --- ## 4. Rollback Procedure ### Pin to a known-good version (global npm install) If an update breaks something, install the last working version: ```bash # Find the current version before updating (keep a note of it) ssh user@gateway-host 'openclaw --version' # Roll back to a specific version ssh user@gateway-host 'sudo npm i -g openclaw@2026.1.15 && openclaw doctor --yes && openclaw gateway restart' ``` To see all published versions: ```bash npm view openclaw versions --json ``` ### Pin to a known-good git commit (source install) ```bash ssh user@gateway-host << 'EOF' cd /path/to/openclaw # Find the last working commit git log --oneline -20 # Check out a specific commit or date git checkout "$(git rev-list -n 1 --before='2026-01-15' origin/main)" # Or check out a specific tag git checkout v2026.1.15 pnpm install pnpm build openclaw doctor --yes openclaw gateway restart EOF ``` To return to the latest after the issue is resolved: ```bash git checkout main && git pull ``` ### Restore from config/state backup If the update corrupted config or state, restore from a backup (see the backup strategy in the next section): ```bash ssh user@gateway-host << 'EOF' systemctl --user stop openclaw-gateway cp -r ~/.openclaw.backup.20260115-120000/* ~/.openclaw/ chmod 600 ~/.openclaw/openclaw.json systemctl --user start openclaw-gateway EOF ``` --- ## 5. Automating Updates Safely Edge devices should update regularly but not silently break. The safest approach uses a version-pinned channel with a manual approval gate, falling back to full automation only when you are confident in the release channel. ### Backup before every update Create a timestamped backup of the OpenClaw state dir before updating: ```bash # Add to crontab (runs at 2am daily) 0 2 * * * cp -r ~/.openclaw ~/.openclaw.backup.$(date +\%Y\%m\%d-\%H\%M\%S) && find ~/.openclaw.backup.* -maxdepth 0 -mtime +7 -exec rm -rf {} + ``` This keeps 7 days of backups and automatically removes old ones. ### Automated weekly update (stable channel, global install) Add to the device's crontab (runs every Sunday at 3am): ```bash 0 3 * * 0 /usr/bin/npm i -g openclaw@latest 2>&1 | tee /tmp/openclaw-update.log && /usr/local/bin/openclaw doctor --yes >> /tmp/openclaw-update.log 2>&1 && /usr/local/bin/openclaw gateway restart >> /tmp/openclaw-update.log 2>&1 ``` Notes: - Use absolute paths in cron (the `PATH` is minimal). - `openclaw@latest` tracks the `stable` release channel only (tagged releases). This is the safest channel for unattended updates. - Redirect stdout and stderr to a log file so you can review what happened: `cat /tmp/openclaw-update.log`. ### Pin to a specific version (maximum stability) If you want zero surprise updates, pin the version explicitly: ```bash # Install once at a fixed version sudo npm i -g openclaw@2026.1.15 # When you're ready to update, explicitly bump the pin sudo npm i -g openclaw@2026.2.1 ``` Then control updates manually or through a reviewed deploy script rather than automation. ### Switch release channels ```bash # Track beta (pre-releases) ssh user@gateway-host 'openclaw update --channel beta' # Switch back to stable ssh user@gateway-host 'openclaw update --channel stable' ``` Channel semantics: - `stable`: tagged releases (`vYYYY.M.D`), npm dist-tag `latest` — recommended for edge devices. - `beta`: pre-release tags (`vYYYY.M.D-beta.N`) — get new features earlier, with more risk. - `dev`: moving head on `main` — not recommended for unattended edge devices. ### Staging: test on one device before rolling to all If you have multiple edge devices, update one first and verify health before updating the rest: ```bash # Update and verify device-1 ssh user@device-1 'sudo npm i -g openclaw@latest && openclaw doctor --yes && openclaw gateway restart' ssh user@device-1 'openclaw health && openclaw channels status --probe' # If healthy, roll out to the rest for host in device-2 device-3; do ssh user@$host 'sudo npm i -g openclaw@latest && openclaw doctor --yes && openclaw gateway restart' ssh user@$host 'openclaw health' done ``` --- ## 6. Quick Reference ### SSH one-liners ```bash # Check version ssh user@gateway-host 'openclaw --version' # Health check ssh user@gateway-host 'openclaw health --json' # Full update (global install) ssh user@gateway-host 'sudo npm i -g openclaw@latest && openclaw doctor --yes && openclaw gateway restart' # Restart gateway only ssh user@gateway-host 'openclaw gateway restart' # Restart systemd service directly ssh user@gateway-host 'systemctl --user restart openclaw-gateway' # Read recent logs ssh user@gateway-host 'journalctl --user -u openclaw-gateway -n 100' # Check channels ssh user@gateway-host 'openclaw channels status --probe' # Roll back to a pinned version ssh user@gateway-host 'sudo npm i -g openclaw@ && openclaw doctor --yes && openclaw gateway restart' ``` ### Cron template ```bash # Backup state daily at 2am (7-day retention) 0 2 * * * cp -r ~/.openclaw ~/.openclaw.backup.$(date +\%Y\%m\%d) && find ~/.openclaw.backup.* -maxdepth 0 -mtime +7 -exec rm -rf {} + # Health watchdog every 15 min — restart if unhealthy */15 * * * * /usr/local/bin/openclaw health || (/usr/local/bin/openclaw gateway restart && echo "restarted $(date)" >> /tmp/openclaw-watchdog.log) # Weekly update on stable channel (Sunday 3am) 0 3 * * 0 /usr/bin/npm i -g openclaw@latest && /usr/local/bin/openclaw doctor --yes && /usr/local/bin/openclaw gateway restart ``` --- ## Related docs - [Updating](/install/updating) — full update command reference - [Tailscale](/gateway/tailscale) — Serve/Funnel config options - [Remote Access](/gateway/remote) — SSH tunnels and remote CLI defaults - [Doctor](/gateway/doctor) — repair, migrate, and audit - [Health Checks](/gateway/health) — health and status commands - [Troubleshooting](/gateway/troubleshooting) — common issues and fixes