Skip to main content

How to Self-Host OpenClaw on a VPS: Complete Guide (2026)

· 8 min read
Yassine El Haddad
Software Developer & Automation Specialist

I build production AI agents, web scrapers, and automation pipelines. Most of what I publish here comes from the actual problems they run into: proxies that get banned, anti-bot stacks that fingerprint your client, RAG that drifts when the underlying data moves. Stack: Python, TypeScript, Go, FastAPI, LangChain, Crawlee, Playwright, deployed on AWS, GCP, and Cloudflare.

This guide takes you from a blank server to a fully running OpenClaw instance — accessible over HTTPS, connected to Telegram, with persistent storage and daily backups. Expect about 20 minutes start to finish.

What You Need Before Starting

  • A LiquidWeb VPS — minimum 4 GB RAM (the 4 GB plan is ~$8.50/mo with current promo)
  • A domain name with DNS control (optional but strongly recommended for HTTPS)
  • An API key for your chosen LLM backend: Anthropic, OpenAI, or similar
  • Basic Linux comfort (copy-paste these commands, you do not need to memorize them)

Step 1: Provision the LiquidWeb VPS

Go to LiquidWeb VPS hosting. Click Build now and configure:

  • OS: Ubuntu 22.04 LTS
  • RAM: 4 GB minimum (8 GB if you plan multiple users or heavy file operations)
  • Storage: 40 GB SSD (default)

Add your payment details. Provisioning takes 2–10 minutes. You receive an email with the server IP, root user, and temporary password.

Step 2: Initial Server Setup

SSH in as root:

ssh root@YOUR_SERVER_IP

Create a user for running OpenClaw (running as root is bad practice):

adduser ocuser
usermod -aG sudo ocuser

Copy your local SSH key to the server (run from your local machine):

ssh-copy-id ocuser@YOUR_SERVER_IP

Harden SSH — disable password login:

sudo sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo systemctl restart sshd

Update the system:

sudo apt-get update && sudo apt-get upgrade -y && sudo apt-get autoremove -y

Step 3: Install Docker Engine

curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker ocuser
newgrp docker
docker --version # Confirm 27.x or higher

Step 4: Pull the OpenClaw Image

docker pull ghcr.io/openclaw/openclaw:2026.3.13-1

Create the config directory (this persists all OpenClaw state):

mkdir -p ~/.openclaw/workspace
chmod 700 ~/.openclaw

Step 5: Write Your OpenClaw Config

Create ~/.openclaw/config.yaml. Pick your LLM backend:

Claude (recommended — strong quality, easy setup):

llm:
provider: anthropic
api_key: "${ANTHROPIC_API_KEY}"
model: claude-sonnet-4-6

agent:
max_steps: 50
timeout_seconds: 300
browser:
enabled: true
headless: true

server:
port: 18789
host: 0.0.0.0

logging:
level: info
format: json

OpenAI:

llm:
provider: openai
api_key: "${OPENAI_API_KEY}"
model: gpt-4o

agent:
max_steps: 50
timeout_seconds: 300

server:
port: 18789
host: 0.0.0.0

Local Ollama (requires GPU — see the GPU guide):

llm:
provider: ollama
base_url: http://host.docker.internal:11434
model: llama3.3:70b

server:
port: 18789
host: 0.0.0.0

Step 6: Docker Compose Setup

Create a directory for the Compose project:

mkdir ~/openclaw && cd ~/openclaw

Create docker-compose.yml:

services:
openclaw:
image: ghcr.io/openclaw/openclaw:2026.3.13-1
restart: unless-stopped
ports:
- "127.0.0.1:18789:18789"
volumes:
- /home/ocuser/.openclaw:/root/.openclaw
environment:
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
mem_limit: 2g
mem_reservation: 512m
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:18789/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 20s

Create the .env file (never commit this to version control):

cat << 'EOF' > .env
ANTHROPIC_API_KEY=sk-ant-your-key-here
EOF
chmod 600 .env

Start it:

docker compose up -d

Check that it is running:

docker compose ps
docker compose logs --tail=30

You should see: OpenClaw gateway listening on :18789 within about 15 seconds.

Test it locally (on the server):

curl -s http://localhost:18789/health
# Should return: {"status":"ok"}

Step 7: HTTPS with Caddy

Caddy is the simplest way to get TLS. It handles certificate issuance and renewal automatically.

Point your domain's A record to your server IP first. DNS propagation takes a few minutes.

Install Caddy:

sudo apt-get install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | \
sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | \
sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt-get update && sudo apt-get install -y caddy

Write /etc/caddy/Caddyfile:

openclaw.yourdomain.com {
reverse_proxy localhost:18789

# Optional: basic auth for extra security
# basicauth {
# your_username $2a$14$hash_from_caddy_hash-password
# }
}

Open firewall ports and reload Caddy:

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo systemctl reload caddy

Visit https://openclaw.yourdomain.com — you should see the OpenClaw dashboard. The TLS certificate is live.

Step 8: Connect Telegram

Telegram is the quickest platform to connect (no app configuration on their end, just a bot token).

  1. Open Telegram and message @BotFather
  2. Send: /newbot
  3. Choose a name (displayed to users) and username (must end in bot)
  4. Copy the token: 8346812749:AAH...
  5. In the OpenClaw dashboard → IntegrationsTelegram → paste the token
  6. Click Save
  7. Message your new bot in Telegram

Within a few seconds, OpenClaw should respond. Ask it something: "What is today's date and what is the weather like in London?"

Step 9: Persistent Storage and Backups

OpenClaw stores everything in ~/.openclaw/. The Docker bind mount you set up in Compose ensures data persists across container restarts.

Set up daily off-server backups:

# Install rclone
sudo apt-get install -y rclone
rclone config # Set up your preferred storage backend (S3, Backblaze B2, etc.)

# Create backup script
cat << 'EOF' > ~/backup-openclaw.sh
#!/bin/bash
set -e
TIMESTAMP=$(date +%Y%m%d-%H%M)
BACKUP_FILE="/tmp/openclaw-${TIMESTAMP}.tar.gz"
tar -czf "$BACKUP_FILE" ~/.openclaw/
rclone copy "$BACKUP_FILE" remote:openclaw-backups/
rm "$BACKUP_FILE"
echo "Backup complete: $TIMESTAMP"
EOF
chmod +x ~/backup-openclaw.sh

# Test it once
~/backup-openclaw.sh

# Schedule daily at 2:30 AM
(crontab -l 2>/dev/null; echo "30 2 * * * /home/ocuser/backup-openclaw.sh >> /home/ocuser/backup.log 2>&1") | crontab -

Step 10: Install Your First ClawHub Skill

ClawHub skills extend what OpenClaw can do. Install the web search skill:

# From the OpenClaw dashboard, or via CLI:
openclaw skills install @clawhub/web-search

After installation, you can ask OpenClaw to "search for the latest news on NemoClaw" and it will pull live results — not just rely on training data.

Browse the full catalog at clawhub.dev.

Keeping OpenClaw Updated

OpenClaw releases frequently. To update:

cd ~/openclaw
# Edit docker-compose.yml image tag to the new version
# Then:
docker compose pull
docker compose up -d

Check the releases page first — sometimes configs need updating between versions.

Apify Affiliate Banner 728x90Apify Affiliate Banner 728x90Apify Affiliate Banner 300x50Apify Affiliate Banner 300x50
Upgrade path

Start with this VPS setup. When you find yourself hitting API cost limits or wanting a model that does not phone home, follow the GPU inference guide to add an LiquidWeb L4 GPU server. The OpenClaw config change is a one-liner.

Frequently Asked Questions

2 vCPU and 2 GB RAM is the bare minimum. 4 GB RAM is recommended for comfortable operation — build processes OOM-kill on 2 GB servers. The LiquidWeb 4 GB VPS at ~$8.50/mo handles this well.

Technically yes (1 GB RAM), but only with a swap file and no browser automation. The gateway itself needs ~512 MB; build processes need ~2 GB. For reliable use, start with 4 GB.

Claude Sonnet 4.6 gives the best results for most task types and is the recommended starting point. GPT-4o is a strong alternative. For full data sovereignty with no per-token costs, use Ollama on a GPU server.

Add each one in the OpenClaw dashboard under Integrations. You can run all 20+ platforms simultaneously — the same OpenClaw instance handles all of them. Each platform uses its own credentials and bot token.

Not without authentication. The Caddy setup in this guide exposes it via HTTPS, but anyone with the URL can access the dashboard. Add basicauth in the Caddyfile or restrict access to your IP only: client_ip YOUR_IP in the Caddy handle block.

Common mistakes and fixes

Container starts but dashboard is unreachable at port 18789.

Check the port binding: docker compose ps should show 0.0.0.0:18789->18789 or 127.0.0.1:18789->18789. If it shows only the internal IP, the port mapping is missing. Verify your docker-compose.yml ports section. Use an SSH tunnel if accessing from a remote machine: ssh -L 18789:localhost:18789 user@server.

Docker build fails with OOM error on 2 GB server.

OpenClaw's build needs at least 2 GB free RAM. Add a swap file: sudo fallocate -l 2G /swapfile && sudo chmod 600 /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile. Or upgrade to the 4 GB VPS plan.

Telegram bot does not respond after setup.

The bot must be started — send /start to it in Telegram. Also verify the webhook URL in the OpenClaw dashboard shows your domain, not localhost. Check logs: docker compose logs openclaw | grep telegram.