Self-Host Hermes Agent on a VPS

12 min read·Matthieu·Hermes AgentAI AgentSelf-hostingDockerTelegramsystemd|

Deploy Nous Research's Hermes Agent on your own VPS with Docker sandboxing, Telegram messaging, and systemd persistence. Every command tested on a live server.

Hermes Agent runs locally on most dev machines. But local means offline when your laptop sleeps, no phone access, and no persistent workspace. Moving it to a VPS solves all three: the agent runs 24/7, you message it from Telegram, and it keeps its memory and skills between sessions.

This guide walks you through deploying Hermes Agent on a VPS from scratch. You will install it, connect an LLM provider, sandbox terminal commands in Docker, wire up Telegram, and run the whole thing as a systemd service that survives reboots. Every command was tested on an Ubuntu 24.04 VPS with 4 vCPU and 8 GB RAM.

Self-hosting AI agents on a VPS

What is Hermes Agent and why self-host it?

Hermes Agent is an open-source AI agent built by Nous Research. It connects to LLM providers (OpenRouter, Anthropic, Ollama, and others), executes terminal commands, browses the web, and remembers what it learns across sessions. It stores persistent memories, builds reusable skills from tasks it completes, and supports messaging gateways so you can talk to it from Telegram, Discord, Slack, WhatsApp, or Signal.

Self-hosting means your prompts and data stay on your server. No third-party agent platform sees your conversations. The agent runs continuously, builds context over time, and costs only VPS hosting plus the LLM API calls you make. On a $5-10/month VPS with OpenRouter, most developers spend under $20/month total.

What does Hermes Agent need to run on a VPS?

Hermes Agent needs a Linux server with at least 2 GB of RAM, 10 GB of free disk space, and Git installed. Docker is required if you want sandboxed terminal execution (you do). The installer handles Python 3.11+ and Node.js automatically.

Requirement Minimum Recommended
OS Ubuntu 22.04 / Debian 12 Ubuntu 24.04
RAM 2 GB 4 GB+
Disk 10 GB free 20 GB+ (Docker images)
CPU 1 vCPU 2+ vCPU
Prerequisites Git Git, Docker
Network Outbound HTTPS Outbound HTTPS

The agent itself is lightweight. Most RAM goes to Docker containers when executing commands. If you plan to run multiple concurrent sessions through the messaging gateway, aim for 4 GB or more.

Prerequisites

Before installing Hermes Agent, set up a non-root user and basic firewall. If you already have a secured VPS, skip to the installation section.

Create a dedicated user

SSH into your server as root and create a user for Hermes:

adduser hermes --disabled-password --gecos ""
usermod -aG sudo hermes

Give this user passwordless sudo (needed for Docker and service management):

echo "hermes ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/hermes
chmod 440 /etc/sudoers.d/hermes

Copy your SSH key so you can log in as this user:

mkdir -p /home/hermes/.ssh
cp ~/.ssh/authorized_keys /home/hermes/.ssh/
chown -R hermes:hermes /home/hermes/.ssh
chmod 700 /home/hermes/.ssh
chmod 600 /home/hermes/.ssh/authorized_keys

From now on, work as the hermes user:

su - hermes

Install Docker

Hermes Agent uses Docker to sandbox terminal commands. Install it from Docker's official repository:

sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin

Add the hermes user to the docker group so it can run containers without sudo:

sudo usermod -aG docker hermes
newgrp docker

Verify Docker works:

docker run --rm hello-world

You should see "Hello from Docker!" in the output. This confirms Docker can pull images and run containers.

Configure the firewall

Install UFW and set it up to allow only SSH and block everything else by default:

sudo apt-get install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw --force enable

Verify the rules:

sudo ufw status verbose

The output should show SSH allowed and all other incoming traffic denied. The Hermes gateway makes outbound connections to Telegram's API, so no inbound ports need to be opened for messaging.

How do I install Hermes Agent on Ubuntu?

Hermes Agent installs with a single command that handles Python, Node.js, and all dependencies. Run it as the hermes user, not root.

First, verify the installer script before piping it to bash. Download it, review it, then execute:

curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh -o /tmp/hermes-install.sh
less /tmp/hermes-install.sh

Review the script. It installs Python 3.11+ via uv, Node.js, and the hermes CLI. When you are satisfied:

bash /tmp/hermes-install.sh

Reload your shell to pick up the new hermes command:

source ~/.bashrc

Verify the installation:

hermes --version

You should see version and environment info:

Hermes Agent v0.4.0 (2026.3.18)
Project: /home/hermes/.hermes/hermes-agent
Python: 3.11.15
...

Run the diagnostic tool to check for missing dependencies:

hermes doctor

Look for green checkmarks in the output. Warnings about unconfigured API keys (OpenRouter, Browserbase, etc.) are expected at this point. You will configure your LLM provider next. Red items about Python, Git, or Docker need fixing before you continue.

How do I configure the LLM provider?

Hermes Agent needs an LLM provider to function. It does not include a model. You connect it to a provider API and pay per token. OpenRouter gives you access to 200+ models through a single API key and is the fastest way to get started.

Create an account at openrouter.ai and generate an API key.

The installer created ~/.hermes/.env with a full template. First, lock down its permissions:

chmod 600 ~/.hermes/.env

Open the file and set your API key on the OPENROUTER_API_KEY= line:

nano ~/.hermes/.env

Find the line OPENROUTER_API_KEY= and add your key after the = sign. Save and exit (Ctrl+X, then Y, then Enter).

Set the default model:

hermes config set model.provider openrouter
hermes config set model.default anthropic/claude-sonnet-4

Verify the file is not readable by other users:

ls -la ~/.hermes/.env

The permissions should show -rw------- (600). Only the hermes user can read this file.

Option 2: Custom OpenAI-compatible endpoint

If you run your own inference server (Ollama, vLLM, llama.cpp) or use another provider:

echo 'OPENAI_BASE_URL=http://localhost:11434/v1' >> ~/.hermes/.env
echo 'OPENAI_API_KEY=ollama' >> ~/.hermes/.env
echo 'LLM_MODEL=llama3.1:70b' >> ~/.hermes/.env

LLM provider comparison

Provider Env Variable Cost Notes
OpenRouter OPENROUTER_API_KEY Per-token, varies by model 200+ models, single key
Anthropic ANTHROPIC_API_KEY Per-token Direct Claude access
Ollama (local) OPENAI_BASE_URL + OPENAI_API_KEY Free (self-hosted) Needs GPU VPS for good speed
vLLM OPENAI_BASE_URL + OPENAI_API_KEY Free (self-hosted) GPU required

Test that the LLM connection works:

hermes -m "What is 2+2? Reply with just the number."

If you get a response, the provider is configured correctly. If you see an authentication error, double-check your API key in ~/.hermes/.env.

How do I sandbox Hermes Agent with Docker?

By default, Hermes Agent executes terminal commands directly on the host. On a VPS, this is a security risk. If the LLM generates a destructive command, it runs on your actual server. Docker sandboxing isolates all command execution inside a container.

Set Docker as the terminal backend:

hermes config set terminal.backend docker

Configure the Docker image and resource limits in ~/.hermes/config.yaml:

hermes config set terminal.docker_image "nikolaik/python-nodejs:python3.11-nodejs20"
hermes config set terminal.container_cpu 1
hermes config set terminal.container_memory 2048
hermes config set terminal.container_persistent true

What these settings do:

  • docker_image: The base image for the sandbox. This one includes Python and Node.js, covering most developer tasks.
  • container_cpu: Limits the container to 1 CPU core. Prevents a runaway process from starving your VPS.
  • container_memory: 2048 MB RAM limit for the container. Adjust up if you work with large datasets.
  • container_persistent: Keeps the container between commands. Faster execution because it skips container startup each time.

Verify the backend is set:

hermes config

In the Terminal section, you should see Backend: docker.

Terminal backend comparison

Backend Security Speed Use Case
local None. Commands run on host Fastest Local dev only. Never on a VPS
docker Container isolation Small startup overhead VPS deployments (recommended)
ssh Network isolation Network latency Execute on a different server

Configure approval mode

Hermes Agent has a built-in approval system that asks before running potentially dangerous commands. On a server, keep this enabled:

hermes config set approval_mode ask

The three modes:

  • ask: Prompts you before any command that modifies files, installs packages, or touches the network. Use this.
  • smart: An AI model assesses risk and only prompts for genuinely dangerous commands. Faster, but relies on the AI's judgment.
  • off: No checks. Every command runs immediately. Do not use this on a server.

How do I connect Hermes Agent to Telegram?

The messaging gateway lets you chat with Hermes from your phone. Telegram is the most common setup. The gateway makes outbound connections to Telegram's API, so you do not need to open any inbound ports on your firewall.

Step 1: Create a Telegram bot

Open Telegram and message @BotFather. Send these commands:

  1. /newbot
  2. Enter a name for your bot (e.g., "My Hermes Agent")
  3. Enter a username (must end in bot, e.g., myhermes_agent_bot)

BotFather replies with a bot token. It looks like 7123456789:AAHx.... Copy it.

Step 2: Get your Telegram user ID

Message @userinfobot on Telegram. It replies with your numeric user ID. Copy this number.

Step 3: Configure the gateway

Add the bot token and your user ID to the environment file:

echo 'TELEGRAM_BOT_TOKEN=7123456789:AAHxYourTokenHere' >> ~/.hermes/.env
echo 'TELEGRAM_ALLOWED_USERS=your_numeric_user_id' >> ~/.hermes/.env

The TELEGRAM_ALLOWED_USERS variable is a security control. Only the user IDs listed here can interact with your bot. Without it, anyone who finds your bot can send it commands. Separate multiple IDs with commas.

Step 4: Test the gateway

Start the gateway in the foreground to verify it connects:

hermes gateway

Send a message to your bot in Telegram. You should see the message appear in the terminal and a response sent back. Press Ctrl+C to stop the gateway once you have confirmed it works.

If the bot does not respond, check:

  • The bot token is correct in ~/.hermes/.env
  • Your user ID is in TELEGRAM_ALLOWED_USERS
  • The VPS can reach api.telegram.org on port 443 (outbound HTTPS)

Other supported platforms include Discord, Slack, WhatsApp, Signal, and Email. Run hermes gateway setup for an interactive wizard that configures any of them.

How do I run Hermes Agent as a systemd service?

Running hermes gateway in a terminal session means it stops when you disconnect. A systemd user service keeps the gateway running after logout and restarts it automatically if it crashes or the server reboots.

Install the service

Hermes provides a built-in command to install the gateway as a systemd user service:

hermes gateway install

This creates a service file at ~/.config/systemd/user/hermes-gateway.service and enables lingering automatically. Lingering keeps user services running after you log out of SSH. Without it, systemd would kill the gateway when your session ends.

Start the service and enable it for boot:

systemctl --user enable --now hermes-gateway

The enable makes it start on boot. The --now flag starts it immediately. Always use both together.

Verify the service is running:

systemctl --user status hermes-gateway

Sharp eyes: look for Active: active (running) in the output. If it says failed, check the logs.

Check the logs

View live gateway logs:

journalctl --user -u hermes-gateway -f

Press Ctrl+C to stop following. The gateway logs show every incoming message, LLM call, and tool execution.

Set the working directory

By default, the gateway uses the home directory as its workspace. Set a dedicated project directory:

echo 'MESSAGING_CWD=/home/hermes/projects' >> ~/.hermes/.env
mkdir -p /home/hermes/projects

Restart the service to apply:

systemctl --user restart hermes-gateway

How do I back up Hermes Agent data?

Hermes stores all its state in ~/.hermes/. This directory contains memories, learned skills, session history, configuration, and cron jobs. Losing it means the agent forgets everything.

Key paths:

Path Contents
~/.hermes/config.yaml Configuration
~/.hermes/.env API keys and secrets
~/.hermes/memories/ Persistent agent memories
~/.hermes/skills/ Agent-created reusable skills
~/.hermes/sessions/ Gateway session history
~/.hermes/cron/ Scheduled jobs
~/.hermes/SOUL.md Agent identity/persona

Create a backup script:

cat > /home/hermes/backup-hermes.sh << 'SCRIPT'
#!/bin/bash
BACKUP_DIR="/home/hermes/backups"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
mkdir -p "$BACKUP_DIR"
tar czf "$BACKUP_DIR/hermes-$TIMESTAMP.tar.gz" \
  --exclude='*.log' \
  -C /home/hermes .hermes/
# Keep only the last 7 backups
ls -t "$BACKUP_DIR"/hermes-*.tar.gz | tail -n +8 | xargs -r rm
echo "Backup saved: $BACKUP_DIR/hermes-$TIMESTAMP.tar.gz"
SCRIPT
chmod 700 /home/hermes/backup-hermes.sh

Run it daily with a cron job:

(crontab -l 2>/dev/null; echo "0 3 * * * /home/hermes/backup-hermes.sh") | crontab -

Verify the cron entry:

crontab -l

You should see the backup job scheduled at 03:00 daily. The script keeps 7 days of backups and removes older ones.

For off-server backups, rsync the backup directory to another machine or object storage. Keeping backups only on the same VPS does not protect against disk failure.

How do I update Hermes Agent?

Hermes Agent includes a built-in update command. Before updating, back up your data.

/home/hermes/backup-hermes.sh
hermes update

Verify the new version:

hermes --version

Check for any configuration changes needed after the update:

hermes config migrate
hermes doctor

config migrate adds new configuration options with their defaults. hermes doctor checks that everything still works after the update.

Restart the gateway service to run the new version:

systemctl --user restart hermes-gateway
systemctl --user status hermes-gateway

If something breaks after an update, restore from backup:

systemctl --user stop hermes-gateway
tar xzf /home/hermes/backups/hermes-YYYYMMDD-HHMMSS.tar.gz -C /home/hermes/
systemctl --user start hermes-gateway

Security hardening checklist

A VPS-hosted AI agent that executes terminal commands needs attention to security. Here is a summary of what this guide already configured and a few additional steps.

Already configured in this guide:

  • Non-root user (hermes) with dedicated home directory
  • Docker sandboxing for all terminal command execution
  • UFW firewall denying all inbound traffic except SSH
  • API keys in ~/.hermes/.env with 600 permissions
  • TELEGRAM_ALLOWED_USERS restricting bot access to your user ID
  • approval_mode: ask requiring confirmation for dangerous commands

Additional hardening:

Disable the local terminal backend entirely by verifying your config:

hermes config

In the Terminal section, confirm Backend says docker, not local.

Set resource limits on the Docker containers to prevent a runaway process from consuming all server resources. This was configured earlier with container_cpu and container_memory.

Review the agent's learned skills periodically:

ls -la ~/.hermes/skills/

Skills are scripts the agent writes and reuses. Audit them like you would any code running on your server.

Monitor gateway logs for unexpected users or unusual activity:

journalctl --user -u hermes-gateway --since "1 hour ago" --no-pager

Troubleshooting

The gateway fails to start:

journalctl --user -u hermes-gateway -n 50 --no-pager

Common causes: invalid bot token, missing API key, Docker not running. Check that Docker is active with systemctl status docker.

Telegram bot does not respond:

Verify the bot token and allowed users are set:

grep TELEGRAM ~/.hermes/.env

Test outbound connectivity:

curl -s https://api.telegram.org/bot<YOUR_TOKEN>/getMe

A valid response with your bot's info confirms the token and network are working.

Docker permission denied:

groups

The output must include docker. If not, re-run sudo usermod -aG docker hermes and log out/in.

hermes command not found after install:

source ~/.bashrc

If still missing, check if ~/.local/bin is in your PATH:

echo $PATH | tr ':' '\n' | grep local

High memory usage:

Check Docker container resource consumption:

docker stats --no-stream

Lower the container_memory setting if containers use too much RAM.

Cost breakdown

Self-hosting Hermes Agent on a VPS costs the server plus LLM API usage. Here is a realistic estimate for a solo developer.

Item Monthly Cost
VPS (2 vCPU, 4 GB RAM) $5-10
OpenRouter API (moderate use, ~500K tokens/day) $5-15
Docker overhead Included in VPS
Telegram gateway Free
Total $10-25/month

Managed AI assistant subscriptions run $20-200/month. Self-hosting costs less and keeps your data on your own server.

Run Claude Code on a VPS


Copyright 2026 Virtua.Cloud. All rights reserved. This content is original work by the Virtua.Cloud team. Reproduction, republication, or redistribution without written permission is prohibited.

Ready to try it yourself?

Deploy your own server in seconds. Linux, Windows, or FreeBSD.

See VPS Plans