AI Environment Documentation

Everything you need to know about your Virtual Works managed server.

SSH Access

Your server credentials are delivered in the welcome email. To connect:

ssh root@YOUR_SERVER_IP

We recommend setting up an SSH alias in ~/.ssh/config on your local machine:

# Add to ~/.ssh/config
Host myserver
    HostName YOUR_SERVER_IP
    User root
    IdentityFile ~/.ssh/id_rsa

Then connect with just ssh myserver.

Security: Never share your SSH private key. If you need to grant access to a team member, add their public key to /root/.ssh/authorized_keys on the server.

Stack Overview

Your AI Environment comes pre-configured with:

ComponentVersionNotes
Ubuntu22.04 LTSLong-term support, auto security updates
Node.js22.x LTSVia NodeSource repo
Nginx1.24+Reverse proxy, static file serving
PostgreSQL16Running on port 5432 (loopback only)
PM2LatestProcess manager with auto-restart
CertbotLatestAuto-renewing SSL via Let's Encrypt
Claude CodeLatestAI pair programmer in terminal
fail2banLatestSSH brute-force protection

Key Paths

PathPurpose
/var/www/Web root, one subdirectory per site
/etc/nginx/sites-available/Nginx site configs
/etc/nginx/sites-enabled/Symlinks to enabled configs
/opt/virtualworks-sms/Node.js API app (if included)
/root/backups/Daily database and file backups
/root/backup-vw.shBackup script (runs 2am daily)

Managing Services

Common PM2 Commands

pm2 list                  # show all running apps
pm2 restart myapp         # restart an app
pm2 logs myapp            # tail logs
pm2 logs myapp --lines 50 # last 50 log lines
pm2 stop myapp            # stop without removing
pm2 delete myapp          # remove from PM2
pm2 startup               # enable auto-start on reboot
pm2 save                  # persist current process list

Nginx Commands

nginx -t                   # test config for errors
systemctl reload nginx     # reload config (no downtime)
systemctl restart nginx    # full restart
systemctl status nginx     # check status

Adding a New Site

  1. Create the web root: mkdir -p /var/www/yourdomain.com
  2. Create an nginx config in /etc/nginx/sites-available/yourdomain.com
  3. Enable it: ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/
  4. Test and reload: nginx -t && systemctl reload nginx
  5. Issue SSL: certbot --nginx -d yourdomain.com -d www.yourdomain.com

Sample Nginx Config (Static Site)

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    root /var/www/yourdomain.com;
    index index.html;
    location / {
        try_files $uri $uri/ =404;
    }
}

Sample Nginx Config (Node.js Proxy)

server {
    listen 80;
    server_name api.yourdomain.com;
    location / {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

SSL Certificates

Certbot is pre-installed and auto-renews certificates twice daily. To issue a new cert:

certbot --nginx -d yourdomain.com -d www.yourdomain.com

Certbot modifies your nginx config automatically. To check renewal status:

systemctl status certbot.timer
certbot renew --dry-run

Database (PostgreSQL)

PostgreSQL runs locally on port 5432. Connect as the postgres superuser:

sudo -u postgres psql

To create a new database and user for your app:

sudo -u postgres psql
CREATE DATABASE myapp;
CREATE USER myapp_user WITH ENCRYPTED PASSWORD 'strongpassword';
GRANT ALL PRIVILEGES ON DATABASE myapp TO myapp_user;
\q
Tip: Store your DB credentials in a .env file in your app directory. Never hardcode passwords in source files.

Claude Code

Claude Code is a terminal-based AI pair programmer. Start it from any project directory:

cd /var/www/yourproject
claude

Claude Code can read, write, and edit files in the current directory. It understands your codebase and can implement features, fix bugs, write tests, and more.

Useful Commands Inside Claude Code

/help          # show available commands
/status        # show current project info
/clear         # clear conversation context
/cost          # show API usage this session
API Key: Claude Code requires an Anthropic API key in the environment. Set it in /etc/environment or your .env file as ANTHROPIC_API_KEY=sk-ant-...

OpenClaw Agent

OpenClaw is an automated AI agent that can run scheduled tasks on your server, such as SEO updates, content generation, and data processing. It is configured separately from Claude Code.

Important: Always configure OpenClaw to work in a development branch, not directly on production files. Merge changes after reviewing them to prevent unintended modifications to your live site.

Contact Virtual Works support to set up OpenClaw for your specific workflows.

SMS AI Configuration

The Virtual Works SMS AI assistant is configured per-business via a prompt stored in the businesses table. To update your AI's personality and knowledge:

  1. Log in to your admin panel
  2. Navigate to Settings → AI Prompt
  3. Edit the prompt to reflect your business's services, hours, pricing, and tone
  4. Save, changes take effect immediately

Prompt Best Practices

  • Include your business name, location, and primary services at the top
  • List pricing ranges so the AI can answer cost questions accurately
  • Include your hours and how to book appointments
  • Tell it what to do when it doesn't know the answer (e.g., "tell the customer to call us at...")

Backups

Daily automated backups run at 2am and are stored in /root/backups/YYYY-MM-DD/. Backups are retained for 7 days.

Each backup includes:

  • Full PostgreSQL database dump (db.sql.gz)
  • All web files in /var/www/
  • App source code from /opt/
  • Nginx configs from /etc/nginx/

To run a manual backup:

bash /root/backup-vw.sh

To restore a database backup:

gunzip -c /root/backups/2026-05-01/db.sql.gz | sudo -u postgres psql mydb

Troubleshooting

Site Not Loading

  1. Check nginx is running: systemctl status nginx
  2. Check nginx config: nginx -t
  3. Check nginx error log: tail -50 /var/log/nginx/error.log
  4. Check DNS is pointed to your server IP

Node.js App Crashed

pm2 logs myapp --lines 100  # see recent errors
pm2 restart myapp           # restart the app

Disk Space Full

df -h              # check disk usage
du -sh /root/backups/*  # check backup sizes
du -sh /var/log/nginx/* # check log sizes

Port Already in Use

lsof -i :3000      # find what's using port 3000
kill -9 PID        # kill the process (replace PID)

Support

VirtualWorks.ai Environment is managed by David Tolo. For help:

  • Text/call: (877) 268-1158
  • Email: david@virtualworks.ai
  • Hours: Mon, Fri, 9am, 6pm ET (emergencies handled promptly)
Fast response: Text is the fastest way to reach David. Describe what you're seeing and include any error messages.