title: "How to Run OpenClaw on a $5 VPS" date: "2026-02-22" description: "Deploy OpenClaw on a budget $5/month VPS. This guide covers server setup, Docker installation, resource optimization, and keeping your instance running 24/7." category: "Guide" author: "OpenClaw Team" tags: ["vps", "deployment", "docker", "budget"] readTime: "11 min"
You do not need a powerful server to run OpenClaw. A $5/month virtual private server — the kind offered by DigitalOcean, Hetzner, Vultr, or Linode — is enough to run a full OpenClaw instance for personal use or small teams. The key is knowing how to configure it for low-memory environments and keep it stable over time.
This guide takes you from a freshly provisioned server to a production-ready OpenClaw deployment with Docker, nginx, HTTPS, and automatic restarts — all on 1 GB of RAM.
What You'll Set Up
By the end of this guide, you'll have:
- A hardened VPS running Ubuntu 24.04 LTS
- Docker and Docker Compose managing OpenClaw containers
- nginx as a reverse proxy with automatic HTTPS via Let's Encrypt
- Memory and CPU optimizations for 1 GB RAM servers
- A systemd service that restarts OpenClaw if it crashes
- Basic monitoring with health checks
Prerequisites
Before you begin, make sure you have:
- A VPS from any major provider (DigitalOcean, Hetzner, Vultr, or similar)
- A domain name pointed at the server's IP (an A record is enough)
- SSH access to the server as root or a user with sudo privileges
- An Anthropic API key (setup guide)
- Basic comfort with Linux command line
Step 1: Choose and Provision Your VPS
The cheapest tier at most providers gives you roughly:
| Provider | Plan | RAM | CPU | Storage | Price | |----------|------|-----|-----|---------|-------| | Hetzner | CX11 | 2 GB | 1 vCPU | 20 GB | $4.15/mo | | DigitalOcean | Basic | 1 GB | 1 vCPU | 25 GB | $6/mo | | Vultr | Cloud Compute | 1 GB | 1 vCPU | 25 GB | $5/mo | | Linode | Nanode | 1 GB | 1 vCPU | 25 GB | $5/mo |
Hetzner offers the best value if you're in Europe. For US-based deployments, Vultr and Linode have datacenters in multiple regions.
When provisioning, select Ubuntu 24.04 LTS as your OS. It has a long support window and excellent Docker compatibility.
After the server is created, point your domain to its IP:
A record: openclaw.yourdomain.com → 203.0.113.42
Step 2: Initial Server Hardening
Log in as root and create a non-root user immediately:
# Create a deploy user
adduser deploy
usermod -aG sudo deploy
# Copy SSH keys to the new user
rsync --archive --chown=deploy:deploy ~/.ssh /home/deploy
# Disable root SSH login
sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl reload sshd
Set up the firewall to allow only SSH, HTTP, and HTTPS:
ufw default deny incoming
ufw default allow outgoing
ufw allow ssh
ufw allow http
ufw allow https
ufw enable
Switch to the deploy user for all remaining steps:
ssh deploy@your-server-ip
For more detailed hardening steps, see the security hardening guide.
Step 3: Install Docker and Docker Compose
Install Docker using the official convenience script:
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# Apply group change without logging out
newgrp docker
# Verify Docker works
docker run --rm hello-world
Install Docker Compose v2 (it comes bundled with modern Docker installs, but verify):
docker compose version
# Should output: Docker Compose version v2.x.x
Step 4: Configure OpenClaw with Docker Compose
Create the project directory and set up the file structure:
mkdir -p ~/openclaw/{config,data,logs}
cd ~/openclaw
Create the Docker Compose file:
# ~/openclaw/docker-compose.yaml
version: "3.9"
services:
openclaw:
image: openclaw/openclaw:latest
container_name: openclaw
restart: unless-stopped
env_file: .env
volumes:
- ./config:/app/config:ro # Config files (read-only)
- ./data:/app/data # Persistent storage
- ./logs:/app/logs # Log files
ports:
- "127.0.0.1:3000:3000" # Only expose to localhost — nginx proxies it
mem_limit: 512m # Hard memory cap for 1 GB server
memswap_limit: 512m # Disable swap for the container
cpus: "0.8" # Leave some CPU headroom for nginx
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
logging:
driver: "json-file"
options:
max-size: "10m" # Prevent log files from filling the disk
max-file: "3"
Create the environment file with your secrets:
# ~/openclaw/.env
ANTHROPIC_API_KEY=sk-ant-api03-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
OPENCLAW_SECRET_KEY=$(openssl rand -hex 32)
OPENCLAW_BASE_URL=https://openclaw.yourdomain.com
OPENCLAW_ENV=production
NODE_ENV=production
Lock down the permissions on the env file so only the deploy user can read it:
chmod 600 ~/openclaw/.env
Create the OpenClaw config file:
# ~/openclaw/config/openclaw.yaml
server:
host: "0.0.0.0"
port: 3000
providers:
anthropic:
api_key: "${ANTHROPIC_API_KEY}"
rate_limits:
requests_per_minute: 30 # Conservative for personal use
tokens_per_minute: 20000
database:
type: sqlite # SQLite needs no separate container
path: "/app/data/openclaw.db"
logging:
level: info
output: "/app/logs/openclaw.log"
rotation: daily
max_files: 7 # Keep one week of logs
Step 5: Set Up nginx as a Reverse Proxy
Install nginx:
sudo apt install -y nginx
Create the OpenClaw site config:
# /etc/nginx/sites-available/openclaw
server {
listen 80;
server_name openclaw.yourdomain.com;
return 301 https://$host$request_uri; # Force HTTPS
}
server {
listen 443 ssl;
server_name openclaw.yourdomain.com;
# SSL certificates (Certbot fills these in)
ssl_certificate /etc/letsencrypt/live/openclaw.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/openclaw.yourdomain.com/privkey.pem;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
# Proxy settings
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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;
proxy_cache_bypass $http_upgrade;
# Timeouts — increase for long AI responses
proxy_read_timeout 120s;
proxy_connect_timeout 10s;
}
# Gzip compression for text responses
gzip on;
gzip_types text/plain application/json application/javascript text/css;
}
Enable the site and test the config:
sudo ln -s /etc/nginx/sites-available/openclaw /etc/nginx/sites-enabled/
sudo nginx -t # Must say "syntax is ok"
sudo systemctl reload nginx
Step 6: Issue SSL Certificates with Let's Encrypt
Install Certbot and get a free certificate:
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d openclaw.yourdomain.com
# Follow the prompts — Certbot auto-configures nginx for SSL
Certbot installs a systemd timer that auto-renews the certificate before expiry. Verify it's active:
sudo systemctl status certbot.timer
Step 7: Start OpenClaw and Enable Auto-Restart
Launch the containers:
cd ~/openclaw
docker compose up -d
docker compose logs -f # Watch startup logs
Check that the health endpoint responds:
curl -s http://localhost:3000/health
# {"status":"ok","version":"x.x.x","uptime":42}
And verify it's accessible over HTTPS:
curl -s https://openclaw.yourdomain.com/health
Docker's restart: unless-stopped policy already handles crashes. But if Docker itself fails or the server reboots, you need a systemd service to bring everything back up:
# Create a systemd service for OpenClaw
sudo tee /etc/systemd/system/openclaw.service > /dev/null <<'EOF'
[Unit]
Description=OpenClaw AI Agent Platform
Requires=docker.service
After=docker.service network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/home/deploy/openclaw
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
User=deploy
Group=deploy
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable openclaw
sudo systemctl start openclaw
Test the full reboot cycle:
sudo reboot
# After the server comes back up:
ssh deploy@your-server-ip
docker ps # OpenClaw should be running
Step 8: Optimize for Low-Memory Servers
A 1 GB server will struggle if you're not deliberate about memory. These optimizations keep OpenClaw stable under the 512 MB container limit:
Add a swap file. Even though swap is slow, it prevents the OOM killer from terminating your container during memory spikes:
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# Reduce kernel's preference for swap (higher = use RAM longer before swapping)
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Limit SQLite's cache size. SQLite aggressively caches by default. In low-memory environments, cap it:
# ~/openclaw/config/openclaw.yaml
database:
type: sqlite
path: "/app/data/openclaw.db"
pragmas:
cache_size: -8000 # 8 MB max cache (default is much higher)
journal_mode: WAL # WAL mode is safer and uses less memory
synchronous: NORMAL
Schedule resource-intensive tasks at night. If you run scheduled workflows, configure them to run during off-peak hours so they don't compete with interactive usage. See scheduling AI tasks with cron jobs for patterns.
Step 9: Set Up Basic Monitoring
A $5 server doesn't need a sophisticated monitoring stack, but you should know if OpenClaw goes down:
# Install a simple monitoring script
cat > ~/openclaw/healthcheck.sh << 'EOF'
#!/bin/bash
HEALTH=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/health)
if [ "$HEALTH" != "200" ]; then
echo "OpenClaw is DOWN (HTTP $HEALTH). Restarting..."
cd ~/openclaw && docker compose restart
# Optionally send an alert (replace with your webhook URL)
curl -s -X POST "$ALERT_WEBHOOK" \
-H 'Content-Type: application/json' \
-d '{"text":"OpenClaw was down and has been restarted."}'
fi
EOF
chmod +x ~/openclaw/healthcheck.sh
Schedule it with cron to run every 5 minutes:
crontab -e
# Add this line:
*/5 * * * * /home/deploy/openclaw/healthcheck.sh >> /home/deploy/openclaw/logs/healthcheck.log 2>&1
Watch disk and memory usage with a simple daily summary:
# Add to crontab for a daily resource report
0 8 * * * df -h / && free -h && docker stats --no-stream >> /home/deploy/openclaw/logs/resources.log 2>&1
Common Issues and Fixes
Container exits immediately after starting — Check the logs with docker compose logs openclaw. Usually this is a missing environment variable or a bad config file path. Confirm .env is present and config/openclaw.yaml is valid YAML.
nginx returns 502 Bad Gateway — OpenClaw hasn't fully started yet, or it crashed. Run docker ps to check if the container is running. If it exited, check docker compose logs --tail 50.
Out of memory errors — Increase the swap file size (sudo fallocate -l 2G /swapfile) and reduce the concurrent agent limit in your OpenClaw config. If problems persist, upgrade to a 2 GB plan — it's usually only $2-3 more per month.
SSL certificate fails to renew — Make sure port 80 is open in your firewall (ufw allow http) and nginx is running. Certbot's renewal uses the HTTP challenge by default.
Let's Encrypt rate limit hit — You can request a certificate at most 5 times per week for the same domain. If you're testing, use --staging flag with Certbot to avoid the rate limit.
Next Steps
With OpenClaw running on your VPS, explore what you can build:
- Build a multi-agent system to run complex AI workflows on your server
- Automate your email with AI agents for a real-world automation that runs 24/7
- Security hardening guide for hardening your production deployment beyond the basics
A $5 VPS with OpenClaw gives you a personal AI automation platform that runs continuously without relying on cloud AI services for compute. You bring the brains (via the Claude API), the server just keeps things running.