How to Set Up Moltbot/Clawdbot (Step-by-Step Guide)

Moltbot

Quick Requirements Checklist

Recommended Hosting

  • Veerhost VPS (Ubuntu 22.04 / 24.04 recommended)
  • SSH access + sudo user
  • A domain (optional but recommended for webhooks/dashboards)

Software You’ll Need

  • Git
  • Node.js 18+ or Python 3.10+
  • A database (MySQL/Postgres)
  • (Optional) Redis for queues/caching
  • Nginx + SSL if using webhooks

Part 1 — VPS Preparation (Veerhost)

1) SSH into your Veerhost server

ssh root@YOUR_SERVER_IP

If you use a non-root user:

ssh youruser@YOUR_SERVER_IP

2) Update packages

sudo apt update && sudo apt -y upgrade

3) Install core dependencies

sudo apt -y install git curl unzip ufw

4) Basic firewall (recommended)

Allow SSH and web traffic:

sudo ufw allow OpenSSH
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enable
sudo ufw status

Part 2 — Get Moltbot/Clawdbot Files onto Veerhost

Option A: Clone from Git (recommended)

cd ~
git clone https://github.com/YOUR_ORG/YOUR_BOT_REPO.git moltbot
cd moltbot

Option B: Upload a ZIP

Upload via SFTP, then:

cd ~
unzip moltbot.zip -d moltbot
cd moltbot

Part 3 — Configure Environment Variables (.env)

Most bots use a .env file so you don’t hardcode secrets in source files.

Create .env

nano .env

Example .env (generic, works for many bots)

# Bot platform token
BOT_TOKEN=YOUR_TOKEN_HERE

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

# Database
DB_TYPE=postgres
DB_HOST=127.0.0.1
DB_PORT=5432
DB_NAME=moltbot
DB_USER=moltbot_user
DB_PASSWORD=STRONG_PASSWORD_HERE

# Optional Redis
REDIS_URL=redis://127.0.0.1:6379

# App settings
NODE_ENV=production
LOG_LEVEL=info

Save and exit (Ctrl+O, Enter, Ctrl+X).

Lock down permissions

chmod 600 .env

Part 4 — Database Setup (Choose MySQL or PostgreSQL)

Option 1: PostgreSQL (excellent for production)

Install PostgreSQL

sudo apt -y install postgresql postgresql-contrib

Create database + user

sudo -u postgres psql

Inside psql:

CREATE DATABASE moltbot;
CREATE USER moltbot_user WITH ENCRYPTED PASSWORD 'STRONG_PASSWORD_HERE';
GRANT ALL PRIVILEGES ON DATABASE moltbot TO moltbot_user;
\q

Update .env accordingly (DB_HOST, DB_USER, DB_PASSWORD, etc.).


Option 2: MySQL (common on hosting stacks)

Install MySQL

sudo apt -y install mysql-server
sudo mysql_secure_installation

Create database + user

sudo mysql

In MySQL:

CREATE DATABASE moltbot CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'moltbot_user'@'localhost' IDENTIFIED BY 'STRONG_PASSWORD_HERE';
GRANT ALL PRIVILEGES ON moltbot.* TO 'moltbot_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Update .env:

DB_TYPE=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=moltbot
DB_USER=moltbot_user
DB_PASSWORD=STRONG_PASSWORD_HERE

Part 5A — Deploy Moltbot/Clawdbot (Node.js Version)

If your bot has package.json, use this section.

1) Install Node.js 18+ (LTS)

curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt -y install nodejs
node -v
npm -v

2) Install dependencies

cd ~/moltbot
npm ci --omit=dev

If your project uses build steps:

npm run build

3) Run a quick test

Common start commands:

npm start
# or
node index.js
# or
node src/main.js

If it starts successfully, stop it (Ctrl+C) and continue to production process management.


4) Run in production with PM2 (auto-restart)

Install PM2

sudo npm i -g pm2

Start the bot

Use your actual entry file (examples below):

pm2 start "npm start" --name moltbot

Or:

pm2 start dist/index.js --name moltbot

Save and enable startup on reboot

pm2 save
pm2 startup

PM2 will print a command—copy/paste it.

View logs

pm2 logs moltbot

Common PM2 commands

pm2 status
pm2 restart moltbot
pm2 stop moltbot
pm2 delete moltbot

Part 5B — Deploy Moltbot/Clawdbot (Python Version)

If your bot has requirements.txt or pyproject.toml, use this section.

1) Install Python tooling

sudo apt -y install python3 python3-venv python3-pip

2) Create virtual environment

cd ~/moltbot
python3 -m venv .venv
source .venv/bin/activate

3) Install dependencies

pip install --upgrade pip wheel
pip install -r requirements.txt

4) Run a quick test

Examples:

python main.py
# or
python -m bot

Stop it (Ctrl+C).


5) Run in production with systemd (recommended for Python)

Create a service file

sudo nano /etc/systemd/system/moltbot.service

Paste (adjust paths and entrypoint):

[Unit]
Description=Moltbot/Clawdbot Service
After=network.target

[Service]
Type=simple
User=%i
WorkingDirectory=/home/%i/moltbot
EnvironmentFile=/home/%i/moltbot/.env
ExecStart=/home/%i/moltbot/.venv/bin/python main.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Enable it (replace youruser):

sudo systemctl daemon-reload
sudo systemctl enable --now moltbot@youruser
sudo systemctl status moltbot@youruser --no-pager

Logs:

journalctl -u moltbot@youruser -f

Part 6 — Webhook + Nginx + SSL (If Your Bot Uses Webhooks)

Some bot platforms prefer webhooks instead of long polling. If Moltbot/Clawdbot supports webhooks (or includes a dashboard), set it up properly with HTTPS.

1) Install Nginx

sudo apt -y install nginx
sudo systemctl enable --now nginx

2) Point your domain to the VPS

In DNS:

  • A record: bot.yourdomain.comYOUR_SERVER_IP

3) Configure Nginx reverse proxy

Create a site config:

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

Example (proxy to port 3000):

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 it:

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

4) Add SSL with Let’s Encrypt (Certbot)

sudo apt -y install certbot python3-certbot-nginx
sudo certbot --nginx -d bot.yourdomain.com

Now update .env:

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

Restart your bot process (PM2/systemd).


Part 7 — Code Examples You Can Copy

Below are common patterns you might need while integrating Moltbot/Clawdbot with webhooks, health checks, and database connections.

A) Node.js — Minimal webhook server (Express)

import express from "express";

const app = express();
app.use(express.json());

app.get("/health", (req, res) => res.status(200).send("OK"));

app.post("/webhook", async (req, res) => {
  try {
    const update = req.body;

    // TODO: pass update to Moltbot/Clawdbot handler
    // await bot.handleUpdate(update);

    return res.status(200).json({ ok: true });
  } catch (err) {
    console.error("Webhook error:", err);
    return res.status(500).json({ ok: false });
  }
});

const port = process.env.WEBHOOK_PORT || 3000;
app.listen(port, () => console.log(`Webhook listening on ${port}`));

B) Python — Minimal webhook server (FastAPI)

import os
from fastapi import FastAPI, Request
from fastapi.responses import PlainTextResponse

app = FastAPI()

@app.get("/health")
def health():
    return PlainTextResponse("OK")

@app.post("/webhook")
async def webhook(request: Request):
    update = await request.json()

    # TODO: pass update to Moltbot/Clawdbot handler
    # await bot.handle_update(update)

    return {"ok": True}

if __name__ == "__main__":
    import uvicorn
    port = int(os.getenv("WEBHOOK_PORT", "3000"))
    uvicorn.run(app, host="127.0.0.1", port=port)

C) Node.js — Example Postgres connection (pg)

import pg from "pg";
const { Pool } = pg;

export const pool = new Pool({
  host: process.env.DB_HOST,
  port: Number(process.env.DB_PORT || 5432),
  database: process.env.DB_NAME,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  max: 10,
  idleTimeoutMillis: 30000,
});

export async function testDb() {
  const res = await pool.query("SELECT NOW() AS now");
  console.log("DB OK:", res.rows[0].now);
}

D) Python — Example Postgres connection (psycopg)

import os
import psycopg

def get_conn():
    return psycopg.connect(
        host=os.getenv("DB_HOST", "127.0.0.1"),
        port=int(os.getenv("DB_PORT", "5432")),
        dbname=os.getenv("DB_NAME", "moltbot"),
        user=os.getenv("DB_USER", "moltbot_user"),
        password=os.getenv("DB_PASSWORD", ""),
    )

with get_conn() as conn:
    with conn.cursor() as cur:
        cur.execute("SELECT NOW()")
        print("DB OK:", cur.fetchone()[0])

Part 8 — Troubleshooting (Most Common Issues)

1) “Bot token invalid” / “401 Unauthorized”

  • Double-check BOT_TOKEN
  • Ensure no extra spaces or quotes in .env
  • Restart the process after updating secrets

2) Port already in use

Find what is using port 3000:

sudo lsof -i :3000

Stop it or change WEBHOOK_PORT.

3) Nginx returns 502 Bad Gateway

  • Your bot process may be down
  • Your bot is listening on the wrong interface/port
  • Confirm it’s bound to 127.0.0.1:3000 (or your configured port)
  • Check logs:
    • pm2 logs moltbot
    • journalctl -u moltbot@youruser -f
    • sudo tail -n 200 /var/log/nginx/error.log

4) Database connection fails

  • Confirm DB service is running:
    • sudo systemctl status postgresql
    • sudo systemctl status mysql
  • Confirm credentials and ports match .env
  • Confirm user permissions were granted

Part 9 — Updates, Backups, and Security

Update the bot from Git

cd ~/moltbot
git pull
npm ci --omit=dev   # Node
npm run build       # if needed
pm2 restart moltbot

Or for Python:

cd ~/moltbot
git pull
source .venv/bin/activate
pip install -r requirements.txt
sudo systemctl restart moltbot@youruser

Back up your database (example: Postgres)

pg_dump -U moltbot_user -d moltbot > moltbot_backup.sql

Security Tips: Protect Your Veerhost VPS When Running Moltbot / Clawdbot

Security Disclaimer: Moltbot/Clawdbot should be deployed securely. Misconfigured servers (especially open ports, exposed dashboards, or unsecured databases) can be targeted by automated scanning and intrusion attempts. For your safety, follow the security steps in this guide—close unused ports, protect admin panels, and keep your system updated.

Running a bot 24/7 means your server is online 24/7—so security matters. Many attacks are not “personal”; they’re automated bots scanning the internet for open ports, weak passwords, exposed databases, or public admin panels.

1) Close all unused ports (critical)

Only allow what you actually need:

  • 22 (SSH) — ideally restricted
  • 80/443 (HTTP/HTTPS) — only if you use webhooks/dashboard
  • Your bot’s internal port (like 3000) should NOT be public if Nginx is proxying it.

UFW: allow only SSH + web

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

Make sure your bot port is NOT exposed

If your bot listens on port 3000, do not allow it in UFW:

sudo ufw delete allow 3000 2>/dev/null || true
sudo ufw status

Also make the bot bind to localhost only:

  • Node/FastAPI/Uvicorn/Express should listen on 127.0.0.1, not 0.0.0.0.

Example (FastAPI / Uvicorn):

uvicorn app:app --host 127.0.0.1 --port 3000

2) Secure SSH (reduce the biggest risk)

Use SSH keys (recommended)

Generate on your local machine:

ssh-keygen -t ed25519
ssh-copy-id youruser@YOUR_SERVER_IP

Disable password login (after keys work)

Edit:

sudo nano /etc/ssh/sshd_config

Set:

PasswordAuthentication no
PermitRootLogin no

Restart SSH:

sudo systemctl restart ssh

3) Install Fail2ban (blocks brute-force logins)

sudo apt -y install fail2ban
sudo systemctl enable --now fail2ban
sudo fail2ban-client status

4) Never expose your database to the internet

Databases should bind to localhost only unless you really need remote access.

Check listening ports

sudo ss -tulpn

If you see MySQL/Postgres listening on 0.0.0.0, fix it:

  • Postgres config usually in:
    • /etc/postgresql/*/main/postgresql.conflisten_addresses = 'localhost'
  • MySQL config usually in:
    • /etc/mysql/mysql.conf.d/mysqld.cnfbind-address = 127.0.0.1

Restart DB service after changes.

5) Protect any dashboard/admin endpoints

If Moltbot/Clawdbot has an admin page:

  • Put it behind auth
  • Restrict access by IP (best)
  • Or use Basic Auth in Nginx

Example: Nginx basic auth

sudo apt -y install apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd adminuser

Then in Nginx:

location /admin {
    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/.htpasswd;
    proxy_pass http://127.0.0.1:3000;
}

Reload:

sudo nginx -t && sudo systemctl reload nginx

6) Keep the server updated (easy win)

sudo apt update && sudo apt -y upgrade

Optional automatic security updates:

sudo apt -y install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

7) Protect secrets (.env) and rotate tokens if leaked

  • Keep .env permissions tight:
chmod 600 .env
  • Never commit .env to Git
  • If you suspect compromise: rotate BOT_TOKEN and DB passwords immediately

8) Monitor logs regularly

  • PM2:
pm2 logs moltbot
  • systemd:
journalctl -u moltbot@youruser -f
  • Auth attempts:
sudo tail -n 200 /var/log/auth.log

9) Quick compromise checklist (if you suspect hacking)

  1. Change SSH passwords / rotate keys
  2. Rotate bot token + DB credentials
  3. Check unknown users: cut -d: -f1 /etc/passwd
  4. Check suspicious processes: ps aux --sort=-%cpu | head
  5. Check open ports: sudo ss -tulpn
  6. Consider rebuilding the VPS if you see clear compromise indicators

FAQ: Moltbot / Clawdbot on Veerhost

Should I use long polling or webhooks?

  • Long polling is easier (no domain/SSL needed).
  • Webhooks are more production-friendly and often faster, but require HTTPS and a stable endpoint.

Can I host this on shared hosting?

Usually bots need a persistent process (always running). Shared hosting often stops background processes. A Veerhost VPS is the safest choice.

What’s the best “always on” method?

  • Node.js: PM2
  • Python: systemd