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

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:
Arecord:bot.yourdomain.com→YOUR_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 moltbotjournalctl -u moltbot@youruser -fsudo tail -n 200 /var/log/nginx/error.log
4) Database connection fails
- Confirm DB service is running:
sudo systemctl status postgresqlsudo 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, not0.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.conf→listen_addresses = 'localhost'
- MySQL config usually in:
/etc/mysql/mysql.conf.d/mysqld.cnf→bind-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
.envpermissions tight:
chmod 600 .env
- Never commit
.envto 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)
- Change SSH passwords / rotate keys
- Rotate bot token + DB credentials
- Check unknown users:
cut -d: -f1 /etc/passwd - Check suspicious processes:
ps aux --sort=-%cpu | head - Check open ports:
sudo ss -tulpn - 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