Hermes Agent Dashboard: VPS Setup with Nginx Reverse Proxy
Deploy your Hermes agent dashboard securely on a VPS with nginx reverse proxy and authentication. Complete guide to expose the control plane safely to your team.
- The Hermes dashboard listens on localhost:9119 by default and requires a reverse proxy (nginx) plus authentication to expose it safely to your team on a VPS.
- Set up nginx with SSL via Let us Encrypt (Certbot) and Basic Auth or OAuth to keep the dashboard encrypted and access-controlled without paying for managed hosting.
- Use systemd to run the dashboard persistently; it auto-restarts after crashes and survives reboots.
- For teams larger than 5 people or those needing compliance, managed hosting (Opsily) eliminates ops burden but costs $50-200/month versus $5/month for DIY.
The Hermes agent dashboard is a browser-based control plane that runs on your local machine or VPS at port 9119. It replaces YAML configuration editing with a visual interface for managing profiles, API keys, skills, scheduled tasks, and real-time chat. By default it only listens on 127.0.0.1, but you can expose it to your team securely via a reverse proxy and authentication layer.
What Is the Hermes Dashboard?
The Hermes dashboard is a web UI shipped with the open source Hermes Agent (259.5K GitHub stars). It transforms the CLI-only experience into a clickable control plane. Instead of editing YAML files by hand or running hermes commands in a terminal, you open a browser, log in, and manage everything visually.
Key features include config management for creating and switching profiles without restarting, API key storage and rotation for external integrations, a skills library to browse and configure installed skills, cron job scheduling for agent tasks like backups and data syncs, session logs for viewing and replaying past conversations, a browser-based chat tab that runs the TUI via WebSocket, and profile switching to jump between dev, staging, and prod environments without CLI commands.
When you run hermes dashboard, it starts a web server listening on 127.0.0.1:9119. Localhost-only binding is intentional: it prevents accidental network exposure before you have configured authentication. For a local machine, that is secure. For a VPS or shared infrastructure, you need a reverse proxy plus an auth layer to grant team access safely.
Quick Start: Local Dashboard Setup
If you already have Hermes installed, starting the dashboard is one command. Run hermes doctor first to verify your environment (Python version, dependencies, config path). The output tells you if something is missing.
Then hermes dashboard starts the web server. You will see output like Dashboard running at localhost:9119. Open that URL in your browser. You are now in the dashboard. You can manage profiles, edit API keys, view logs, and use the browser-based chat tab.
The dashboard process runs in the foreground (blocking your terminal). If you close the terminal, it stops. To keep it running after you close the terminal, you need process management, which we cover in the systemd section below. For now, understand that the dashboard is running locally on port 9119, and only processes on that machine can reach it.
Before deploying to a VPS, ensure you have completed the base installation. If you have not, follow the guide on Hermes agent installation to set up the CLI first. The dashboard assumes Hermes is already installed and configured.
Deploying to a VPS: The Network Exposure Problem
Running Hermes locally on your laptop is one thing. Running it on a shared VPS where your team needs access is different. Here is the problem: By default, the dashboard listens only on 127.0.0.1. That is the loopback address, meaning only processes on that machine can reach it. Even if you ssh into the VPS, you cannot access the dashboard directly because it is not bound to a public IP or internal network interface.
You have three options. First, SSH tunnel using ssh -L 9119:localhost:9119 works, but is a manual step every session and not scalable for teams. Second, bind to 0.0.0.0 with --insecure flag opens the dashboard to anyone on the network who guesses your URL. The --insecure flag is deprecated because it bypasses all authentication. Never use it in production. Third, a reverse proxy plus authentication is the professional setup: run the dashboard on localhost, put nginx or Apache in front, add SSL plus auth layer.
We will use option three. The flow is: your VPS runs Hermes dashboard on 127.0.0.1:9119 (internal, unencrypted), nginx listens on 0.0.0.0:443 (public, encrypted TLS), nginx validates authentication (OAuth, Basic Auth, or tokens), and nginx forwards approved requests to the dashboard. SSL certificates come from Let us Encrypt (free, automated with Certbot). This way, the dashboard is never exposed directly to the internet. nginx is the gatekeeper.
Setting Up a Reverse Proxy (Nginx)
Install nginx on your VPS:
sudo apt update
sudo apt install nginx
Edit the nginx config. Create a new file /etc/nginx/sites-available/hermes-dashboard. Replace dashboard.your-domain.com with your actual domain name. The config file needs two server blocks: one to redirect HTTP traffic (port 80) to HTTPS, and one for the secure HTTPS listener (port 443).
The HTTP redirect server block should listen on port 80 and use a location block to redirect all traffic to the HTTPS version of the same hostname.
server {
listen 80;
server_name dashboard.your-domain.com;
location / {
# Redirect all HTTP traffic to HTTPS
}
}
The HTTPS server block handles encrypted traffic on port 443:
server {
listen 443 ssl http2;
server_name dashboard.your-domain.com;
ssl_certificate /etc/letsencrypt/live/dashboard.your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dashboard.your-domain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
location / {
auth_basic "Hermes Dashboard";
auth_basic_user_file /etc/nginx/.htpasswd;
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_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Within the HTTPS location block, add the proxy_pass directive to forward requests to the dashboard service running on localhost at port 9119. The proxy_read_timeout and proxy_send_timeout directives are set to 3600s (one hour) to support long-lived WebSocket connections used by the browser chat interface.
Enable the site:
sudo ln -s /etc/nginx/sites-available/hermes-dashboard /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
Generate SSL certs using Certbot:
sudo apt install certbot python3-certbot-nginx
sudo certbot certonly --nginx -d dashboard.your-domain.com
Certbot will update the nginx config with cert paths and auto-renew every 90 days. For Basic Auth, create a password file:
sudo apt install apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd username
Repeat for each team member (or use the same password for all). Test the proxy: visit https://dashboard.your-domain.com in your browser. Enter the username and password. You should see the Hermes dashboard.
Common pitfalls: WebSocket timeout occurs if the chat tab disconnects after a few minutes; ensure proxy timeouts are set to 3600s or higher. Port forwarding issues arise if your firewall does not allow incoming HTTPS (port 443) and HTTP (port 80, for the redirect). Certificate renewal happens automatically with Certbot, but verify certbot renew --dry-run works.
Authentication and Access Control
Basic Auth (username plus password in nginx) is the simplest for small teams. Each user enters the same password, or you create separate.htpasswd entries. For larger teams or stricter control, use OAuth. Nous Research (the creators of Hermes) support OAuth through an identity provider. You configure the OAuth provider details in the Hermes config (API client ID, secret, redirect URL), then the dashboard hands off authentication to that provider.
In nginx, you would replace the auth_basic block with oauth2-proxy or similar, forwarding the authenticated user info to Hermes via headers. Session tokens: the dashboard stores a session token in your browser cookie after login. That token is valid for the duration of the session (24-48 hours by default, configurable). You do not re-authenticate on every request.
For a trusted internal network (VPN, private subnet), you can skip auth entirely and rely on firewall rules. Only allow inbound traffic from your office IP or VPN subnet. This is faster but less granular. Trade-off summary: Basic Auth is simple with no external dependencies but requires manual password management. OAuth offers centralized user management and integrates with Okta or Azure AD but is harder to set up. SSH tunnel requires no proxy but is manual per-session. Firewall-only is fastest but requires VPN or static IP and offers no user-level audit trail.
Keeping the Dashboard Running 24/7 (Systemd)
The hermes dashboard command runs in the foreground. If you close the terminal, it stops. For a production VPS, you need a process manager to restart it automatically after crashes or reboots. systemd is built into Linux. Create a user service file at ~/.config/systemd/user/hermes-dashboard.service:
[Unit]
Description=Hermes Agent Dashboard
After=network.target
[Service]
Type=simple
ExecStart=/home/hermes/.venv/bin/hermes dashboard
WorkingDirectory=/home/hermes
Environment="PATH=/home/hermes/.venv/bin"
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=hermes
[Install]
WantedBy=default.target
Load and start the service:
systemctl --user daemon-reload
systemctl --user enable hermes-dashboard
systemctl --user start hermes-dashboard
Check status:
systemctl --user status hermes-dashboard
journalctl --user-unit hermes-dashboard -f
The dashboard now restarts automatically if it crashes. It also starts on reboot (if you enable lingering):
sudo loginctl enable-linger $(whoami)
If you are running as root (not recommended), use /etc/systemd/system/ instead of ~/.config/systemd/user/. With systemd in place, the dashboard runs continuously, survives reboots, and logs all output to the journal for debugging.
Local vs. Managed Hosting: When to Switch to Opsily
Self-hosting the Hermes dashboard on a VPS saves money up front. You rent a VPS ($5-20/month), install Hermes, configure nginx, and manage updates yourself. Total cost is predictable and low.
But there are hidden costs. Time: you are responsible for SSL renewal, security patches, backup strategy, monitoring uptime, and debugging issues at 2 AM. Security: you must harden the VPS, manage firewall rules, rotate credentials, and audit access logs. Scaling: if dashboard performance degrades, you scale (add resources, load balance), which is complex. Compliance: if your team needs SOC 2 or HIPAA compliance, self-hosting requires you to document everything and pass audits.
Managed hosting (like Opsily's Hermes Agent hosting) shifts this burden. You get a pre-configured reverse proxy with no nginx setup and authentication built in, HTTPS by default with SSL management handled, automatic scaling with your usage, data residency in EU data centers if you need GDPR compliance, 24/7 uptime SLA with professional support, and regular backups with no manual work.
The trade-off is cost: managed hosting runs $50-200/month depending on usage, compared to $5/month for a DIY VPS. For a team of 2-3 people using Hermes casually, DIY VPS wins. For a team of 10 plus running Hermes as a production service, managed hosting pays for itself in reduced ops time. See Hermes Agent pricing for a cost breakdown and VPS provider comparison if you choose DIY.
Troubleshooting and Pro Tips
Dashboard will not start? Check Python version (python3 --version should be 3.8 or higher). Verify Hermes is installed (hermes --version). Restart systemd: systemctl --user restart hermes-dashboard.
Connection refused at reverse proxy? nginx is running but the dashboard is not. Verify dashboard is listening: netstat -an | grep 9119. If port 9119 is not in the list, restart the dashboard.
Chat tab disconnects? Increase proxy timeouts in nginx to 3600s. WebSocket connections are long-lived and nginx will timeout if set too low.
Basic Auth prompt loops? Ensure the.htpasswd file exists and is readable: sudo cat /etc/nginx/.htpasswd. Regenerate if needed.
Dashboard loads but buttons do not work? Clear your browser cache (Ctrl+Shift+Delete). Some versions cache JavaScript incorrectly.
Profile switching fails? Ensure the dashboard has write access to the config directory (~/.config/hermes by default). Check permissions: ls -la ~/.config/hermes/.
Pro tip: Use DNS failover. If your VPS provider supports it, configure a second Hermes instance on a different VPS and use round-robin DNS. If one goes down, the second picks up traffic. Pro tip: Backup your skills. Export your skills library regularly. If the dashboard or VPS fails, you can restore quickly. Use hermes skills export and commit to Git.
Frequently Asked Questions
What is the Hermes Web Dashboard?
A browser-based control plane for Hermes Agent, running on localhost:9119 by default. It replaces YAML editing with a clickable UI for managing profiles, API keys, skills, cron jobs, and session logs.
How do I start the Hermes dashboard?
Run hermes dashboard in your terminal. It opens on localhost:9119 by default. You must have Hermes installed first; see the installation guide for setup.
Is the Hermes dashboard secure by default?
Yes. It listens only on localhost (127.0.0.1), so it is not exposed to the network. For remote team access on a VPS, add a reverse proxy with authentication as described in this guide.
Can I run the Hermes dashboard in Docker?
Yes. Set HERMES_DASHBOARD=1 in your docker-compose environment and publish port 9119. The same reverse proxy and auth setup applies.
How do I access the Hermes dashboard on a VPS?
Use a reverse proxy (nginx) with HTTPS and Basic Auth or OAuth, as covered in the Setting Up a Reverse Proxy section. Do not use the --insecure flag, which is deprecated.
What does the browser Chat tab in the dashboard do?
It runs the Hermes TUI (terminal interface) over WebSocket, embedded in the browser using xterm.js. You can chat with your agent directly from the dashboard without using the CLI.
Can the Hermes dashboard manage multiple profiles?
Yes. Use the profile switcher in the UI to jump between Config, API Keys, Skills, Models, and Chat for different Hermes configurations (dev, staging, prod).
What is a control plane for AI agents?
An operations layer that handles scheduling, observability, credential management, session history, approval workflows, and config governance. The Hermes dashboard is your control plane for agent administration.
The Bottom Line
The Hermes agent dashboard turns agent management from a terminal affair into a visual, team-friendly interface. You now know how to run it locally, expose it securely on a VPS via nginx, and keep it running with systemd. The decision to self-host or use managed hosting depends on your team size and tolerance for operational overhead. For a quick cost and feature comparison, check out managed Hermes hosting on Opsily.