Skip to main content

Self-Host OpenClaw on Liquid Web VPS

This guide takes you from a new Liquid Web account to a running OpenClaw instance with HTTPS, persistent storage, and automatic restart. Budget about 20 minutes. New to OpenClaw? See What Is OpenClaw? for the feature set and system requirements before you provision anything.

Handling sensitive data or team workloads?

Base OpenClaw has no network egress controls or audit logging. If your deployment handles internal business data, PHI, or is used by multiple people, add NemoClaw after completing this guide. It layers process-level sandboxing on top of this setup without requiring any changes to your OpenClaw config.

Step 1: Provision a Liquid Web VPS​

Go to Liquid Web VPS hosting and build a new server. Promo prices below reflect the current "50% off for 2 months" offer for new accounts; list prices apply after that. Checked live against liquidweb.com/vps-hosting on 2026-09-09 — promos change without notice, so re-check before you buy.

Use CasePlanRAMPromo / List
Cloud API backend (Claude, OpenAI)4 GB2 vCPU / 80 GB SSD$8.50 / $17/mo
Multiple users, file operations8 GB4 vCPU / 240 GB SSD$22.50 / $45/mo
Small-scale local inference via CPU / larger state16 GB6 vCPU / 440 GB SSD$45 / $90/mo

Pick Ubuntu 22.04 LTS. Provisioning typically takes a few minutes and you'll get an email with the server IP and root credentials. Note: on-VPS Ollama without a GPU is viable only for very small models (≤3B) and low concurrency. Serious local inference needs a GPU bare metal server (see the GPU guide).

Liquid Web vs. cheaper alternatives

Liquid Web costs more than Hetzner or Vultr but includes 24/7 managed support and a BAA option, which is useful if you lack dedicated ops staff or need HIPAA. For personal projects with no compliance needs, Hetzner at ~$4/mo is a reasonable alternative.

Step 2: Initial Server Setup​

SSH as root and run the following setup sequence:

ssh root@YOUR_SERVER_IP

Create a non-root user:

adduser ocuser
usermod -aG sudo ocuser

Copy your SSH key from your local machine:

# Run this from your local machine
ssh-copy-id ocuser@YOUR_SERVER_IP

Disable password authentication to harden SSH:

# On the server
sudo nano /etc/ssh/sshd_config
# Set: PasswordAuthentication no
sudo systemctl restart sshd

Update packages:

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

Step 3: Install Docker Engine​

curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker ocuser
newgrp docker
docker --version # Should show 27+

Step 4: Pull the OpenClaw Image​

# Check https://github.com/openclaw/openclaw/releases for the current stable tag.
# Replace 2026.4.x with that tag.
docker pull ghcr.io/openclaw/openclaw:2026.4.x

The image is ~1.2 GB; on Liquid Web's 10 Gbps network this pulls in under a minute. Never deploy :latest to production. Pin the tag so upgrades are explicit.

Create the config directory:

mkdir -p ~/.openclaw/workspace

Step 5: Configure Your LLM Provider​

Create ~/.openclaw/config.yaml. Choose one inference backend:

Option A: Claude (no GPU required)

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

agent:
max_steps: 50
timeout_seconds: 300

server:
port: 18789
host: 0.0.0.0

claude-sonnet-5 is the current Sonnet model — Active, with retirement "not sooner than June 30, 2027" on Anthropic's model deprecations page (checked 2026-09-09). It is a pinned snapshot, not a rolling pointer: Anthropic's models overview notes that dateless IDs from the 4.6 generation onward are each their own pinned snapshot. If you followed an earlier version of this guide, your config may still say claude-sonnet-4-5 — for pre-4.6 models that undated name is an alias that resolves to the dated ID claude-sonnet-4-5-20250929. It is still Active, but it carries the nearest retirement floor of any Sonnet ("not sooner than September 29, 2026"), so switch to claude-sonnet-5. Re-check both pages before deploying if you're reading this later.

Option B: OpenAI

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

server:
port: 18789
host: 0.0.0.0

Option C: Local Ollama (requires a GPU plan, see the GPU guide)

llm:
provider: ollama
base_url: http://host.docker.internal:11434
model: llama3.2:latest

server:
port: 18789
host: 0.0.0.0

Step 6: Write Docker Compose File​

Create ~/openclaw/docker-compose.yml:

services:
openclaw:
image: ghcr.io/openclaw/openclaw:2026.4.x # Pin to a specific release
restart: unless-stopped
ports:
- "127.0.0.1:18789:18789"
volumes:
- ~/.openclaw:/root/.openclaw
environment:
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
# or OPENAI_API_KEY=${OPENAI_API_KEY}
mem_limit: 2g
mem_reservation: 512m

Create a .env file alongside it:

# ~/openclaw/.env
ANTHROPIC_API_KEY=your_key_here

Start OpenClaw:

cd ~/openclaw
docker compose up -d
docker compose logs -f # Watch startup

After ~30 seconds you should see: OpenClaw gateway listening on :18789.

Step 7: Configure HTTPS with Caddy​

Do not expose port 18789 directly to the internet. Put Caddy in front for TLS termination.

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 update && sudo apt install caddy

Point your domain's A record to your server IP. Then create /etc/caddy/Caddyfile:

yourdomain.com {
reverse_proxy localhost:18789
}

Reload Caddy:

sudo systemctl reload caddy

Caddy automatically provisions a Let's Encrypt TLS certificate. Your dashboard is now at https://yourdomain.com.

Open the required ports in the firewall:

sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP (needed for ACME challenge)
sudo ufw allow 443/tcp # HTTPS
sudo ufw enable

Step 8: Connect a Messaging Platform​

Open the dashboard at https://yourdomain.com. Navigate to Integrations and pick your platform.

Telegram (quickest to set up):

  1. Open Telegram and message @BotFather
  2. Send /newbot and follow the prompts
  3. Copy the bot token
  4. In the OpenClaw dashboard, paste the token under Telegram
  5. Message your new bot. You should get a response within a few seconds

Slack:

  1. Create a Slack app at api.slack.com/apps
  2. Enable Socket Mode and Event Subscriptions
  3. Copy the Bot Token (xoxb-...) and App Token (xapp-...)
  4. Add to OpenClaw dashboard under Slack

Other platforms follow similar patterns. The OpenClaw docs at docs.openclaw.ai/platforms index per-platform install guides (Linux, macOS, Windows, Android, iOS, ChromeOS, plus Azure, Fly.io, GCP, Hetzner and other VPS hosts) — it's a directory page that links out to each walkthrough, not the walkthroughs themselves.

Step 9: Persistent Storage and Backups​

OpenClaw stores all state in ~/.openclaw/. This includes session tokens, conversation history, and installed skills. The bind mount in Docker Compose ensures data persists across container restarts.

Set up daily backups to an off-server location:

# Install rclone (supports S3, Backblaze B2, Dropbox, etc.)
sudo apt-get install -y rclone
rclone config # Follow prompts to add your storage backend

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

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

Monitoring​

Check container health:

docker compose ps
docker compose logs --tail=50

Set up a simple uptime check with a cron-based healthcheck:

# Ping the health endpoint every 5 minutes, alert if down
*/5 * * * * curl -sf http://localhost:18789/health || \
echo "OpenClaw DOWN at $(date)" | mail -s "OpenClaw Alert" you@example.com

Or use LiquidWeb's built-in server monitoring, available on all managed plans, to alert on process failures. For structured logs, metrics, and alerting beyond a cron healthcheck, see Monitoring & Observability for OpenClaw.

Upgrading OpenClaw​

cd ~/openclaw
docker compose pull
docker compose up -d

Always check the release notes before upgrading. OpenClaw does not guarantee config schema stability between minor versions.

Frequently Asked Questions

The 4 GB VPS ($8.50/mo on the current 50%-off-for-2-months promo, $17/mo list) is the minimum for a cloud-API backend. Use 8 GB if you have multiple users or run file-heavy tasks. For local model inference of anything above a 3B model, you need a dedicated GPU server, not a VPS. See the GPU guide.

Yes. Access the dashboard directly via http://YOUR_SERVER_IP:18789, but only over an SSH tunnel for security: ssh -L 18789:localhost:18789 ocuser@YOUR_SERVER_IP. Never expose port 18789 directly to the internet without TLS.

Update the image tag in docker-compose.yml, then run: docker compose pull && docker compose up -d. Your data in ~/.openclaw/ persists through upgrades.

Liquid Web VPS plans are available self-managed or fully managed. On fully managed plans, Liquid Web handles OS updates, security patches, and hardware; you manage the application layer (Docker, OpenClaw). Self-managed plans cost less but leave OS patching to you. Pick the management tier during checkout.

Common mistakes and fixes

Docker build OOM-kills on a 2 GB VPS.

The build requires at least 2 GB of available RAM. Either upgrade to the 4 GB plan or add a 2 GB swap file: fallocate -l 2G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile. Add to /etc/fstab for persistence.

OpenClaw container starts but messaging platform auth fails.

Most platform tokens expire if the session container was recreated without preserving state. Ensure the ~/.openclaw directory is bind-mounted into the container. Without it, session tokens are lost on restart.

Caddy fails to obtain a TLS certificate.

Caddy requires ports 80 and 443 to be open and your domain A record pointing to the server. Check: ufw status, then verify DNS with: dig +short yourdomain.com. Let's Encrypt rate limits apply, so wait 1 hour if you see 'too many requests'.