Skip to main content
🦞

How to Run OpenClaw on a $5 VPS

11 minGuide

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:

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.

Cookie Preferences

We use essential cookies and analytics to operate and improve the site. Advertising cookies are loaded only after you consent. Privacy Policy