OpenClaw AI App Hosting on VPS with pgvector

Start with the deployment shape, not the app code
OpenClaw AI app hosting on VPS works best when you treat the server like a production system, not a demo box. For support bots, sales bots, RAG apps, and workflow agents, a small VPS with PostgreSQL, pgvector, Redis, and a Node.js or Next.js app is usually easier to control than a serverless stack that hides logs, secrets, and regional placement.
If you want a broader look at where VPS hosting fits, see AI Agent Hosting on VPS: A Practical 2026 Setup Guide and Private AI Hosting for Bots, RAG, and Next.js Apps. For platform comparisons, a Hostperl VPS gives you the control you need for data residency, predictable costs, and supportable deployments.
Use these placeholders throughout the tutorial: SERVER_IP is your VPS address, DOMAIN_NAME is the hostname you will point at the app, ADMIN_USER is your sudo user, APP_USER is the runtime account, APP_DIR is the app path, and APP_PORT is the local backend port. Example values are 203.0.113.10, bot.example.com, deploy, openclaw, /opt/openclaw, and 3000.
Connect, detect the OS, and create a safer admin user
Start on your local computer by opening SSH. Leave the root session open until the new user is confirmed and working.
ssh root@SERVER_IPIf your provider gave you a non-root default login, use that instead. Once connected, check the distribution before installing anything.
cat /etc/os-releaseYou should see Ubuntu/Debian or AlmaLinux/Rocky Linux details. Next, create a non-root administrator.
Ubuntu and Debian
adduser ADMIN_USER
usermod -aG sudo ADMIN_USER
mkdir -p /home/ADMIN_USER/.ssh
chmod 700 /home/ADMIN_USER/.ssh
cp /root/.ssh/authorized_keys /home/ADMIN_USER/.ssh/authorized_keys
chown -R ADMIN_USER:ADMIN_USER /home/ADMIN_USER/.ssh
chmod 600 /home/ADMIN_USER/.ssh/authorized_keysThis creates the account, adds sudo access, and copies your SSH key so you can log in without a password. Replace ADMIN_USER with your real admin name.
AlmaLinux and Rocky Linux
useradd -m ADMIN_USER
passwd ADMIN_USER
usermod -aG wheel ADMIN_USER
mkdir -p /home/ADMIN_USER/.ssh
chmod 700 /home/ADMIN_USER/.ssh
cp /root/.ssh/authorized_keys /home/ADMIN_USER/.ssh/authorized_keys
chown -R ADMIN_USER:ADMIN_USER /home/ADMIN_USER/.ssh
chmod 600 /home/ADMIN_USER/.ssh/authorized_keysOn these systems, wheel grants sudo rights. If root does not already have an SSH key, add one from your local computer first, then repeat the copy step safely.
Open a second terminal on your local computer and test the new login.
ssh ADMIN_USER@SERVER_IP
sudo -v
whoami
pwdYou want to see ADMIN_USER from whoami and no sudo errors. Only after that should you consider disabling root password login.
Install the stack for OpenClaw AI app hosting on VPS
This tutorial uses a straightforward stack: Node.js for the app, PostgreSQL with pgvector for retrieval, Redis for queueing and rate limits, Nginx for TLS termination, and systemd for process control. If you are deciding between deployment styles, our notes on Next.js deployment on VPS explain the same operational pattern from a site owner’s point of view.
Ubuntu and Debian packages
sudo apt update
sudo apt install -y nginx postgresql postgresql-contrib redis-server curl ca-certificates gnupg ufw
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs gitCheck versions so you know what actually installed.
node -v
npm -v
psql --version
redis-server --version
nginx -vAlmaLinux and Rocky Linux packages
sudo dnf -y install nginx postgresql-server postgresql-contrib redis curl git firewalld
sudo dnf -y module install nodejs:22
sudo systemctl enable --now firewalldInitialize PostgreSQL if this is a fresh install.
sudo postgresql-setup --initdbThen confirm the services are available.
node -v
npm -v
psql --version
redis-server --version
nginx -vStart the database, Redis, and Nginx services on both families.
sudo systemctl enable --now postgresql
sudo systemctl enable --now redis-server
sudo systemctl enable --now nginxPrepare PostgreSQL, pgvector, and app credentials
OpenClaw-style bots usually need two kinds of data: structured records and retrieval chunks. PostgreSQL with pgvector handles both cleanly on a small VPS, which is why many Hostperl customers use it before they outgrow a single server. If you later need a larger box, managed VPS hosting keeps the move straightforward.
Create the database and user
Run these commands on the VPS as root or with sudo.
sudo -iu postgres psqlInside psql, create the database and role.
CREATE USER openclaw_user WITH PASSWORD 'REPLACE_WITH_STRONG_PASSWORD';
CREATE DATABASE openclaw OWNER openclaw_user;
\c openclaw
CREATE EXTENSION IF NOT EXISTS vector;
\qIf vector is not available in your package set, install the pgvector package for your distribution or use a PostgreSQL image that includes it. A missing extension is the most common retrieval setup failure.
Set up the app directory and secrets file
sudo useradd --system --create-home --home-dir /opt/openclaw --shell /usr/sbin/nologin openclaw || true
sudo mkdir -p /opt/openclaw/app
sudo chown -R openclaw:openclaw /opt/openclaw
sudo nano /opt/openclaw/app/.envPaste this file content and replace the placeholders with your own values.
NODE_ENV=production
APP_PORT=3000
DOMAIN_NAME=bot.example.com
DATABASE_URL=postgresql://openclaw_user:REPLACE_WITH_STRONG_PASSWORD@127.0.0.1:5432/openclaw
REDIS_URL=redis://127.0.0.1:6379
OPENAI_API_KEY=replace_me
EMBEDDING_MODEL=text-embedding-3-large
CHAT_MODEL=gpt-4.1-mini
JWT_SECRET=replace_with_a_long_random_string
ALLOWED_ORIGIN=https://bot.example.comSave and exit the editor. Then lock the file down so only the app owner can read it.
sudo chown openclaw:openclaw /opt/openclaw/app/.env
sudo chmod 600 /opt/openclaw/app/.env
sudo ls -l /opt/openclaw/app/.envThe permissions should show -rw-------.
Deploy the app with a process manager and background jobs
This example assumes a Node.js app with a server entry point at server.js and a queue worker at worker.js. If your stack is Next.js, NestJS, or FastAPI behind a Node proxy, the same operational pattern still applies. For a broader service comparison, see AI App Hosting for Bots, RAG, and Private Workloads.
On the VPS as the non-root sudo user, place your app code in /opt/openclaw/app. If you are cloning from Git, replace the repository URL.
sudo -iu openclaw
cd /opt/openclaw/app
git clone https://example.com/openclaw-app.git .
npm ci
npm run buildConfirm the build completed and the lockfile resolved cleanly.
ls -la
npm run test --if-presentCreate a systemd service for the web app
Back on the VPS as root or a sudo user, create the service unit.
sudo nano /etc/systemd/system/openclaw-web.serviceUse this content.
[Unit]
Description=OpenClaw Web App
After=network.target postgresql.service redis-server.service
[Service]
Type=simple
User=openclaw
WorkingDirectory=/opt/openclaw/app
EnvironmentFile=/opt/openclaw/app/.env
ExecStart=/usr/bin/node /opt/openclaw/app/server.js
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.targetCheck the unit before starting it.
sudo systemctl daemon-reload
sudo systemctl enable --now openclaw-web
sudo systemctl status openclaw-web --no-pagerCreate a worker service for embeddings and jobs
sudo nano /etc/systemd/system/openclaw-worker.serviceUse this content for queue jobs, webhook retries, and embedding refresh tasks.
[Unit]
Description=OpenClaw Worker
After=network.target postgresql.service redis-server.service
[Service]
Type=simple
User=openclaw
WorkingDirectory=/opt/openclaw/app
EnvironmentFile=/opt/openclaw/app/.env
ExecStart=/usr/bin/node /opt/openclaw/app/worker.js
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.targetThen enable it and confirm both services are active.
sudo systemctl daemon-reload
sudo systemctl enable --now openclaw-worker
sudo systemctl status openclaw-worker --no-pagerCheck logs if either unit fails.
sudo journalctl -u openclaw-web -n 50 --no-pager
sudo journalctl -u openclaw-worker -n 50 --no-pagerPut Nginx in front, then add TLS
Nginx handles public traffic, compresses static assets, and gives you a stable place to terminate HTTPS. That matters for AI apps because you will often call webhooks, show admin pages, and send browser traffic to the same host.
Firewall rules first
Open SSH, HTTP, and HTTPS before you switch traffic over.
Ubuntu and Debian with UFW
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verboseAlmaLinux and Rocky Linux with firewalld
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-allConfigure the reverse proxy
sudo nano /etc/nginx/sites-available/openclawOn Debian-based systems, use this server block.
server {
listen 80;
server_name bot.example.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;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}Enable it, then test syntax before reloading.
sudo ln -s /etc/nginx/sites-available/openclaw /etc/nginx/sites-enabled/openclaw
sudo nginx -t
sudo systemctl reload nginxOn AlmaLinux and Rocky Linux, create the file in /etc/nginx/conf.d/openclaw.conf with the same server block, then run sudo nginx -t and reload Nginx.
Issue a certificate with Certbot
Point DOMAIN_NAME at the VPS first. After DNS resolves, install Certbot and request HTTPS.
sudo apt install -y certbot python3-certbot-nginxor on RHEL-family systems:
sudo dnf -y install certbot python3-certbot-nginxThen run:
sudo certbot --nginx -d bot.example.comChoose the redirect option when prompted. Afterward, confirm renewal works.
sudo certbot renew --dry-runBuild the retrieval path with pgvector and Redis
At this point, your app should start, but a useful AI deployment also needs retrieval and queue checks. In practice, that means your ingestion job writes embeddings to PostgreSQL, Redis tracks jobs or rate limits, and the web app calls the local backend rather than a remote demo service.
Your smoke test should cover three things: one document ingest, one vector lookup, and one response from the public HTTPS endpoint. Here is a minimal example flow you can adapt to your app endpoints.
curl -I https://bot.example.com
curl -X POST https://bot.example.com/api/health
curl -X POST https://bot.example.com/api/ingest -H 'Content-Type: application/json' -d '{"text":"Hostperl supports VPS-based private AI deployments."}'You should get a 200 response from health and a successful ingest result. If your app exposes a query endpoint, test it next.
curl -X POST https://bot.example.com/api/chat -H 'Content-Type: application/json' -d '{"message":"Where is my knowledge stored?"}'For teams watching token spend, a smaller chat model and cached retrieval answer often cuts usage more than expected. That is one reason customers compare VPS-based hosting with serverless alternatives such as Vercel, Netlify, Render, and Railway before launch.
Lock down secrets, logs, backups, and rollback
Private AI hosting needs simple, auditable habits. Keep secrets in environment files, avoid printing API keys to logs, and snapshot the database before major prompt or schema changes. For a practical restore mindset, see VPS Backup Testing: How to Trust Your Restore Plan.
Use these checks weekly.
- Run
sudo systemctl status openclaw-web openclaw-worker nginx postgresql redis-server. - Inspect
sudo journalctl -u openclaw-web -n 100after releases. - Take a PostgreSQL backup with
pg_dump openclaw > openclaw-$(date +%F).sql. - Test a restore on a spare VPS before you trust the backup.
- Rotate API keys if a contractor or temporary admin leaves the project.
If you serve customers in New Zealand, Australia, or wider APAC, a Hostperl VPS keeps the data path closer to your users and support team. That usually reduces latency and makes privacy reviews easier than routing every request through a distant serverless region.
For private bots, RAG apps, and customer-service automations, Hostperl gives you a clearer operational path than a black-box serverless stack. Start with a Hostperl VPS hosting plan and keep your deployment, data, and logs in one place. If you want a more managed path, compare it with Hostperl shared hosting for lighter WordPress or content sites that support your AI workflow.
Troubleshooting the most common failures
Nginx returns 502 Bad Gateway
Run this on the VPS.
sudo systemctl status openclaw-web --no-pager
sudo journalctl -u openclaw-web -n 50 --no-pagerIf the app crashed, fix the missing env var, bad build, or wrong port, then restart with sudo systemctl restart openclaw-web.
pgvector or database connection errors
Check the database and extension.
sudo -iu postgres psql -d openclaw -c "\dx"
sudo -iu postgres psql -d openclaw -c "SELECT now();"If vector is absent, install the package or use a PostgreSQL build that includes it.
Certificate issuance fails
Confirm DNS points to the VPS and port 80 is reachable.
dig +short bot.example.com
sudo ss -ltnp | grep ':80\|:443'Fix the DNS record or firewall rule, then rerun Certbot.
Redis or worker jobs keep restarting
Check the worker logs and the Redis service.
sudo systemctl status redis-server --no-pager
sudo journalctl -u openclaw-worker -n 50 --no-pagerMost failures come from a bad queue URL or a missing dependency in the worker environment.
Final checks from server and client
On the VPS, confirm the whole stack is listening and enabled.
sudo systemctl is-enabled openclaw-web openclaw-worker nginx postgresql redis-server
sudo ss -ltnp | grep -E ':80|:443|:3000|:5432|:6379'From your local computer, test the public site and one functional endpoint.
curl -I https://bot.example.com
curl -X POST https://bot.example.com/api/chat -H 'Content-Type: application/json' -d '{"message":"Summarize our hosting setup in one sentence."}'If both commands succeed, your OpenClaw AI app hosting on VPS setup is ready for real traffic. The result is a private deployment with clearer costs, simpler rollback, and better control over data residency than most serverless alternatives, which is why many teams start here and scale from there.
FAQ
Is pgvector enough for a small RAG app?
Yes. For modest document sets and a single app, PostgreSQL with pgvector is usually enough. Add Redis for queues and caching, then revisit Qdrant or a separate vector store only when growth demands it.
Should I use Vercel or a VPS for private AI bots?
Use Vercel for front-end convenience, but a VPS gives you better control over logs, secrets, background jobs, and data location. That matters for support bots and internal workflows.
How do I reduce API spend?
Cache retrieval results, limit prompt size, use a smaller model for routine answers, and store repeated responses in Redis. The savings are often visible within the first billing cycle.
Can Hostperl help if I need to migrate later?
Yes. Hostperl customers often start on a VPS, then move to larger VPS or dedicated resources as usage grows. That path is easier when the app already uses Nginx, systemd, and a clear backup plan.
For buyers who want a supportable base for AI apps, Hostperl VPS is the right starting point. It gives you room for pgvector, webhooks, workers, and APAC-friendly deployments without forcing you into a serverless model that is harder to audit.
