All systems operational Your IP: 216.73.216.50 info@cloudhosting.lv +371 66 66 29 69 Client area

← All questions

Install OpenClaw on a VPS: step by step

Updated:

To install OpenClaw on a VPS you need a fresh Ubuntu 24.04 server, a normal (non-root) user and Node 24.16+ or 26.1+, then one command: curl -fsSL https://openclaw.ai/install.sh | bash, followed by openclaw onboard --install-daemon, which stores your model key, writes the gateway config and registers a systemd service. Keep the gateway on its default loopback bind (port 18789), reach the Control UI through an SSH tunnel, connect a Telegram bot and approve yourself as the only allowed sender. The whole process takes about 15 minutes; Docker is the alternative path if you prefer containers.

Rewritten in September 2026 against the official documentation and the current stable release, v2026.9.4 (11 September 2026): the top-level commands from our February 2026 version are unchanged, but the Node requirement, update flow, Telegram allowlist format and security defaults have moved on.

Before you start: OS, server size, user

OpenClaw runs on macOS, Linux and Windows; on a server that means Linux. We use Ubuntu 24.04 LTS because the gateway relies on systemd user services and the release gets security updates for years; avoid minimal images without systemd.

The gateway is a light Node application. In our deployments 2 vCPU and 4 GB RAM is comfortable for one owner using a hosted model (OpenAI, Anthropic or an OpenAI-compatible gateway such as avots.ai). If you plan to run a local model through Ollama on the same machine, the model sets the size; see which server runs a local AI model. Any plan from our VPS catalogue with Ubuntu 24.04 works. Have ready: SSH access, one provider API key and a Telegram account.

Step 1: prepare Ubuntu 24.04

Log in as root once, update the system and create the user that will own the gateway. The gateway runbook is explicit: do not run the gateway as root.

apt update && apt upgrade -y
adduser openclaw
usermod -aG sudo openclaw
ufw allow OpenSSH
ufw enable

The gateway port is never opened to the internet in this guide, so SSH is the only firewall rule. From here on log in as the new user (ssh openclaw@your-server) and stay there.

Node.js

OpenClaw requires Node 24.16+ or 26.1+, and the docs recommend Node 26. The official installer provisions the supported Node 24 LTS line on Linux when Node is missing, so with path A you can skip this step. To manage Node yourself, the docs list NodeSource for Ubuntu:

curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
sudo apt-get install -y nodejs

Version managers (fnm, nvm, mise, asdf) work too, but initialise them in your shell startup file, or openclaw may not be found in new sessions because PATH lacks the Node bin directory.

Step 2: choose an install path

Path A (installer or npm) puts the CLI in the global npm prefix and runs the gateway as a systemd user service; simplest on a single VPS. Path B (Docker) runs ghcr.io/openclaw/openclaw under Docker Compose with state in a volume; pick it if the host already runs everything in containers.

Path A: installer script or npm

curl -fsSL https://openclaw.ai/install.sh | bash

The script installs the CLI globally and starts onboarding straight away. To install now and configure later, the documented form is curl -fsSL https://openclaw.ai/install.sh | bash -s -- --no-onboard. The equivalent with npm (npm 12 or 11.16+):

npm install -g openclaw@latest --allow-scripts=openclaw
openclaw onboard --install-daemon

The --allow-scripts=openclaw flag matters: npm 12 blocks unapproved package lifecycle scripts by default and the flag allows OpenClaw's preinstall and postinstall steps (omit it on npm 11.15 or earlier). pnpm and Bun variants are in the install docs. Verify with openclaw --version and openclaw doctor before going further.

Path B: Docker

The official Docker guide starts "from the repo root" without saying how you got there, so clone the repository first:

git clone https://github.com/openclaw/openclaw.git
cd openclaw
export OPENCLAW_IMAGE="ghcr.io/openclaw/openclaw:latest"
./scripts/docker/setup.sh

You need Docker Engine and Docker Compose v2. State lives in a volume at /home/node/.openclaw, and the Control UI answers at http://127.0.0.1:18789/ with the token from the generated .env. The :latest-browser tag adds Chromium and Playwright. Channels and diagnostics go through the CLI container:

docker compose run --rm openclaw-cli channels add --channel telegram --token "<token>"
docker compose run --rm openclaw-cli doctor --json

One caveat from our own deployments: the sandbox backend is Docker, so sandbox mode "all" inside a containerised gateway needs the docker command inside that container. Sandboxing is off by default and does not require the gateway itself to run in a container, so for sandboxed tools path A with Docker on the host is simpler. Full reference: the official Docker guide.

Step 3: onboarding and the first provider key

openclaw onboard --install-daemon is the interactive wizard plus service registration. In local mode it walks through the workspace, model provider and auth (API key or OAuth), gateway settings (port, bind, secret storage, optional Tailscale exposure), channels, optional web search and skills, the daemon and a health check. The config lands in ~/.openclaw/openclaw.json; the wizard stores provider credentials as named auth profiles, and in our deployments the raw secrets live in ~/.openclaw/.env. The docs describe the format as JSON5 (comments and trailing commas allowed); we keep plain JSON, which any JSON5 parser accepts. OPENCLAW_STATE_DIR and OPENCLAW_CONFIG_PATH relocate the state directory and the config.

The default model is written as provider/model under agents.defaults.model.primary; the provider docs use this example:

{
  "agents": { "defaults": { "model": { "primary": "anthropic/claude-opus-4-6" } } }
}

OpenAI, Anthropic and Ollama each have a page under providers. An OpenAI-compatible gateway (avots.ai in our deployments) goes under models.providers, the custom provider map keyed by provider id in the configuration reference; copy the field names from there, not from an older tutorial. Later edits go through openclaw configure, openclaw config set <key> <value>, or the Control UI.

Step 4: run the gateway as a service

On Linux, openclaw gateway install (already run by onboard --install-daemon) creates a systemd user service. Two extra steps from the runbook matter on a headless VPS: without lingering, your user session ends at logout and the gateway stops with it, and without XDG_RUNTIME_DIR the user bus is not reachable from a plain SSH shell.

sudo loginctl enable-linger $(whoami)
export XDG_RUNTIME_DIR=/run/user/$(id -u)
systemctl --user enable --now openclaw-gateway.service
openclaw gateway status

Day to day: openclaw gateway status --deep, openclaw gateway restart, openclaw gateway stop, openclaw logs --follow, openclaw doctor --fix. A system-wide unit is also documented at /etc/systemd/system/openclaw-gateway.service with User=<username> in [Service]. An invalid config exits with code 78 and the unit will not restart on it; run openclaw doctor rather than restarting.

Step 5: loopback only, SSH tunnel for the UI

The gateway listens on port 18789 and binds to loopback by default (gateway.bind resolves to loopback outside containers). Keep it that way. OpenClaw is remote code execution by design, it already had a 1-click RCE via token theft (CVE-2026-25253) plus origin-validation flaws, and the gateway refuses a non-loopback bind without auth for a reason. Do not put the port behind a plain reverse proxy either; the only documented reverse-proxy setup is the trusted-proxy auth mode. The docs' preferred remote path is Tailscale; the fallback is an SSH tunnel from your laptop:

ssh -N -L 18789:127.0.0.1:18789 openclaw@your-server

Then open http://127.0.0.1:18789 locally. Auth is still required over the tunnel; the token was set at onboarding (gateway.auth.token, or the OPENCLAW_GATEWAY_TOKEN environment variable). The minimal gateway block is:

{
  "gateway": {
    "bind": "loopback",
    "port": 18789
  }
}

Run openclaw security audit after every config change; it flags auth gaps, open group policies, risky tool and sandbox combinations and config drift; --fix applies the safe remediations. The security page carries the exposure runbook, with pre-flight and rollback checklists, for the rare case where loopback is not enough.

Step 6: connect the first channel (Telegram)

  1. In Telegram open BotFather, send /newbot, follow the prompts and save the token.
  2. Hand it to OpenClaw: openclaw channels add --channel telegram --token <bot-token>. Alternatives are channels.telegram.botToken in the config or the TELEGRAM_BOT_TOKEN environment variable (default account only).
  3. Send any message to your bot. The default DM policy for Telegram is pairing, so the message is not processed; you get a short pairing code instead.
  4. Approve yourself on the server: openclaw pairing list telegram, then openclaw pairing approve telegram <CODE>. Codes expire after one hour.
  5. Confirm readiness: openclaw channels status --probe.

BotFather's /setprivacy and /setjoingroups control what the bot sees in groups; leave privacy mode on unless you need group replies.

Step 7: lock the agent to you

The security model is one trust boundary per gateway: a single operator or a mutually trusting team, never strangers. On Telegram, dmPolicy accepts pairing (default), allowlist, open or disabled, and allowFrom lists numeric Telegram user ids (telegram: and tg: prefixes are normalised). The access-control page shows the owner-only pattern:

{
  "channels": {
    "telegram": {
      "enabled": true,
      "dmPolicy": "pairing",
      "allowFrom": ["<YOUR_TELEGRAM_USER_ID>"],
      "groupPolicy": "allowlist"
    }
  }
}

Old configs with @username entries are migrated to numeric ids by openclaw doctor --fix. Tool permissions can be scoped per sender with toolsBySender, and tool execution can be moved into a container with agents.defaults.sandbox.mode set to non-main or all (off runs tools directly on the host). The docs are honest that this is not a perfect security boundary, but it materially limits filesystem and process access when the model does something dumb. Treat every inbound message as untrusted input.

Updating OpenClaw

The documented path is the built-in updater, which detects your install type (npm, pnpm, Bun or git), validates the candidate while the old gateway keeps serving, then activates and verifies it:

openclaw update
openclaw doctor
openclaw gateway restart
openclaw health

openclaw update --dry-run previews; --channel beta, --channel extended-stable and --channel dev switch channels. Extended-stable suits a server you do not want to touch monthly; v2026.6.35 (10 September 2026) is described as the final release of the June 2026 line, so check the docs for the line the channel tracks now. The manual fallback is npm install -g openclaw@latest --allow-scripts=openclaw plus the same three checks. Back up ~/.openclaw first; the docs warn that automatic config copies are not a full-state backup. On Docker, docker compose pull openclaw-gateway openclaw-cli then docker compose up -d openclaw-gateway; the gateway runs its startup-safe migrations on the volume.

Uninstalling

The order is service, state, package. With the CLI still present, openclaw uninstall --all --yes --non-interactive does all of it; the manual steps are:

openclaw gateway stop
openclaw gateway uninstall
rm -rf "${OPENCLAW_STATE_DIR:-$HOME/.openclaw}"
npm rm -g openclaw

If the systemd unit survives: systemctl --user disable --now openclaw-gateway.service, then remove ~/.config/systemd/user/openclaw-gateway.service and run systemctl --user daemon-reload. Revoke the Telegram token in BotFather and the provider key in its dashboard; deleting the server revokes neither.

What changed since early 2026

  • Versioning and channels. Releases are dated (year.month.n). v2026.8.1 was labelled "OpenClaw 2.0" with a rebuilt web experience and simpler onboarding; the updater offers stable, beta, extended-stable and dev channels.
  • Node floor raised. Node 24.16+ or 26.1+ is required, Node 26 recommended; use the installer or NodeSource, not the distro package.
  • Updater. openclaw update is the documented path; v2026.9.2 added update reports and recovery, v2026.9.3 validation in isolated candidate state.
  • Telegram allowlists. Numeric user ids only; @username entries are legacy and migrated by doctor.
  • Safer admin defaults shipped in v2026.6.11; openclaw security audit checks your instance against them.

If you would rather skip steps 1 to 5, our ready OpenClaw server from 9.35 EUR per month comes with Ubuntu 24.04 and the gateway preinstalled on loopback; you add the model key and the Telegram bot. For hosted model versus your own model, see AI agent or your own AI model, and for GPU-backed options the AI servers page.

Questions

Can I install OpenClaw as root to save time?

The runbook says not to, and here it matters: the exec tool runs shell commands with the gateway user's rights, so a root gateway hands the model root. Create a user and run the gateway there.

Do I need Docker if I use the npm path?

No. Sandboxing is off by default and the gateway runs without Docker. Install Docker Engine only if you turn the sandbox on, because Docker is its backend.

The gateway works from SSH but stops after I log out

That is the lingering problem. Run sudo loginctl enable-linger $(whoami) so the systemd user session survives logout, then check openclaw gateway status in a fresh shell with XDG_RUNTIME_DIR exported.

Can I open port 18789 with a token instead of a tunnel?

The gateway binds non-loopback only when auth is configured, but the docs still steer you to Tailscale or an SSH tunnel and keep an exposure runbook for anything else. Given the RCE history, treat public exposure as a last resort behind a firewall, not a convenience.

Want this running privately?
An AI assistant on your own server in the EU, with your data staying where you put it.
See what it costs

Ready to start?

Deploy in minutes or talk to an engineer about what fits your project.