Documentation Index
Fetch the complete documentation index at: https://mintlify.com/bidewio/better-openclaw/llms.txt
Use this file to discover all available pages before exploring further.
Deploy better-openclaw stacks to any VPS provider (DigitalOcean, Linode, Vultr, Hetzner, AWS EC2, etc.) with Docker or bare-metal.
Prerequisites
- VPS with 2GB+ RAM (varies by preset)
- Ubuntu 22.04+ or Debian 11+ (recommended)
- Root or sudo access
- Public IP address
- SSH key authentication (recommended)
Server sizing guide
Choose a VPS size based on your preset:
| Preset | RAM | CPU | Disk | Cost/month |
|---|
| Minimal | 1 GB | 1 vCPU | 25 GB | $5-10 |
| Creator | 2 GB | 2 vCPU | 50 GB | $10-20 |
| Researcher | 4 GB | 2 vCPU | 80 GB | $20-40 |
| DevOps | 4 GB | 2 vCPU | 80 GB | $20-40 |
| AI Playground | 8 GB | 4 vCPU | 160 GB | $40-80 |
| Full Stack | 8 GB | 4 vCPU | 160 GB | $40-80 |
Initial server setup
Create VPS
Create a VPS with your preferred provider:DigitalOcean:doctl compute droplet create openclaw \
--region nyc3 \
--size s-2vcpu-4gb \
--image ubuntu-22-04-x64 \
--ssh-keys YOUR_KEY_ID
Hetzner:hcloud server create \
--name openclaw \
--type cx21 \
--image ubuntu-22.04 \
--ssh-key YOUR_KEY_NAME
Update system
Update packages and install essentials:apt update && apt upgrade -y
apt install -y curl git ufw
Configure firewall
Set up UFW firewall:# Allow SSH
ufw allow 22/tcp
# Allow HTTP/HTTPS (if using reverse proxy)
ufw allow 80/tcp
ufw allow 443/tcp
# Enable firewall
ufw --force enable
Docker deployment
Install Docker
Install Docker Engine
curl -fsSL https://get.docker.com | sh
Enable Docker service
systemctl enable docker
systemctl start docker
Verify installation
docker --version
docker compose version
Deploy stack
Generate stack locally
On your local machine:npx create-better-openclaw@latest \
--preset researcher \
--proxy caddy \
--domain example.com \
--yes
Transfer to VPS
Upload the generated stack:rsync -avz ./my-openclaw-stack root@YOUR_SERVER_IP:/opt/openclaw
Configure environment
SSH into the server and edit .env:ssh root@YOUR_SERVER_IP
cd /opt/openclaw
nano .env
Update:
- Domain names
- API keys
- Database passwords
- Email settings (for Let’s Encrypt)
Start services
Launch the stack:Monitor logs:
Install dependencies
Install Docker
curl -fsSL https://get.docker.com | sh
systemctl enable docker
systemctl start docker
Generate stack with bare-metal mode
On your local machine:npx create-better-openclaw@latest \
--preset researcher \
--deployment-mode bare-metal \
--yes
Transfer to VPS
Upload the stack:rsync -avz ./my-openclaw-stack root@YOUR_SERVER_IP:/opt/openclaw
Run installer
SSH into the server and run the installer:ssh root@YOUR_SERVER_IP
cd /opt/openclaw
chmod +x install.sh
./install.sh
This will:
- Install native services (Redis, etc.)
- Configure systemd units
- Start native services
- Launch Docker containers for remaining services
DNS configuration
Point your domain to the VPS:
Create A record
In your DNS provider, create an A record:| Type | Name | Value | TTL |
|---|
| A | @ | YOUR_SERVER_IP | 300 |
Create CNAME for subdomains (optional)
For service-specific subdomains:| Type | Name | Value | TTL |
|---|
| CNAME | grafana | example.com | 300 |
| CNAME | n8n | example.com | 300 |
Verify DNS propagation
Check DNS resolution:dig example.com +short
dig grafana.example.com +short
SSL/TLS configuration
Caddy (automatic)
Caddy automatically provisions Let’s Encrypt certificates. No additional configuration needed.
Verify:
curl -I https://example.com
Traefik (automatic)
Traefik provisions certificates when traefik.http.routers.<service>.tls.certresolver=letsencrypt is set.
Verify in Traefik dashboard:
open http://YOUR_SERVER_IP:8080
Manual (Certbot)
For custom SSL setup:
# Install Certbot
apt install -y certbot
# Generate certificate
certbot certonly --standalone -d example.com
# Certificates saved to:
# /etc/letsencrypt/live/example.com/fullchain.pem
# /etc/letsencrypt/live/example.com/privkey.pem
Update docker-compose.yml to mount certificates:
services:
caddy:
volumes:
- /etc/letsencrypt:/etc/letsencrypt:ro
Security hardening
Disable root SSH
Create non-root user
adduser openclaw
usermod -aG sudo openclaw
usermod -aG docker openclaw
Copy SSH key
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
Edit SSH config:nano /etc/ssh/sshd_config
Set:PermitRootLogin no
PasswordAuthentication no
Restart SSH:
Enable automatic updates
# Install unattended-upgrades
apt install -y unattended-upgrades
# Enable automatic security updates
dpkg-reconfigure -plow unattended-upgrades
Install fail2ban
Protect against brute-force attacks:
apt install -y fail2ban
systemctl enable fail2ban
systemctl start fail2ban
Monitoring and maintenance
System monitoring
If you included Grafana and Prometheus in your stack:
- Access Grafana at
https://grafana.example.com
- Login with credentials from
.env
- View pre-configured dashboards for system metrics
Log management
View service logs:
# Docker services
docker compose logs -f
# Native services
journalctl -u redis -f
Rotate logs to prevent disk overflow:
# Configure Docker log rotation
nano /etc/docker/daemon.json
Add:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
Restart Docker:
Backup strategy
Create backup script
nano /opt/openclaw/backup.sh
Add:#!/bin/bash
BACKUP_DIR="/backup/openclaw-$(date +%F)"
mkdir -p $BACKUP_DIR
# Backup Docker volumes
docker run --rm -v postgres-data:/data -v $BACKUP_DIR:/backup \
alpine tar czf /backup/postgres.tar.gz -C /data .
docker run --rm -v redis-data:/data -v $BACKUP_DIR:/backup \
alpine tar czf /backup/redis.tar.gz -C /data .
# Backup .env
cp /opt/openclaw/.env $BACKUP_DIR/
echo "Backup complete: $BACKUP_DIR"
Make executable:chmod +x /opt/openclaw/backup.sh
Schedule daily backups
Add to crontab:Add:0 2 * * * /opt/openclaw/backup.sh
Update stack
Update services to latest versions:
cd /opt/openclaw
# Pull latest images
docker compose pull
# Recreate containers
docker compose up -d --force-recreate
# Clean up old images
docker image prune -a -f
Scaling considerations
Vertical scaling
Increase VPS resources:
-
Resize VPS via provider dashboard
-
Restart VPS
-
Verify new resources:
Horizontal scaling
For high availability, use:
- Load balancer: Distribute traffic across multiple VPS instances
- Shared database: External PostgreSQL (e.g., AWS RDS, DigitalOcean Managed DB)
- Shared cache: External Redis (e.g., Redis Cloud, AWS ElastiCache)
- Object storage: External MinIO or S3-compatible storage
Or migrate to Dokploy or Coolify for built-in orchestration.
Troubleshooting
Services won’t start
Check logs:
docker compose logs <service-name>
Common issues:
- Port conflicts:
lsof -i :<port>
- Insufficient memory:
free -h
- Missing environment variables:
cat .env
SSL certificate errors
Error: Certificate provisioning failed
Solution:
- Verify DNS points to server IP:
dig example.com +short
- Ensure ports 80 and 443 are open:
ufw status
- Check Caddy/Traefik logs:
docker compose logs caddy
Disk space issues
Check disk usage:
Clean up Docker:
docker system prune -a --volumes
Resize disk via provider dashboard if needed.
Connection refused
Error: Cannot connect to services
Solution:
- Verify services are running:
docker compose ps
- Check firewall rules:
ufw status
- Test locally first:
curl http://localhost:3000
- Verify DNS:
dig example.com
Provider-specific guides
DigitalOcean
Hetzner
Vultr
Linode
Next steps