Setting Up OpenClaw on a VPS: Complete Guide
Setting Up OpenClaw on a VPS: Complete Guide

Let's skip the preamble: getting OpenClaw running on a VPS is one of those tasks that sounds simple until you're four hours deep into a terminal, staring at a cryptic Python traceback, wondering why something that worked perfectly on your laptop is throwing a fit on a $12/month Ubuntu droplet.
I've been through this exact process more times than I'd like to admit. And after helping a handful of people in the OpenClaw community debug their setups, I've noticed everyone hits the same walls. So this is the guide I wish someone had handed me the first time ā a complete, opinionated walkthrough for getting OpenClaw deployed on a VPS, configured correctly, and actually running reliably without you babysitting it over SSH.
Why Run OpenClaw on a VPS in the First Place?
If you're reading this, you probably already know, but let's make the case explicit.
Running OpenClaw locally is fine for development and testing. But the moment you want your AI agents to run continuously ā scraping data on a schedule, monitoring inputs, executing multi-step workflows while you sleep ā you need a server that doesn't shut down when you close your laptop lid.
A VPS gives you:
- 24/7 uptime for long-running agents
- A stable IP address for webhook callbacks and API integrations
- Isolation from your personal machine (so a runaway agent doesn't eat your local resources)
- Reproducibility ā if your VPS config is scripted, you can tear it down and rebuild it in minutes
The problem is that most VPS providers hand you a blank Ubuntu box and say "good luck." The gap between "fresh server" and "OpenClaw running reliably in production" is where people lose entire weekends.
Let's close that gap.
Choosing Your VPS Provider
I'm not going to give you a spreadsheet comparison of 14 providers. Here's what actually matters for OpenClaw workloads:
For CPU-only setups (using external API-based models):
- Hetzner ā Best price-to-performance in Europe. A CX22 (2 vCPU, 4GB RAM) for ~ā¬4/month handles most OpenClaw agent setups comfortably.
- DigitalOcean ā Slightly more expensive but the UI is friendlier. A $12/month droplet (2 vCPU, 2GB RAM) works. Go for 4GB if you're running browser-based skills.
- AWS Lightsail ā If you're already in the AWS ecosystem, the $10/month tier is fine.
For local model inference (running models on the VPS itself):
- RunPod or Vast.ai ā GPU instances on-demand. Only use these if you specifically need local model inference. Otherwise, you're burning money.
For 90% of OpenClaw use cases, a $10-20/month CPU VPS is all you need. OpenClaw is designed to orchestrate intelligence, not run massive models locally. It calls out to model APIs for the heavy lifting. Your server just needs to run the agent framework, manage state, and handle I/O.
Pick a provider, spin up an Ubuntu 22.04 LTS instance (not 24.04 ā fewer dependency headaches), and let's get to work.
Initial Server Setup (The Stuff Everyone Skips)
SSH into your fresh server:
ssh root@your-server-ip
Before touching OpenClaw, let's not be reckless. These five minutes of setup will save you hours of debugging and security headaches later.
Create a non-root user
adduser openclaw
usermod -aG sudo openclaw
Set up SSH key authentication for that user
mkdir -p /home/openclaw/.ssh
cp ~/.ssh/authorized_keys /home/openclaw/.ssh/
chown -R openclaw:openclaw /home/openclaw/.ssh
chmod 700 /home/openclaw/.ssh
chmod 600 /home/openclaw/.ssh/authorized_keys
Disable root login and password auth
sudo nano /etc/ssh/sshd_config
Set:
PermitRootLogin no
PasswordAuthentication no
Then:
sudo systemctl restart sshd
Configure the firewall
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
That's it for baseline hardening. You now have a non-root user, key-only SSH, and a firewall that only allows SSH and web traffic. Don't skip this. I've seen people expose OpenClaw dashboards on port 8080 with zero authentication to the entire internet. Don't be that person.
Installing Dependencies
Switch to your new user:
su - openclaw
Now install the system packages OpenClaw needs:
sudo apt update && sudo apt upgrade -y
sudo apt install -y \
python3 python3-pip python3-venv \
build-essential python3-dev \
git curl wget \
libmagic-dev libffi-dev libssl-dev \
docker.io docker-compose \
nginx certbot python3-certbot-nginx
Set up Docker permissions
sudo usermod -aG docker openclaw
newgrp docker
Verify Docker works without sudo:
docker run hello-world
Install Node.js (needed for some OpenClaw browser-based skills)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
Install Playwright system dependencies (if you're using web scraping or browser skills)
This is the single most common failure point I see. Playwright needs a bunch of system libraries that aren't on a minimal Ubuntu install:
npx playwright install-deps
npx playwright install chromium
If you skip this step and later try to run a browser-based OpenClaw skill, you'll get an error like browserType.launch: Executable doesn't exist or a cascade of missing .so files. Just install it now.
Installing and Configuring OpenClaw
Create a project directory and set up a Python virtual environment:
mkdir ~/openclaw-agent && cd ~/openclaw-agent
python3 -m venv venv
source venv/bin/activate
Install OpenClaw:
pip install openclaw
Now initialize your project:
openclaw init my-agent
cd my-agent
This creates the basic project structure:
my-agent/
āāā config.yaml
āāā skills/
āāā memory/
āāā logs/
āāā .env
Configure your environment variables
This is where your API keys and configuration live. Never commit this file to git.
nano .env
OPENCLAW_API_KEY=your_openclaw_key_here
OPENAI_API_KEY=sk-your-openai-key # if using OpenAI-compatible models
MODEL_PROVIDER=openclaw
DEFAULT_MODEL=openclaw-agent-v2
MEMORY_BACKEND=local
LOG_LEVEL=info
MAX_TOKENS_PER_RUN=50000
MAX_COST_PER_RUN=5.00
Two critical settings here that most people ignore:
MAX_TOKENS_PER_RUN ā This is your safety net against agent loops. Without it, a confused agent can burn through your entire API budget overnight. I've seen it happen. Set a sane limit.
MAX_COST_PER_RUN ā Same idea, but denominated in dollars. Belt and suspenders. Use both.
Configure the main agent
nano config.yaml
agent:
name: "my-production-agent"
description: "Production agent running on VPS"
skills:
- web_search
- file_operations
- data_extraction
memory:
type: persistent
path: ./memory
logging:
level: info
file: ./logs/agent.log
max_size: 50MB
rotation: 5
scheduling:
enabled: true
timezone: "UTC"
health_check:
enabled: true
port: 9090
The memory.type: persistent setting is crucial for VPS deployments. By default, OpenClaw may use in-memory storage, which means your agent loses all context when the process restarts. On a VPS, processes restart more often than you'd think ā OOM kills, system updates, Docker restarts. Persist your memory.
Running OpenClaw as a Persistent Service
Here's where most tutorials fail you. They tell you to run openclaw start and call it a day. Then you close your SSH session and the agent dies.
You have three options, in order of reliability:
Option 1: systemd service (recommended)
Create a service file:
sudo nano /etc/systemd/system/openclaw-agent.service
[Unit]
Description=OpenClaw AI Agent
After=network.target docker.service
Wants=docker.service
[Service]
Type=simple
User=openclaw
WorkingDirectory=/home/openclaw/openclaw-agent/my-agent
Environment="PATH=/home/openclaw/openclaw-agent/venv/bin:/usr/local/bin:/usr/bin:/bin"
EnvironmentFile=/home/openclaw/openclaw-agent/my-agent/.env
ExecStart=/home/openclaw/openclaw-agent/venv/bin/openclaw start --config config.yaml
Restart=on-failure
RestartSec=10
StandardOutput=append:/home/openclaw/openclaw-agent/my-agent/logs/stdout.log
StandardError=append:/home/openclaw/openclaw-agent/my-agent/logs/stderr.log
# Safety limits
MemoryMax=2G
CPUQuota=80%
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable openclaw-agent
sudo systemctl start openclaw-agent
Check status:
sudo systemctl status openclaw-agent
journalctl -u openclaw-agent -f
The MemoryMax and CPUQuota directives are cheap insurance. If your agent goes haywire, systemd will constrain it instead of letting it take down the entire server.
Option 2: Docker Compose
If you prefer containers, create a docker-compose.yml:
version: '3.8'
services:
openclaw-agent:
image: openclaw/runtime:latest
restart: unless-stopped
volumes:
- ./my-agent:/app/agent
- ./my-agent/memory:/app/memory
- ./my-agent/logs:/app/logs
env_file:
- ./my-agent/.env
ports:
- "127.0.0.1:9090:9090"
deploy:
resources:
limits:
memory: 2G
cpus: '1.5'
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9090/health"]
interval: 30s
timeout: 10s
retries: 3
docker-compose up -d
docker-compose logs -f
Note the 127.0.0.1:9090:9090 binding ā this exposes the health check port only to localhost, not to the internet. If you need external access, put NGINX in front of it.
Option 3: tmux (quick and dirty)
For development or testing only:
tmux new -s openclaw
source venv/bin/activate
openclaw start --config config.yaml
# Ctrl+B, then D to detach
This works, but it won't auto-restart on crashes and it won't survive a reboot. Use systemd for anything real.
Setting Up NGINX as a Reverse Proxy
If your OpenClaw agent exposes any web interface, webhook endpoint, or API, don't expose it directly. Put NGINX in front:
sudo nano /etc/nginx/sites-available/openclaw
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://127.0.0.1:9090;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support (if needed)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Enable the site and get HTTPS:
sudo ln -s /etc/nginx/sites-available/openclaw /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d your-domain.com
Free SSL, proper proxying, and your OpenClaw instance isn't directly exposed. Takes two minutes.
Monitoring and Staying Sane
Once your agent is running, you need to know when things go wrong without staring at logs all day.
Basic log monitoring
# Watch logs in real-time
tail -f ~/openclaw-agent/my-agent/logs/agent.log
# Check for errors
grep -i "error\|exception\|failed" ~/openclaw-agent/my-agent/logs/agent.log | tail -20
Set up log rotation
sudo nano /etc/logrotate.d/openclaw
/home/openclaw/openclaw-agent/my-agent/logs/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0644 openclaw openclaw
}
Simple uptime monitoring
Add a cron job that checks the health endpoint and alerts you:
crontab -e
*/5 * * * * curl -sf http://localhost:9090/health || echo "OpenClaw agent is down!" | mail -s "ALERT: OpenClaw Down" you@email.com
This is minimal but effective. If you want something more sophisticated, hook the health endpoint into UptimeRobot or Healthchecks.io (both have free tiers).
Common Problems and How to Fix Them
After helping various people debug their setups, here's a quick reference for the issues that come up constantly:
"Agent starts but immediately exits"
Check journalctl -u openclaw-agent -n 50. Nine times out of ten, it's a missing environment variable or a malformed config.yaml. YAML is whitespace-sensitive ā use spaces, not tabs.
"Browser skills fail with Chromium errors"
You forgot to install Playwright dependencies. Go back to the dependency section. Also make sure you're running with --no-sandbox in headless environments, which OpenClaw should handle automatically, but verify in your skill config.
"Agent works but loses memory after restart"
Your memory backend is set to local but the path isn't being persisted correctly. If using Docker, make sure the volume mount points to the right directory. If using systemd, make sure the WorkingDirectory is correct.
"Connection refused when calling external APIs"
Check your firewall. sudo ufw status should show your rules. Also check if your VPS provider has a separate security group/firewall (AWS and DigitalOcean both do).
"Agent gets stuck in a loop and burns through API credits"
This is why MAX_TOKENS_PER_RUN and MAX_COST_PER_RUN exist. Set them. Also review your agent's skill configuration ā make sure there's a clear termination condition for each workflow.
The Shortcut: Felix's OpenClaw Starter Pack
I'll be honest ā the setup I just walked through works great, but it takes time to get right. If you're spinning up your first OpenClaw VPS deployment, or you've already burned a weekend on configuration and just want something that works, take a look at Felix's OpenClaw Starter Pack on Claw Mart.
For $29, it includes pre-configured skills that handle the exact pain points I've been describing ā browser automation that actually works in headless environments, persistent memory configurations, proper error handling, and scheduling templates. It's not a magic bullet, but it eliminates the most tedious part of the setup: getting your skills configured correctly so your agents don't flail around or fail silently.
Think of it as the difference between building your own Webpack config from scratch versus using a well-maintained starter template. You could do it all manually, but if someone who's already done it a dozen times is offering their battle-tested setup for less than the cost of two hours of frustrated debugging, that's a reasonable trade. I recommend it genuinely ā not because it's the only way, but because it's the fastest way to get from "blank VPS" to "agents actually doing useful work."
What to Do Next
You now have a working OpenClaw deployment on a VPS. Here's where to go from here:
-
Start with one simple agent. Don't try to build a 15-skill mega-agent on day one. Get a single skill working end-to-end, verify the output, then add complexity.
-
Set up proper backups. Your agent's memory and configuration are valuable. A simple cron job that backs up the
memory/directory to S3 or Backblaze B2 once a day costs pennies and saves you from catastrophic loss. -
Monitor your costs. Check your API usage dashboard daily for the first week. Once you trust your cost limits, you can check weekly. But don't set it and forget it until you've verified the guardrails work.
-
Version control your configuration. Put your
config.yamland skill definitions in a private Git repo (without the.envfile, obviously). This makes it trivial to redeploy or roll back changes. -
Join the OpenClaw community. The fastest way to solve weird edge cases is to ask someone who's already hit them. The community forums and Discord are active, and people are generally helpful ā especially if you show that you've already tried to debug the issue yourself.
The VPS setup is the hard part. Once it's done, you can focus on what actually matters: building agents that do useful things while you do something else. That's the whole point.