VPS Pilot is a server monitoring and management platform designed for private VPS servers.
It provides real-time monitoring, alerting, and project management (run declared commands, read logs, back up) β all from a single dashboard. Agents dial out to the hub, so your servers need no open ports.
- A lightweight Rust agent (agent/) on each node (server), enrolled with a one-time join token
- Agents send system metrics to the central server over TLS (protocol):
- CPU usage
- Memory usage
- Network statistics
- Disk usage of the root filesystem
- Metrics are visualized in the dashboard with selectable time ranges:
- 5 minutes, 15 minutes, 1 hour, 1 day, 2 days, 7 days
- Real-time updates via WebSocket connection
- Interactive charts with historical data
- Configure alerts based on metric thresholds
- Multiple notification channels supported:
- Discord β
- Email β
- Slack β
- Alert conditions on CPU, memory, disk and network
- Alert history and tracking
- Each node can have multiple projects; each needs a
config.vpspilot.jsonin its directory - Agents find these files under their project directories (
--projects-dir, default/var/wwwand/home, 4 levels deep) and report them to the hub - Per node, in Projects β Scan settings: automatic scan on/off, scan interval, Rescan now, and the problems from the last scan (broken configs, rejected paths)
- Projects β Add project points a node's agent at a directory the search doesn't reach. The agent only accepts it inside its project directories unless started with
--allow-any-project-path - Run a command declared in the file from the project page, with live output and a history of every run. The agent runs it as the owner of
config.vpspilot.json - Read the files in the log folders the file declares from the project page, and follow one live. The agent reads them as the owner of
config.vpspilot.json - Back up the folders, env file and database dump the file declares into a zip on the server, on a schedule set in the file or with Back up now, and optionally upload it to S3-compatible storage. The agent backs up as the owner of
config.vpspilot.json
Sample config.vpspilot.json:
{
"name": "meta ads dashboard",
"tech": ["laravel", "react", "mysql"],
"logs": ["storage/logs"],
"commands": [
{ "name": "node build", "command": "npm run build" },
{ "name": "php build", "command": "composer install" }
],
"backups": {
"env_file": ".env",
"zip_file_name": "project_backup",
"database": {
"connection": "DB_CONNECTION",
"host": "DB_HOST",
"port": "DB_PORT",
"username": "DB_USERNAME",
"password": "DB_PASSWORD",
"database_name": "DB_DATABASE"
},
"dir": [
"storage/app",
"database/companies"
],
"schedule": "daily",
"at": "03:00",
"local_dir": "../backups/meta-ads",
"retention_days": 7,
"s3": {
"access_key": "S3_ACCESS_KEY",
"secret_key": "S3_SECRET_KEY",
"bucket": "my-backups",
"region": "us-east-1",
"endpoint": "https://us-east-1.linodeobjects.com",
"prefix": "meta-ads/"
}
}
}The database and s3 keys are the names of variables in env_file, so passwords and keys stay on the server. Every field is described in the projects docs.
- Cron jobs declared per project in
config.vpspilot.json, run by the agent - The last run of each job and its output in the dashboard
- Status: planned for v0.6.0
| Component | Technology |
|---|---|
| Agent | Rust |
| Central Server | Golang |
| Dashboard | React + Vite |
| Database | SQLite (dual DB) |
| Deployment | Single executable |
- Operational DB: Users, nodes, alerts, projects, command runs, backup runs
- Timeseries DB: Metrics data (CPU, Memory, Network stats)
- Embedded UI: React app bundled into Go binary
- Agent channel: TLS server that receives metrics from enrolled agents (default port
55001) - HTTP/WebSocket: REST API + real-time data streaming (default port
8080)
git clone https://github.com/sanda0/vps_pilot.git
cd vps_pilotThe build.sh script (or make build) installs dashboard dependencies, builds the UI into the Go binary, and builds the agent.
chmod +x build.sh
./build.shWhat it does:
- Installs dashboard dependencies with bun (if needed)
- Builds the dashboard straight into
server/cmd/app/dist/ - Compiles the Go binary with the UI embedded
- Builds the agent with cargo (skipped if cargo isn't installed)
Output: server/vps_pilot (hub) and agent/target/release/vps-pilot-agent (agent)
cd server
cp .env.example .envThen open .env and set at least TOKEN_SECRET:
openssl rand -hex 32 # paste the output as TOKEN_SECRETThe other settings (DB_PATH, TOKEN_LIFESPAN, COOKIE_SECURE, TCP_SERVER_PORT, SMTP for email alerts) are explained in server/.env.example.
Migrations run automatically on startup, but you can also run them manually:
cd server
./vps_pilot -migrateThen create your admin account:
./vps_pilot -create-superuserFollow the interactive prompts to set a username and password.
cd server
./vps_pilotBy default the server listens on port 8080. To use a different port:
./vps_pilot -port 9090Open your browser: http://localhost:8080
Log in with the credentials you created in step 4.
In the dashboard, open Nodes β Add node, copy the install command and run it on the server. It downloads the agent for the server's architecture, checks it against SHA256SUMS, and installs it as a systemd service. Each release also has a .deb, and you can run the binary by hand:
VPS_PILOT_TOKEN=vpsp1.β¦ ./vps-pilot-agent --hub your-hub.example.comThe agent enrolls, saves its credentials to /var/lib/vps-pilot-agent/state.json, and doesn't need the token again. It dials out to the hub's agent port (55001), so the server needs no open ports. See the agent docs and agent/README.md for options and exit codes.
All flags are passed directly to the vps_pilot binary:
| Flag | Default | Description |
|---|---|---|
-port |
8080 |
HTTP server port |
-agent-port |
55001 |
Agent channel (TLS) port; also TCP_SERVER_PORT |
-agent-tls-cert / -agent-tls-key |
self-signed in $DB_PATH/tls |
Your own certificate for the agent channel |
-migrate |
β | Run database migrations and exit |
-create-superuser |
β | Create an admin user interactively and exit |
-create-makefile |
β | Generate a Makefile in server/ and exit |
Examples:
# Run on a custom port
./vps_pilot -port 3000
# Only run migrations (no server started)
./vps_pilot -migrate
# Create an admin user
./vps_pilot -create-superuserFrom the repo root (make help lists every task):
cp server/.env.example server/.env # then set TOKEN_SECRET
make install migrate superuser # one-time setup
make dev # hub on :8080 (hot reload with air) + dashboard on http://localhost:5173
make agent VPS_PILOT_TOKEN=vpsp1... # run a local agent; later runs are just `make agent`
make agent PROJECT_DIRS=~/vpspilot-demo # look for projects only there (default: /var/www,/home)
make agent-reset # forget the local agent's enrollment
make lint test # before pushingThe website and docs at vpspilot.dev live in site/ and are built with Hugo v0.167.0 (the standard edition is enough; no Node needed). On Ubuntu, install that exact version from the release:
curl -fsSLO https://github.com/gohugoio/hugo/releases/download/v0.167.0/hugo_0.167.0_linux-amd64.deb
sudo apt install ./hugo_0.167.0_linux-amd64.debThen make site-dev previews it at http://localhost:1313 and make site-build builds it into site/public/. Pushes to main that touch site/ deploy it to GitHub Pages.
Configure in .env:
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=your-email@gmail.com
MAIL_PASSWORD=your-app-password
MAIL_FROM_ADDRESS=noreply@example.com- Go to your Slack workspace β Apps β Incoming Webhooks
- Create a new webhook for your desired channel
- Copy the webhook URL and paste it in the alert configuration in the dashboard
- Go to your Discord server settings β Integrations β Webhooks
- Create a new webhook for your desired channel
- Copy the webhook URL and paste it in the alert configuration in the dashboard
vps_pilot/
βββ agent/ # Rust agent (one per server)
βββ client/ # React + Vite dashboard (built into server/cmd/app/dist)
β βββ src/
β βββ components/ # Reusable UI components
β βββ pages/ # Page components
β βββ hooks/ # Custom React hooks
β βββ lib/ # Utilities and API client
βββ server/ # Go backend
β βββ cmd/
β β βββ app/ # HTTP server + embedded UI
β β β βββ dist/ # Embedded UI files (generated, gitignored)
β β βββ cli/ # CLI tools (migrations, superuser)
β βββ internal/
β β βββ db/ # Database layer (SQLC + migrations)
β β βββ handlers/ # HTTP handlers
β β βββ services/ # Business logic
β β βββ middleware/ # HTTP middleware
β β βββ agentauth/ # Agent enrollment and keys
β β βββ tcpserver/ # Agent channel (TLS)
β β βββ utils/ # Utilities
β βββ data/ # SQLite databases (gitignored)
β βββ main.go # Entry point
β βββ vps_pilot # Compiled binary (gitignored)
βββ docs/ # Documentation, agent protocol
βββ build.sh # Full build script
βββ Makefile # Development tasks
βββ SCOPE.md # What VPS Pilot does and doesn't doDocker Compose setup will be available in a future release.
- Use a strong random
TOKEN_SECRET(openssl rand -hex 32) - Keep the
data/directory in a secure, backed-up location - Use HTTPS in production (put a reverse proxy like nginx or Caddy in front)
- Agents authenticate with a per-node key issued at enrollment; join tokens are single-use and expire after 1 hour
- Keep
data/tls/with the database: agents pin the hub certificate's fingerprint, so losing it means re-enrolling every agent - Optionally restrict TCP port
55001to your servers' IPs via firewall rules - Agents dial out to the hub; servers need no open ports
- The hub sends command names, never command strings: an agent only runs, reads or backs up what its project's
config.vpspilot.jsondeclares, as the owner of that file - Backup zips stay on the server and in the project's bucket; database passwords and S3 keys are read from the env file on the server, never sent to the hub
Build fails:
# Check the frontend builds cleanly
cd client && bun run build
# Check the Go code compiles
cd server && go build .Server won't start:
# Check if port 8080 is already in use
lsof -i :8080
# Check database directory permissions
ls -la server/data/
# Verify .env exists
ls -la server/.envUI doesn't load after build:
# Check that dist was copied into the server
ls server/cmd/app/dist/
# If missing, rebuild
./build.shMetrics not showing up:
- Ensure the agent is installed, enrolled (Nodes β Add node) and running on the target node
- If the agent exits with code
3, its credentials were rejected; re-enroll it from the node page - Check that TCP port
55001is open and reachable from the node - Verify the node is registered in the dashboard
- Real-time metrics collection (CPU, Memory, Network, Disk)
- WebSocket-based live updates
- Discord alert integration
- Email alert integration
- Slack alert integration
- SQLite dual-database architecture
- Embedded UI in single binary
- User authentication with JWT
- Authenticated agent enrollment + TLS on the agent channel
- Rust agent in this repo (
agent/) - Project discovery via
config.vpspilot.json(per-node scan settings, manual paths) - Run named project commands (declared in the config file only) with audit log
- Log tailing for declared log folders
- Project backups (database + directories)
- Cron jobs declared per project
- Install script + systemd unit for the agent
- Docker Compose deployment
- Multi-user support with roles
- Hub install script (Nginx or Apache, Let's Encrypt, systemd)
- Service monitoring (systemd units, alerts on failure)
- MCP server for Claude Code and Claude Desktop
- API documentation (Swagger)
- Mobile app
Contributions are welcome! Before you start:
- Read SCOPE.md: it lists what VPS Pilot does and what belongs in other tools.
- Keep pull requests under 1000 changed lines and each commit under 200, with one concern per pull request.
- Run
make lint testbefore pushing. - If your change affects users, add a line to CHANGELOG.md. RELEASING.md explains versions and releases.
Made with β€οΈ by Sandakelum
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0-only). Versions released before this change remain available under the MIT License.
- Website: https://vpspilot.dev
- Agent: agent/ Β· protocol
- Issues: https://github.com/sanda0/vps_pilot/issues
- Documentation: docs/
β Star this repo if you find it useful!