How to Install OpenClaw on a VeerHost VPS (Docker)

Estimated reading: 5 minutes

OpenClaw is a self-hosted AI assistant platform that can connect to messaging channels, webhooks, databases, and private knowledge sources. This guide walks you through installing OpenClaw on a VeerHost VPS using Docker in a cleaner, more secure way.

Note: Some older guides may still refer to OpenClaw as Moltbot or Clawdbot. In this documentation, we use the current name: OpenClaw.

Requirements

Before you begin, make sure you have:

  • A VeerHost VPS with Ubuntu 22.04 or Ubuntu 24.04
  • SSH access to the server
  • A sudo-enabled user
  • Docker installed
  • Docker Compose plugin installed
  • A domain or subdomain if you want HTTPS or webhooks

Step 1: Connect to your VPS

SSH into your server:

ssh root@YOUR_SERVER_IP

If you use a non-root sudo user:

ssh youruser@YOUR_SERVER_IP

Step 2: Update the system

Update package lists and upgrade installed packages:

sudo apt update && sudo apt -y upgrade

Step 3: Install Docker

If Docker is not already installed, run:

sudo apt install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Verify the installation:

docker --version
docker compose version

Step 4: Create the OpenClaw project directory

Create a dedicated directory for OpenClaw:

mkdir -p ~/openclaw
cd ~/openclaw

If you are cloning from a repository, use the current OpenClaw repository URL:

git clone https://github.com/openclaw/openclaw.git .

If you are using your own fork or private repository, replace the URL accordingly.

Step 5: Create the environment file

Create a .env file:

nano .env

Paste and adjust this example:

BOT_TOKEN=YOUR_TOKEN_HERE

WEBHOOK_ENABLED=false
WEBHOOK_URL=https://bot.yourdomain.com/webhook
WEBHOOK_PORT=3000

DB_TYPE=postgres
DB_HOST=127.0.0.1
DB_PORT=5432
DB_NAME=openclaw
DB_USER=openclaw_user
DB_PASSWORD=STRONG_PASSWORD_HERE

REDIS_URL=redis://127.0.0.1:6379

NODE_ENV=production
LOG_LEVEL=info

Save the file, then lock down permissions:

chmod 600 .env

Step 6: Create the Docker Compose file

Create a docker-compose.yml file:

nano docker-compose.yml

Use this basic example and adjust it for your actual OpenClaw image and service requirements:

services:
  openclaw:
    image: ghcr.io/openclaw/openclaw:latest
    container_name: openclaw
    restart: unless-stopped
    env_file:
      - .env
    ports:
      - "127.0.0.1:3000:3000"
    depends_on:
      - postgres
      - redis

  postgres:
    image: postgres:16
    container_name: openclaw_postgres
    restart: unless-stopped
    environment:
      POSTGRES_DB: openclaw
      POSTGRES_USER: openclaw_user
      POSTGRES_PASSWORD: STRONG_PASSWORD_HERE
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:7
    container_name: openclaw_redis
    restart: unless-stopped
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
  redis_data:

Important:

  • Bind the app only to 127.0.0.1 if you are using Nginx as a reverse proxy.
  • Do not expose internal app ports publicly unless you truly need direct access.

Step 7: Start OpenClaw

Launch the stack:

docker compose up -d

Check running containers:

docker compose ps

View logs:

docker compose logs -f

Step 8: Configure firewall rules

Allow only the ports you need:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enable
sudo ufw status

Do not open port 3000 publicly if Nginx is proxying traffic to OpenClaw locally.

Step 9: Optional Nginx reverse proxy

If you want to access OpenClaw through a domain like bot.yourdomain.com, create an Nginx site:

sudo nano /etc/nginx/sites-available/openclaw

Example config:

server {
    listen 80;
    server_name bot.yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        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;
    }
}

Enable the site:

sudo ln -s /etc/nginx/sites-available/openclaw /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Step 10: Add SSL with Let’s Encrypt

Install Certbot:

sudo apt install -y certbot python3-certbot-nginx

Request the certificate:

sudo certbot --nginx -d bot.yourdomain.com

If you enable webhook mode, update .env:

WEBHOOK_ENABLED=true
WEBHOOK_URL=https://bot.yourdomain.com/webhook
WEBHOOK_PORT=3000

Then restart the stack:

docker compose down
docker compose up -d

Troubleshooting

OpenClaw container is restarting

Check logs first:

docker compose logs -f openclaw

Common causes:

  • Wrong token
  • Bad database credentials
  • Missing environment variables
  • Port conflicts

Port 3000 is already in use

Find what is using the port:

sudo ss -tulpn | grep 3000

Either stop the conflicting service or change the internal binding.

Database connection failed

Make sure:

  • PostgreSQL container is running
  • Username, password, and database name match your .env
  • The app is using the correct host and port

Nginx returns 502 Bad Gateway

Usually this means OpenClaw is not running or is not listening on the expected port. Check:

docker compose ps
docker compose logs -f openclaw

Security tips

  • Keep OpenClaw behind Nginx when possible
  • Expose only ports 22, 80, and 443
  • Store secrets only in .env
  • Use strong database passwords
  • Keep Docker images updated
  • Back up your .env, compose file, and database regularly

Next Steps