A completely self-hosted, stealth server monitoring solution with ZERO cloud dependencies. All data stays on your infrastructure.
- No Cloud Services: Everything runs on your own hardware
- SQLite Database: Lightweight, file-based database
- Local API Server: Node.js/Express backend
- Complete Privacy: Your data never leaves your network
- Stealth Mode: No external connections or dependencies
- Real-time metrics (CPU, Memory, Disk, Network)
- System logs collection and analysis
- Alert system with configurable thresholds
- Remote command execution
- Security event monitoring
- Multi-server management
┌─────────────────┐
│ Web Dashboard │ (React - Port 5173)
│ localhost │
└────────┬────────┘
│
┌────────▼────────┐
│ API Server │ (Express - Port 3001)
│ localhost │
└────────┬────────┘
│
┌────────▼────────┐
│ SQLite Database │ (monitoring.db)
│ Local Storage │
└────────┬────────┘
│
┌────────▼────────┐
│ Monitored │ (Python Agents)
│ Servers │ Send metrics to API
└─────────────────┘
- Node.js 18+ and npm
- Python 3.7+ (for agents on monitored servers)
- Linux or macOS (Windows works with WSL)
-
Run the setup script:
chmod +x setup.sh ./setup.sh
-
Start the system:
chmod +x start.sh ./start.sh
-
Access the dashboard:
- Open http://localhost:5173 in your browser
That's it! The monitoring system is now running locally.
If you prefer manual setup:
npm install
cd server
npm install
cd ..cd server
npm run init-db
cd ..cd server
npm startThe backend will run on http://localhost:3001
npm run devThe dashboard will be available at http://localhost:5173
-
Click "Add Server" button
-
Enter server details:
- Name: Friendly name (e.g., "Production Server 1")
- Hostname: Server hostname
- IP Address: Server IP address
- OS Version: Operating system (e.g., "Ubuntu 22.04")
-
Copy the Server ID displayed after adding
-
Copy the agent script:
scp agent/server-agent.py user@target-server:/opt/
-
Install dependencies on target server:
ssh user@target-server sudo apt update sudo apt install python3 python3-pip -y pip3 install requests psutil
-
Configure the agent:
nano /opt/server-agent.py
Update these lines:
API_URL = "http://YOUR_MONITORING_SERVER_IP:3001/api" SERVER_ID = "YOUR_SERVER_ID_FROM_DASHBOARD"
-
Test the agent:
python3 /opt/server-agent.py
-
Setup automatic monitoring (optional):
crontab -e
Add this line to run every minute:
*/1 * * * * /usr/bin/python3 /opt/server-agent.py >> /var/log/server-agent.log 2>&1
Edit server/server.js to customize:
- Port (default: 3001)
- Database location
- CORS settings
Edit .env.local:
VITE_API_URL=http://localhost:3001/apiChange the URL if running on a different machine.
Edit agent/server-agent.py:
API_URL = "http://your-server-ip:3001/api"
SERVER_ID = "server-id-from-dashboard"Only allow access to port 3001 from your monitored servers:
sudo ufw allow from 192.168.1.0/24 to any port 3001
sudo ufw deny 3001For production, setup a reverse proxy with SSL:
server {
listen 443 ssl;
server_name monitor.yourdomain.local;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:5173;
}
location /api {
proxy_pass http://localhost:3001;
}
}Add basic authentication to the backend by modifying server/server.js:
app.use((req, res, next) => {
const auth = req.headers.authorization;
if (!auth || auth !== 'Bearer YOUR_SECRET_TOKEN') {
return res.status(401).json({ error: 'Unauthorized' });
}
next();
});Run the monitoring system on an isolated management network separate from production.
cp server/monitoring.db server/monitoring.db.backupcd server
sqlite3 monitoring.dbExample queries:
SELECT * FROM servers;
SELECT * FROM metrics ORDER BY timestamp DESC LIMIT 10;
SELECT * FROM alerts WHERE is_active = 1;cd server
rm monitoring.db
npm run init-dbcd server
rm -rf node_modules
npm install
npm startcd server
rm monitoring.db
npm run init-db- Check firewall allows port 3001
- Verify API_URL in agent is correct
- Test connectivity:
curl http://YOUR_SERVER_IP:3001/api/servers
- Check browser console for errors
- Verify backend is running (http://localhost:3001/api/servers)
- Check
.env.localhas correct API URL
Create /etc/systemd/system/monitor-backend.service:
[Unit]
Description=Server Monitoring Backend
After=network.target
[Service]
Type=simple
User=monitor
WorkingDirectory=/opt/monitoring/server
ExecStart=/usr/bin/node server.js
Restart=always
[Install]
WantedBy=multi-user.targetEnable and start:
sudo systemctl enable monitor-backend
sudo systemctl start monitor-backendnpm run buildServe the dist folder with nginx or any web server.
- Database: SQLite handles 100+ servers easily
- Memory: Backend uses ~50MB RAM
- CPU: Minimal (<1% on modern hardware)
- Storage: ~10MB per server per month (metrics)
Edit server/server.js to add automatic cleanup:
setInterval(() => {
db.prepare('DELETE FROM metrics WHERE timestamp < datetime("now", "-7 days")').run();
db.prepare('DELETE FROM logs WHERE timestamp < datetime("now", "-30 days")').run();
}, 86400000);Add alerts directly to database:
INSERT INTO alerts (id, server_id, type, severity, condition, threshold, message, is_active)
VALUES (
hex(randomblob(16)),
'YOUR_SERVER_ID',
'cpu',
'warning',
'CPU usage exceeds threshold',
80,
'CPU usage is above 80%',
1
);All endpoints available at http://localhost:3001/api:
GET /servers- List all serversPOST /servers- Add new serverDELETE /servers?id=ID- Remove serverGET /metrics?server_id=ID&limit=100- Get metricsPOST /metrics- Submit metricsGET /commands?server_id=ID- Get commandsPOST /commands- Create commandPUT /commands- Update commandGET /logs?server_id=ID- Get logsGET /alerts?server_id=ID- Get alertsPUT /alerts/:id/resolve- Resolve alertGET /security-events?server_id=ID- Get security eventsPUT /security-events/:id/resolve- Resolve event
This is a self-hosted solution. All code is open and available for inspection and modification.
MIT - Use freely for personal and commercial purposes.