Advanced

Paste this guide into Claude Code and it will walk you through every step interactively.

VPS Setup Guide

What this gives you: AI agents that run 24/7 without your laptop being open. Morning briefings delivered before you wake up, automated reports, always-on assistants handling tasks around the clock. Your business works while you sleep.

Your laptop closes. Your AI agents keep working. This is how you set up a server that runs 24/7 so your automation stack never sleeps.

Why You Need a VPS

Running AI agents on your local machine is fine for testing. It is not fine for production. The moment you close your laptop, everything stops. Your morning briefing does not run. Your Telegram bot goes offline. Your cron jobs do not fire.

A VPS (Virtual Private Server) is a $10-20/month Linux machine that runs 24/7 in a data centre. It is always connected, always available, and you can SSH into it from anywhere in the world. Once your agents are deployed there, they operate independently of you. That is the point.

Beyond availability, a VPS gives you a clean environment. No conflicts with your local Node version. No "works on my machine" problems. You define the environment once, and it stays exactly that way.

Choosing a Provider

Two providers stand out for this use case:

ProviderStarting PriceRecommended SpecNotes
Hetzner~€4/mo4GB RAM, 2 vCPUBest value, EU-based
DigitalOcean~$6/mo4GB RAM, 2 vCPUMore tutorials, US-based

Minimum spec for running Claude Code agents: 4GB RAM, 2 vCPU, 40GB SSD. Claude CLI pulls models and caches context - you need headroom. If you are running more than 3 concurrent agents, go to 8GB RAM.

Operating system: Ubuntu 22.04 LTS. Do not overthink it. Every tutorial, every Stack Overflow answer, every tool assumes Ubuntu. Use it.

SSH Key Setup

Never log in with a password. SSH keys are faster, safer, and required if you want to automate deployments.

On your local machine, generate a key pair if you do not already have one:

# Generate an ED25519 key (faster and more secure than RSA) ssh-keygen -t ed25519 -C "your@email.com" # View your public key - this is what you add to the server cat ~/.ssh/id_ed25519.pub

When creating your VPS, paste your public key into the provider's SSH key field. If the server already exists, copy it manually:

# Copy your public key to the server ssh-copy-id root@YOUR_SERVER_IP # Or manually append it cat ~/.ssh/id_ed25519.pub | ssh root@YOUR_SERVER_IP "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

Now set up a shortcut in your SSH config so you never type the IP again:

# Edit ~/.ssh/config on your LOCAL machine Host my-vps HostName 187.77.176.54 User root IdentityFile ~/.ssh/id_ed25519 ServerAliveInterval 60 ServerAliveCountMax 3

Now you can SSH in with just: ssh my-vps

Create a Dedicated User (Never Run as Root)

Root has unlimited power. That means a single mistake - a bad script, a compromised package - can destroy the entire server. Create a dedicated user for your agent system and only use root when you absolutely must.

# SSH in as root first ssh my-vps # Create a dedicated user for your AI assistant adduser jarvis # Add to sudo group so it can install packages when needed usermod -aG sudo jarvis # Copy your SSH key to the new user mkdir -p /home/jarvis/.ssh cp /root/.ssh/authorized_keys /home/jarvis/.ssh/ chown -R jarvis:jarvis /home/jarvis/.ssh chmod 700 /home/jarvis/.ssh chmod 600 /home/jarvis/.ssh/authorized_keys

Update your SSH config to use this user going forward:

Host my-vps HostName 187.77.176.54 User jarvis IdentityFile ~/.ssh/id_ed25519
Tip: Name the user something meaningful. "jarvis" is fine if your agent system has a name. The key thing is: never do day-to-day operations as root.

Install Node.js, Bun, and pm2

SSH in as your new user and set up the runtime environment:

# Install nvm (Node Version Manager) for clean Node installs curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source ~/.bashrc # Install Node.js LTS nvm install --lts nvm use --lts # Install Bun (faster runtime, great for TypeScript bots) curl -fsSL https://bun.sh/install | bash source ~/.bashrc # Install pm2 globally - this keeps your processes alive npm install -g pm2 # Verify everything installed node --version bun --version pm2 --version

Then install the Claude CLI so your agents can actually run:

# Install Claude Code CLI npm install -g @anthropic-ai/claude-code # Authenticate (you'll need your Anthropic API key) claude auth

Directory Structure

A clean directory structure makes everything easier to maintain. Here is the layout that works well for a multi-agent system:

/home/jarvis/ ├── gateway/ # Main bot process (Telegram, Slack, etc.) │ ├── index.ts │ ├── router.ts │ └── package.json ├── agents/ # One file per specialist agent │ ├── general.md │ ├── linkedin.md │ ├── youtube.md │ ├── newsletter.md │ └── accountant.md ├── context/ # Shared context files injected into all agents │ ├── MEMORY.md │ ├── business-context.md │ └── client-context.md ├── data/ # Bash scripts that pull live data from APIs │ ├── stripe.sh │ ├── beehiiv.sh │ └── fireflies.sh ├── skills/ # Reusable workflows (markdown files) │ ├── write-shorts.md │ └── post-content.md ├── cron/ # Scheduled automation scripts │ ├── morning-briefing.sh │ └── weekly-content-plan.sh └── .env # ALL secrets live here, never in code
Warning: The .env file must never be committed to Git. Add it to .gitignore immediately. Store a backup of your secrets somewhere secure like a password manager - if you lose the .env file you will need to regenerate all API keys.

pm2 - Process Management

pm2 is what keeps your bot running after you close the SSH session. Without it, your process dies the moment you disconnect.

# Start your gateway bot cd /home/jarvis/gateway pm2 start index.ts --name jarvis-gateway --interpreter bun # Save the process list so it restores after reboot pm2 save # Generate and enable startup script (run as root, follow the output instructions) pm2 startup # View all running processes pm2 list # View live logs for a specific process pm2 logs jarvis-gateway # View the last 100 lines pm2 logs jarvis-gateway --lines 100 # Interactive monitoring dashboard pm2 monit # Restart a process (after code changes) pm2 restart jarvis-gateway # Stop everything pm2 stop all

After making code changes, the workflow is: pull from git, then restart the process:

cd /home/jarvis/gateway git pull origin main pm2 restart jarvis-gateway

Security Hardening

A public-facing server without hardening is a target. These steps take 15 minutes and prevent the vast majority of attacks.

Firewall with ufw

# Install ufw if not present sudo apt install ufw # Default: deny all incoming, allow all outgoing sudo ufw default deny incoming sudo ufw default allow outgoing # Allow SSH (critical - do this BEFORE enabling the firewall) sudo ufw allow ssh # Allow HTTP and HTTPS if you're running a web server sudo ufw allow http sudo ufw allow https # Enable the firewall sudo ufw enable # Check status sudo ufw status verbose

fail2ban - Block Brute Force Attacks

# Install fail2ban sudo apt install fail2ban # Create a local config (never edit the main one) sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local # Edit the local config sudo nano /etc/fail2ban/jail.local # Key settings to configure: # bantime = 3600 (ban for 1 hour) # findtime = 600 (10 minute window) # maxretry = 3 (3 failures = ban) # Start and enable fail2ban sudo systemctl start fail2ban sudo systemctl enable fail2ban

Disable Root Login and Password Auth

# Edit the SSH daemon config sudo nano /etc/ssh/sshd_config # Change these lines: PermitRootLogin no PasswordAuthentication no PubkeyAuthentication yes # Restart SSH daemon to apply changes sudo systemctl restart sshd
Warning: Before disabling root login and password auth, confirm you can successfully SSH in as your jarvis user with your key. If you lock yourself out, you will need to use the provider's emergency console to recover.

Monitoring: Disk, Memory, and Logs

Know what is happening on your server before problems become outages.

# Check disk usage df -h # Check memory usage free -h # Check running processes and CPU/memory htop # Check pm2 process health with live graph pm2 monit # Check system journal for errors sudo journalctl -xe --since "1 hour ago" # Disk usage by directory (find what's eating space) du -sh /home/jarvis/* | sort -hr

Log files from Claude Code agents can grow quickly. Set up log rotation to prevent disk filling up:

# Install pm2 log rotate module pm2 install pm2-logrotate # Configure: keep 7 days of logs, max 10MB per file pm2 set pm2-logrotate:max_size 10M pm2 set pm2-logrotate:retain 7 pm2 set pm2-logrotate:compress true
Tip: Set up a weekly cron job that checks disk usage and messages you if it goes above 80%. A single line of bash can save you from a server outage caused by full disk.

Environment Variables on the VPS

All your secrets live in /home/jarvis/.env. Load them into shell sessions and into pm2 processes:

# Add to ~/.bashrc so they load in every session export $(cat /home/jarvis/.env | grep -v '^#' | xargs) # For pm2 processes, use the --env flag or ecosystem file # Create ecosystem.config.js in your gateway directory: module.exports = { apps: [{ name: 'jarvis-gateway', script: 'index.ts', interpreter: 'bun', env_file: '/home/jarvis/.env' }] } # Start using the ecosystem file pm2 start ecosystem.config.js

Quick Deployment Checklist

  1. Provision server (4GB RAM minimum, Ubuntu 22.04)
  2. Generate SSH key locally, add to server
  3. Create dedicated user, copy SSH key
  4. Install Node.js via nvm, Bun, pm2, Claude CLI
  5. Set up directory structure under /home/jarvis/
  6. Clone your agent repo, create .env file
  7. Configure ufw firewall (SSH + any web ports)
  8. Install and configure fail2ban
  9. Disable root login and password auth
  10. Start processes with pm2, run pm2 save and pm2 startup
  11. Set up log rotation with pm2-logrotate
  12. Test: close your laptop, wait 5 minutes, check if the bot still responds

Want this set up for you?

I can provision and configure your entire VPS agent infrastructure in one session.

Book a Call
Next Guide
Building Jarvis: Multi-Agent System