{"id":2000,"date":"2026-01-28T10:19:02","date_gmt":"2026-01-28T10:19:02","guid":{"rendered":"https:\/\/veerhost.com\/docs\/vps\/how-to-install-moltbot-clawdbot-on-a-veerhost-vps-docker\/"},"modified":"2026-03-31T17:54:49","modified_gmt":"2026-03-31T17:54:49","slug":"how-to-install-openclaw-on-a-veerhost-vps-docker","status":"publish","type":"docs","link":"https:\/\/veerhost.com\/de\/docs\/vps\/how-to-install-openclaw-on-a-veerhost-vps-docker\/","title":{"rendered":"How to Install OpenClaw on a VeerHost VPS (Docker)"},"content":{"rendered":"<p class=\"wp-block-paragraph\">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.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Note: Some older guides may still refer to OpenClaw as Moltbot or Clawdbot. In this documentation, we use the current name: OpenClaw.<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">Requirements<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before you begin, make sure you have:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A VeerHost VPS with Ubuntu 22.04 or Ubuntu 24.04<\/li>\n\n\n\n<li>SSH access to the server<\/li>\n\n\n\n<li>A sudo-enabled user<\/li>\n\n\n\n<li>Docker installed<\/li>\n\n\n\n<li>Docker Compose plugin installed<\/li>\n\n\n\n<li>A domain or subdomain if you want HTTPS or webhooks<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Connect to your VPS<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">SSH into your server:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ssh root@YOUR_SERVER_IP<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you use a non-root sudo user:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ssh youruser@YOUR_SERVER_IP<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: Update the system<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Update package lists and upgrade installed packages:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update &amp;&amp; sudo apt -y upgrade<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3: Install Docker<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If Docker is not already installed, run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt install -y ca-certificates curl gnupg\nsudo install -m 0755 -d \/etc\/apt\/keyrings\ncurl -fsSL https:\/\/download.docker.com\/linux\/ubuntu\/gpg | sudo gpg --dearmor -o \/etc\/apt\/keyrings\/docker.gpg\nsudo chmod a+r \/etc\/apt\/keyrings\/docker.gpg\necho \\\n  \"deb &#91;arch=$(dpkg --print-architecture) signed-by=\/etc\/apt\/keyrings\/docker.gpg] https:\/\/download.docker.com\/linux\/ubuntu \\\n  $(. \/etc\/os-release &amp;&amp; echo \"$VERSION_CODENAME\") stable\" | \\\n  sudo tee \/etc\/apt\/sources.list.d\/docker.list &gt; \/dev\/null\nsudo apt update\nsudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Verify the installation:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker --version\ndocker compose version<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4: Create the OpenClaw project directory<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create a dedicated directory for OpenClaw:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir -p ~\/openclaw\ncd ~\/openclaw<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you are cloning from a repository, use the current OpenClaw repository URL:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git clone https:\/\/github.com\/openclaw\/openclaw.git .<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you are using your own fork or private repository, replace the URL accordingly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 5: Create the environment file<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create a <code>.env<\/code> file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>nano .env<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Paste and adjust this example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>BOT_TOKEN=YOUR_TOKEN_HERE\n\nWEBHOOK_ENABLED=false\nWEBHOOK_URL=https:\/\/bot.yourdomain.com\/webhook\nWEBHOOK_PORT=3000\n\nDB_TYPE=postgres\nDB_HOST=127.0.0.1\nDB_PORT=5432\nDB_NAME=openclaw\nDB_USER=openclaw_user\nDB_PASSWORD=STRONG_PASSWORD_HERE\n\nREDIS_URL=redis:\/\/127.0.0.1:6379\n\nNODE_ENV=production\nLOG_LEVEL=info<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Save the file, then lock down permissions:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>chmod 600 .env<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 6: Create the Docker Compose file<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create a <code>docker-compose.yml<\/code> file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>nano docker-compose.yml<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Use this basic example and adjust it for your actual OpenClaw image and service requirements:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>services:\n  openclaw:\n    image: ghcr.io\/openclaw\/openclaw:latest\n    container_name: openclaw\n    restart: unless-stopped\n    env_file:\n      - .env\n    ports:\n      - \"127.0.0.1:3000:3000\"\n    depends_on:\n      - postgres\n      - redis\n\n  postgres:\n    image: postgres:16\n    container_name: openclaw_postgres\n    restart: unless-stopped\n    environment:\n      POSTGRES_DB: openclaw\n      POSTGRES_USER: openclaw_user\n      POSTGRES_PASSWORD: STRONG_PASSWORD_HERE\n    volumes:\n      - postgres_data:\/var\/lib\/postgresql\/data\n\n  redis:\n    image: redis:7\n    container_name: openclaw_redis\n    restart: unless-stopped\n    volumes:\n      - redis_data:\/data\n\nvolumes:\n  postgres_data:\n  redis_data:<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Important:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Bind the app only to <code>127.0.0.1<\/code> if you are using Nginx as a reverse proxy.<\/li>\n\n\n\n<li>Do not expose internal app ports publicly unless you truly need direct access.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Step 7: Start OpenClaw<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Launch the stack:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker compose up -d<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check running containers:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker compose ps<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">View logs:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker compose logs -f<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 8: Configure firewall rules<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Allow only the ports you need:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo ufw default deny incoming\nsudo ufw default allow outgoing\nsudo ufw allow OpenSSH\nsudo ufw allow 80\nsudo ufw allow 443\nsudo ufw enable\nsudo ufw status<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Do not open port 3000 publicly if Nginx is proxying traffic to OpenClaw locally.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 9: Optional Nginx reverse proxy<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If you want to access OpenClaw through a domain like <code>bot.yourdomain.com<\/code>, create an Nginx site:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo nano \/etc\/nginx\/sites-available\/openclaw<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example config:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server {\n    listen 80;\n    server_name bot.yourdomain.com;\n\n    location \/ {\n        proxy_pass http:\/\/127.0.0.1:3000;\n        proxy_http_version 1.1;\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n    }\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Enable the site:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo ln -s \/etc\/nginx\/sites-available\/openclaw \/etc\/nginx\/sites-enabled\/\nsudo nginx -t\nsudo systemctl reload nginx<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 10: Add SSL with Let\u2019s Encrypt<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Install Certbot:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt install -y certbot python3-certbot-nginx<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Request the certificate:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo certbot --nginx -d bot.yourdomain.com<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you enable webhook mode, update <code>.env<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>WEBHOOK_ENABLED=true\nWEBHOOK_URL=https:\/\/bot.yourdomain.com\/webhook\nWEBHOOK_PORT=3000<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then restart the stack:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker compose down\ndocker compose up -d<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">OpenClaw container is restarting<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Check logs first:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker compose logs -f openclaw<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Common causes:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Wrong token<\/li>\n\n\n\n<li>Bad database credentials<\/li>\n\n\n\n<li>Missing environment variables<\/li>\n\n\n\n<li>Port conflicts<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Port 3000 is already in use<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Find what is using the port:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo ss -tulpn | grep 3000<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Either stop the conflicting service or change the internal binding.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Database connection failed<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Make sure:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>PostgreSQL container is running<\/li>\n\n\n\n<li>Username, password, and database name match your <code>.env<\/code><\/li>\n\n\n\n<li>The app is using the correct host and port<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Nginx returns 502 Bad Gateway<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Usually this means OpenClaw is not running or is not listening on the expected port. Check:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker compose ps\ndocker compose logs -f openclaw<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Security tips<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Keep OpenClaw behind Nginx when possible<\/li>\n\n\n\n<li>Expose only ports 22, 80, and 443<\/li>\n\n\n\n<li>Store secrets only in <code>.env<\/code><\/li>\n\n\n\n<li>Use strong database passwords<\/li>\n\n\n\n<li>Keep Docker images updated<\/li>\n\n\n\n<li>Back up your <code>.env<\/code>, compose file, and database regularly<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Next Steps<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/veerhost.com\/de\/docs\/vps\/how-to-secure-and-harden-openclaw-on-a-veerhost-vps\/\">Secure and harden your OpenClaw installation<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/veerhost.com\/de\/docs\/vps\/how-to-secure-your-vps-ssh-keys-new-user-firewall\/\">Secure your VPS<\/a><\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>OpenClaw is a self-hosted AI assistant platform that can connect to messaging channels, webhooks, databases, and private knowledge sources. This guide walks [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":1967,"menu_order":7,"comment_status":"open","ping_status":"closed","template":"","doc_tag":[],"class_list":["post-2000","docs","type-docs","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/docs\/2000","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/docs"}],"about":[{"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/types\/docs"}],"author":[{"embeddable":true,"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/comments?post=2000"}],"version-history":[{"count":5,"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/docs\/2000\/revisions"}],"predecessor-version":[{"id":2294,"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/docs\/2000\/revisions\/2294"}],"up":[{"embeddable":true,"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/docs\/1967"}],"wp:attachment":[{"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/media?parent=2000"}],"wp:term":[{"taxonomy":"doc_tag","embeddable":true,"href":"https:\/\/veerhost.com\/de\/wp-json\/wp\/v2\/doc_tag?post=2000"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}