← Back to Free Tools

Install OpenClaw on a VPS

Complete guide. From a blank server to a running AI agent with web dashboard.

In this guide

Prerequisites 1. Get a VPS 2. Install Node.js 3. Install OpenClaw 4. Configure OpenClaw 5. Set up nginx + Cloudflare (HTTPS) 6. Start the Gateway 7. Pair the Web UI 8. Access via TUI (terminal) 9. Run as a background service 10. Connect Gmail, Calendar & Drive Tips & troubleshooting

Prerequisites

🖥️

A VPS

Any Linux server. Ubuntu 22/24 recommended. 2GB+ RAM.

🔑

SSH Access

Root or sudo access to your server.

🤖

AI API Key

OpenRouter, OpenAI, or Anthropic API key.

🌐

A Domain

With Cloudflare DNS (free). Needed for HTTPS / web UI pairing.

1. Get a VPS

If you don't have a server yet, grab one from Contabo ($6.99/mo for 4 CPU, 8GB RAM) or any provider. You need Ubuntu 22.04 or 24.04.

SSH into your server:

ssh root@YOUR_SERVER_IP

Update packages first:

apt update && apt upgrade -y

2. Install Node.js

OpenClaw requires Node.js 20+.

# Install Node.js 22 (LTS) curl -fsSL https://deb.nodesource.com/setup_22.x | bash - apt install -y nodejs git # Verify node --version # should show v22.x npm --version # should show 10.x

3. Install OpenClaw

npm install -g openclaw # Verify openclaw --version

4. Configure OpenClaw

OpenClaw has a guided setup. Run it and configure each section one at a time:

openclaw configure

You can only select one section per run. Run openclaw configure again for each section.

Round 1: Model (most important)

Select Model → choose your AI provider and paste your API key.

OpenRouter is recommended — cheapest option with access to all models. Get a key at openrouter.ai.

Round 2: Gateway

Select Gateway → set these options:

SettingChoose
Gateway port18789 (default)
Bind modeLAN (All interfaces)
AuthToken (default)
TailscaleOff
Token sourceGenerate/store plaintext token (default)

Round 3+ (optional): Workspace, Channels, Skills

Run openclaw configure again for each section you want to set up. Defaults are fine for most.

Enable shell command execution (critical)

By default, the agent may not be able to run shell commands. You need to enable tool execution so the agent can use gog, run scripts, and interact with the system.

Open the config file:

nano ~/.openclaw/openclaw.json

Find or add the "tools" section inside the top-level JSON object. Add this block (merge with existing config if needed):

"tools": { "profile": "full", "allow": ["*"], "sessions": { "visibility": "all" }, "exec": { "host": "gateway", "security": "full", "ask": "off" } }
This gives the agent full shell access. It can run any command on your VPS without asking for approval. Only enable this on a server you control, not on your personal machine.

Save the file (Ctrl+O, Enter, Ctrl+X). The gateway will pick up the changes on next restart.

Install useful tools on the VPS

The agent can use any CLI tool installed on the server. Install these common ones:

# GitHub CLI (for repos, PRs, issues) curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null apt update && apt install -y gh # Common utilities apt install -y curl wget jq htop unzip python3 python3-pip

Authenticate GitHub CLI (optional, if your agent needs repo access):

gh auth login

Install OpenClaw skills

Skills teach the agent how to use specific tools. Install them with clawhub:

# Google Workspace (Gmail, Calendar, Drive) npx clawhub@latest install gog # Email management (smart inbox triage, drafting, follow-ups) npx clawhub@latest install email-manager-ai # Market research (competitor analysis, trends, reports) npx clawhub@latest install market-research # Web scraping with Playwright (headless browser) npx clawhub@latest install playwright-scraper-skill # Browse all available skills npx clawhub@latest search

Playwright requires extra setup — it needs Chromium and system dependencies:

cd ~/.openclaw/workspace/skills/playwright-scraper-skill npm install npx playwright install chromium npx playwright install-deps chromium cd ~ # Create screenshots folder mkdir -p /root/.openclaw/workspace/screenshots # Set Playwright defaults for headless VPS echo 'SAVE_HTML=true' >> /etc/environment echo 'WAIT_TIME=5000' >> /etc/environment echo 'HEADLESS=true' >> /etc/environment echo 'SCREENSHOT_PATH=/root/.openclaw/workspace/screenshots' >> /etc/environment
Never set HEADLESS=false on a VPS. There is no display — the browser will crash. Keep it true.

Playwright environment variables:

VariableDefaultDescription
HEADLESStrueRun browser without display (must be true on VPS)
SAVE_HTMLfalseSave page HTML alongside screenshots
WAIT_TIME5000Milliseconds to wait for page to load
SCREENSHOT_PATH./screenshot.pngWhere to save screenshots
USER_AGENTdefaultCustom browser user agent string

After installing skills, restart the gateway: openclaw gateway --force

Install ClawFlows (automated workflows)

ClawFlows adds 100+ pre-built workflows to your agent — morning briefings, email summaries, calendar checks, and more.

curl -fsSL https://raw.githubusercontent.com/nikilster/clawflows/main/system/install.sh | bash

When asked to enable the essentials pack, say Y. It enables:

After install, open a new terminal tab or run:

export PATH="/root/.local/bin:$PATH"

Useful commands:

clawflows list # Browse all workflows clawflows enable <name> # Turn one on clawflows disable <name> # Turn one off clawflows run <name> # Run a workflow now clawflows dashboard # Browse in browser clawflows update # Pull latest workflows

Supported providers

ProviderEnv VariableCost
OpenRouterOPENROUTER_API_KEYPay per use, cheapest
OpenAIOPENAI_API_KEYPay per use
AnthropicANTHROPIC_API_KEYPay per use
Ollama (local)OLLAMA_BASE_URLFree (runs on your hardware)

5. Set up nginx + Cloudflare (HTTPS)

The web UI requires HTTPS for device pairing. Set this up before starting the gateway.

5a. Add DNS record in Cloudflare

In your Cloudflare dashboard, add an A record:

FieldValue
TypeA
Nameagent1 (or any subdomain)
ContentYOUR_VPS_IP
ProxyON (orange cloud)

5b. Cloudflare settings

In Cloudflare dashboard, configure these settings:

SettingLocationValue
SSL/TLS modeSSL/TLS → OverviewFull
WebSocketsNetworkON
Rocket LoaderSpeed → OptimizationOFF
Email ObfuscationScrape ShieldOFF
Auto Minify JSSpeed → OptimizationOFF
Rocket Loader, Email Obfuscation, and Auto Minify can inject scripts or headers that break the OpenClaw pairing flow. Make sure they are OFF.

5c. Install and configure nginx

apt install -y nginx nano /etc/nginx/sites-available/default

Replace the entire file with (change agent1.yourdomain.com to your subdomain):

server { listen 80; server_name agent1.yourdomain.com; location / { proxy_pass http://127.0.0.1:18789; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto https; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # Fix CSP: OpenClaw sets script-src 'self' which blocks # inline scripts when accessed through Cloudflare proxy. # This replaces it with a version that allows inline scripts. proxy_hide_header Content-Security-Policy; add_header Content-Security-Policy "default-src 'self'; base-uri 'none'; object-src 'none'; frame-ancestors 'none'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https:; font-src 'self' https://fonts.gstatic.com; connect-src 'self' ws: wss:;" always; } }

Save (Ctrl+O, Enter, Ctrl+X) and test:

nginx -t && systemctl restart nginx
The proxy_hide_header + add_header lines are critical. OpenClaw's default CSP blocks inline scripts when accessed through Cloudflare, which breaks the pairing UI. This replaces it with a version that allows inline scripts.

5d. Allow the domain in OpenClaw

openclaw config set gateway.controlUi.allowedOrigins '["https://agent1.yourdomain.com"]'

6. Start the Gateway

# Start the gateway openclaw gateway --force

You should see output like:

[gateway] listening on ws://0.0.0.0:18789 (PID 5676) [gateway] agent model: openrouter/auto
The gateway runs in the foreground. Open a second SSH session to run other commands.

7. Pair the Web UI

Pairing is a two-step process: first you submit the token in the browser, then you approve the device from the VPS command line.

7a. Get your token

In your second SSH session:

# Get your gateway token cat ~/.openclaw/openclaw.json | grep token

Copy the token value (the long hex string).

7b. Submit the token in the browser

Open https://agent1.yourdomain.com in your browser. You'll see the Gateway Dashboard with these fields:

Click Connect. It will say "pairing required" — this is expected.

7c. Approve the device from the VPS

Back in your SSH session, list pending pairing requests:

openclaw devices list

You'll see your browser listed under Pending with a Request ID. Approve it:

# Replace REQUEST_ID with the ID from the Pending list openclaw devices approve REQUEST_ID

7d. Reconnect in the browser

Go back to the browser and click Connect again. It should now connect successfully and show the agent chat interface.

Each new browser/device needs to be approved separately. If you open the web UI from a different computer, repeat steps 7b-7c.

Troubleshooting pairing

"origin not allowed" — Run the allowedOrigins command from Step 5d and restart: openclaw gateway --force

"control ui requires device identity" — You're on HTTP, not HTTPS. Make sure you're using https://.

CSP inline script error in console — Make sure your nginx config includes the proxy_hide_header and add_header lines from Step 5c.

No pending request in openclaw devices list — Make sure you clicked Connect in the browser first, then run the list command immediately.

Fallback: SSH tunnel — If Cloudflare pairing doesn't work, pair via localhost:

# On your local machine (not the VPS) ssh -N -L 18789:127.0.0.1:18789 root@YOUR_VPS_IP

Open http://localhost:18789, paste the token, click Connect, then approve via openclaw devices approve.

8. Access via TUI (terminal)

The TUI (Terminal User Interface) is the most reliable way to interact with your agent. No browser needed:

openclaw tui

This opens a chat interface directly in your terminal. It has the same capabilities as the web UI.

Useful TUI commands

CommandWhat it does
/helpShow all commands
/agentsList running agents
/sessionsList active sessions
/modelChange AI model
/thinkToggle thinking mode
/quitExit TUI

9. Run as a background service

Keep OpenClaw running even after you close SSH.

Option A: systemd (recommended)

# Find the correct openclaw path first which openclaw # Create service file nano /etc/systemd/system/openclaw.service

Paste this (update ExecStart path and API key):

[Unit] Description=OpenClaw AI Agent After=network.target [Service] Type=simple User=root WorkingDirectory=/root ExecStart=/usr/bin/openclaw gateway --force Restart=always RestartSec=10 Environment=OPENROUTER_API_KEY=your-key-here Environment=PYTHON_KEYRING_BACKEND=keyrings.alt.file.PlaintextKeyring Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/linuxbrew/.linuxbrew/bin [Install] WantedBy=multi-user.target
Important: Replace /usr/bin/openclaw with the output of which openclaw. It might be /usr/local/bin/openclaw or under ~/.nvm/.

Save, then enable and start:

systemctl daemon-reload systemctl enable openclaw systemctl start openclaw # Check status systemctl status openclaw # View logs journalctl -u openclaw -f

Option B: screen (quick and simple)

apt install -y screen screen -S openclaw openclaw gateway --force # Press Ctrl+A then D to detach # To reattach later: screen -r openclaw

10. Connect Gmail, Calendar & Drive

Give your agent access to Google Workspace (Gmail, Calendar, Drive, Contacts) using the gog CLI tool.

Important: Follow these steps in exact order. The #1 cause of problems is encrypted keyring tokens that OpenClaw can't decrypt. This guide uses plaintext token storage so the agent subprocess can access Gmail without prompts.

10a. Create brewuser (as root)

Homebrew can't run as root on Linux. Create a dedicated user:

useradd -m -s /bin/bash brewuser echo 'brewuser ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

10b. Install Homebrew (as brewuser)

Switch to brewuser:

su - brewuser

Now install Homebrew (this takes a few minutes):

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

After it finishes, add brew to your PATH. Run the commands that Homebrew prints at the end. Usually:

eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv bash)" echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv bash)"' >> ~/.bashrc
If the path /home/linuxbrew/ doesn't exist, try /home/brewuser/.linuxbrew/ instead. Use whatever Homebrew printed at the end of installation.

10c. Install gog (still as brewuser)

brew install must run as brewuser, not root. Homebrew refuses to run as root.
brew install steipete/tap/gogcli

Verify:

which gog gog --help

10d. Switch back to root

exit

Now add brew to root's PATH so gog is available as root:

eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv bash)" echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv bash)"' >> /root/.bashrc

Verify gog works as root:

which gog
If which gog returns nothing, the brew path is different. Try: eval "$(/home/brewuser/.linuxbrew/bin/brew shellenv bash)" and update the echo command to match.

10e. Install gog skill in OpenClaw (as root)

npx clawhub@latest install gog

10f. Create Google OAuth credentials (free)

You need OAuth credentials so gog can access Gmail/Calendar. This is 100% free — no billing required.

  1. Go to console.cloud.google.com — sign in with the Gmail account your agent will use
  2. Create a new project (any name, e.g. "My Agent")
  3. Go to APIs & Services → Library — search for and enable Gmail API and Google Calendar API
  4. Go to APIs & Services → OAuth consent screen → choose External → fill in app name and your email → Save
  5. Under Test users → click + Add Users → add the Gmail address your agent will use
  6. Go to APIs & Services → CredentialsCreate Credentials → OAuth client ID
  7. Application type: Desktop app → name it anything → Create
  8. Copy the Client ID and Client Secret

10g. Create credentials file on VPS

Replace YOUR_CLIENT_ID and YOUR_CLIENT_SECRET with the values from the previous step.

Use the full format below. A minimal file with just client_id/client_secret will fail. You need the "installed" wrapper with auth_uri, token_uri, and redirect_uris.
mkdir -p /root/.config/gogcli # Write the full credentials file printf '{\n "installed": {\n "client_id": "YOUR_CLIENT_ID",\n "client_secret": "YOUR_CLIENT_SECRET",\n "auth_uri": "https://accounts.google.com/o/oauth2/auth",\n "token_uri": "https://oauth2.googleapis.com/token",\n "redirect_uris": ["http://localhost"]\n }\n}\n' > /root/.config/gogcli/credentials.json # Verify it looks right cat /root/.config/gogcli/credentials.json

The output should look like this:

{ "installed": { "client_id": "123456789-xxxxx.apps.googleusercontent.com", "client_secret": "GOCSPX-xxxxxxxxxxxxx", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "redirect_uris": ["http://localhost"] } }

10h. Set up plaintext keyring BEFORE authenticating

Do this BEFORE running gog auth login. If you authenticate first, the tokens get encrypted and OpenClaw can't decrypt them (you'll get aes.KeyUnwrap(): integrity check failed).
# Tell gog to store tokens in plaintext (no encryption) export PYTHON_KEYRING_BACKEND=keyrings.alt.file.PlaintextKeyring # Make it permanent for your shell echo 'export PYTHON_KEYRING_BACKEND=keyrings.alt.file.PlaintextKeyring' >> /root/.bashrc # Make it available to ALL processes (critical for OpenClaw) echo 'PYTHON_KEYRING_BACKEND=keyrings.alt.file.PlaintextKeyring' >> /etc/environment
Why plaintext? OpenClaw runs gog as a background subprocess with no TTY. Encrypted keyring requires a password prompt the subprocess can't answer. Plaintext = no prompt = agent works autonomously.

10i. Register credentials with gog

gog auth credentials /root/.config/gogcli/credentials.json

10j. Authenticate with Google

gog auth login

This prints a URL like http://127.0.0.1:XXXXX. Since the VPS has no browser, you need an SSH tunnel.

On your local computer (not the VPS), open a new terminal:

# Replace XXXXX with the port from gog auth login ssh -N -L XXXXX:127.0.0.1:XXXXX root@YOUR_VPS_IP

Now open http://127.0.0.1:XXXXX in your local browser. Sign in with the Gmail account, click Select all permissions, then Continue.

The port changes every time you run gog auth login. Have your SSH command ready — just change the port number. Create the tunnel quickly before the auth times out.
If you see "Access blocked: app has not completed Google verification" — go to Google Cloud Console → OAuth consent screen → Test users → add your Gmail address.

If gog asks for a keyring password, set one and remember it. You'll need it in the next step.

10k. Set environment variables for OpenClaw

OpenClaw runs gog as a subprocess. It needs these env vars so gog knows which account to use and can unlock the keyring without prompting.

# Set your Gmail account (replace with the email you authorized) export [email protected] echo 'export [email protected]' >> /root/.bashrc echo '[email protected]' >> /etc/environment # Set your keyring password (replace with the password you set during gog auth login) export GOG_KEYRING_PASSWORD=your-keyring-password echo 'export GOG_KEYRING_PASSWORD=your-keyring-password' >> /root/.bashrc echo 'GOG_KEYRING_PASSWORD=your-keyring-password' >> /etc/environment
Replace [email protected] with the Gmail you authorized, and your-keyring-password with the passphrase you set during gog auth login. These are secrets — don't share them.
Why /etc/environment? When OpenClaw runs gog as a subprocess, it doesn't inherit your shell's env vars. /etc/environment is loaded by all processes on the system, so the agent can use gog without prompts.

10l. Set timezone

# Set to Eastern time (change to your timezone) timedatectl set-timezone America/New_York # Verify date

Common timezones: America/New_York, America/Chicago, America/Denver, America/Los_Angeles, Europe/London, Asia/Tokyo

10m. Verify gog works

# Search inbox gog gmail search "in:inbox" --max 3 # List calendar events gog calendar list # Send a test email to yourself gog gmail send --to [email protected] --subject "Test" --body "Digital worker is connected!"
If all three commands work without any password prompts, you're good. The agent will be able to use Gmail too.

10n. Restart OpenClaw and test

# Restart the gateway openclaw gateway --force

In the TUI or web UI, tell your agent:

# Try these prompts: Search my Gmail inbox for the latest 5 emails Send an email to [email protected] about our new product launch What's on my calendar this week?

The agent uses gog under the hood. If it works in your terminal, it works for the agent.

Tips & Troubleshooting

"origin not allowed" in browser

openclaw config set gateway.controlUi.allowedOrigins '["https://agent1.yourdomain.com"]' openclaw gateway --force

Web UI shows "assets not found"

Use the TUI instead — it has the same capabilities: openclaw tui

"unknown command 'start'"

The correct command is gateway, not start:

openclaw gateway --force

Port already in use

# --force kills anything on the port first openclaw gateway --force

"aes.KeyUnwrap(): integrity check failed"

Tokens were saved with encryption. Wipe and re-auth with plaintext:

# Nuclear reset rm -rf /root/.config/gogcli/keyring rm -rf /root/.config/gogcli/tokens rm -rf /root/.config/gogcli/token.json rm -rf /root/.local/share/keyrings # Set plaintext keyring export PYTHON_KEYRING_BACKEND=keyrings.alt.file.PlaintextKeyring # Re-register and re-auth gog auth credentials /root/.config/gogcli/credentials.json gog auth login

"OAuth credentials not configured"

gog auth credentials /root/.config/gogcli/credentials.json

"OAuth client not found" or "invalid_client"

Check credentials.json has the full "installed" format (see Step 10e). Watch out for extra spaces or line breaks in the client_secret.

Agent can use gog but you can't (or vice versa)

Make sure PYTHON_KEYRING_BACKEND=keyrings.alt.file.PlaintextKeyring is in /etc/environment (for the agent) AND in your .bashrc (for your shell).

Monthly costs

ItemCost
Contabo VPS (4 CPU, 8GB RAM)$6.99/mo
OpenRouter API credits$5-50/mo (usage-based)
OpenClawFree (open source)
Google Workspace APIs (Gmail, Calendar)Free
Cloudflare (SSL + CDN)Free
Node.js, nginx, Homebrew, gogFree
Total~$12-57/mo