tutorial

Monitoring Cleavr-Managed Servers with Vigilmon

Cleavr deploys and manages web apps on your VPS — but the agent on each server, nginx/Caddy, PHP-FPM, PM2, databases, and SSL renewal can all fail independently. Here's how to monitor every layer with Vigilmon so you catch outages before they affect production traffic.

Cleavr is a server management platform that provisions VPS instances, deploys web apps (Node.js, PHP, Python, Go, static), and manages SSL certificates — an alternative to Forge or Ploi for teams that want a clean UI for non-Docker deployments. Each managed server runs a lightweight Cleavr agent that communicates with the SaaS control plane, plus nginx or Caddy, PHP-FPM, PM2, and managed databases. Any of these can fail without Cleavr's dashboard reflecting the true state immediately. Vigilmon fills that gap by continuously monitoring each layer from outside the control plane.

What You'll Set Up

  • HTTP monitor for each deployed web app (the most important check)
  • TCP monitor for the Cleavr agent on each managed server
  • Cron heartbeats for nginx/Caddy, PHP-FPM, PM2, and database processes
  • SSL certificate expiry monitor for each app domain
  • Disk space heartbeat for each managed server
  • Deployment webhook receiver health check
  • Alerting configuration for the full fleet

Prerequisites

  • One or more VPS instances managed by Cleavr with the Cleavr agent installed
  • Cleavr agent running on port 27001 on each server
  • Web apps deployed (nginx or Caddy as reverse proxy)
  • A free Vigilmon account

Step 1: Monitor Each Deployed Web App

The end-to-end HTTP check is the most valuable monitor — it verifies that nginx, the reverse proxy, the app process (PM2 or PHP-FPM), and the database are all working together. A single failing component anywhere in that chain causes this monitor to fail.

For each web app:

  1. Log in to vigilmon.online and click Add Monitor.
  2. Set Type to HTTP / HTTPS.
  3. Enter your app's domain: https://yourapp.com.
  4. Set Check interval to 1 minute.
  5. Set Expected HTTP status to 200.
  6. Enable Monitor SSL certificate with a 21-day expiry alert.
  7. Click Save.
# Verify manually
curl -I https://yourapp.com
# HTTP/2 200

If your app serves a health endpoint (e.g., /health, /ping, or /status), use that URL instead — it avoids auth redirects and returns a consistent response that doesn't depend on a logged-in session.


Step 2: Monitor the Cleavr Agent

The Cleavr agent (running on port 27001) is what the control plane uses to execute deployments, manage services, and collect server metrics. If the agent crashes or its port becomes unavailable, Cleavr's dashboard loses the ability to deploy to that server — but your running apps are unaffected, so you might not notice immediately.

  1. Click Add MonitorTCP Port.
  2. Set Host to your server's public IP or hostname.
  3. Set Port to 27001.
  4. Set Check interval to 2 minutes.
  5. Click Save.

Repeat for each managed server. Name the monitors Cleavr Agent - server1, Cleavr Agent - server2, etc.

# Quick check from your local machine
nc -zv your-server 27001 && echo "Agent reachable"

If the agent is firewalled to only Cleavr's IPs (recommended for security), use a cron heartbeat from the server itself instead:

# On the managed server — confirms the agent process is running
* * * * * root systemctl is-active --quiet cleavr-agent \
  && curl -s https://vigilmon.online/heartbeat/YOUR_AGENT_HEARTBEAT_ID

Step 3: Monitor nginx or Caddy

Cleavr provisions nginx or Caddy as the reverse proxy for all web apps. If the web server process crashes, every app on that server returns a connection refused error — the apps themselves are running but unreachable.

Add a cron heartbeat on each server:

#!/bin/bash
# /usr/local/bin/webserver-check.sh

# For nginx
if systemctl is-active --quiet nginx; then
  curl -s https://vigilmon.online/heartbeat/YOUR_NGINX_HEARTBEAT_ID
fi

# For Caddy (if using Caddy instead)
# if systemctl is-active --quiet caddy; then
#   curl -s https://vigilmon.online/heartbeat/YOUR_CADDY_HEARTBEAT_ID
# fi

Schedule in cron every minute:

# /etc/cron.d/webserver-check
* * * * * root /usr/local/bin/webserver-check.sh

In Vigilmon, create a Cron Heartbeat with a 1 minute expected interval and 2 minute grace period.

Note: The Step 1 HTTP monitor also catches nginx failures, but this heartbeat distinguishes nginx being down from the app process being down — useful for triage.


Step 4: Monitor PHP-FPM (for PHP Apps)

Cleavr manages PHP-FPM pools for PHP/Laravel applications. If PHP-FPM crashes, nginx receives a 502 Bad Gateway for every PHP request while the web server itself is healthy. This is one of the most common causes of 502 errors on PHP stacks.

#!/bin/bash
# /usr/local/bin/phpfpm-check.sh
# Check each PHP-FPM version you have installed

for VERSION in 8.1 8.2 8.3; do
  if systemctl is-active --quiet "php${VERSION}-fpm" 2>/dev/null; then
    curl -s "https://vigilmon.online/heartbeat/YOUR_PHPFPM_${VERSION//.}_HEARTBEAT_ID"
  fi
done

Schedule every minute and create a Cron Heartbeat per PHP-FPM version. If you only run one PHP version, simplify to a single check.

Pair with nginx's fastcgi_pass socket check for a more direct probe:

# Verify PHP-FPM socket is accepting connections
if php-fpm8.2 -t 2>/dev/null; then
  curl -s https://vigilmon.online/heartbeat/YOUR_PHPFPM_HEARTBEAT_ID
fi

Step 5: Monitor PM2 Processes (for Node.js Apps)

Cleavr uses PM2 to manage Node.js application processes. PM2 has a daemon that persists across reboots and a set of managed app processes under it. Two distinct failures exist: PM2 daemon crash (rare) and individual app process crash (more common, especially with memory leaks).

Monitor the PM2 daemon:

#!/bin/bash
# /usr/local/bin/pm2-check.sh

# Check if PM2 daemon is running
if pm2 list 2>/dev/null | grep -q "online"; then
  curl -s https://vigilmon.online/heartbeat/YOUR_PM2_HEARTBEAT_ID
fi

For per-app monitoring, check each app's PM2 status:

#!/bin/bash
# Check a specific app by PM2 name
APP_NAME="your-app-name"
STATUS=$(pm2 show "$APP_NAME" 2>/dev/null | grep status | awk '{print $4}')

if [ "$STATUS" = "online" ]; then
  curl -s https://vigilmon.online/heartbeat/YOUR_APP_PM2_HEARTBEAT_ID
fi

The end-to-end HTTP check from Step 1 catches most PM2 failures, but this heartbeat lets you distinguish a crashed app from a misconfigured reverse proxy.


Step 6: Monitor Managed Databases

Cleavr can provision and manage MySQL, PostgreSQL, and MariaDB on your servers. A database process restart or crash causes immediate 500 errors in all connected apps.

MySQL/MariaDB:

* * * * * root mysqladmin ping --silent 2>/dev/null \
  && curl -s https://vigilmon.online/heartbeat/YOUR_MYSQL_HEARTBEAT_ID

Or via TCP monitor (works when MySQL is on a known port):

  1. Click Add MonitorTCP Port.
  2. Set Port to 3306.
  3. Set Check interval to 1 minute.
  4. Click Save.

PostgreSQL:

* * * * * postgres pg_isready -q \
  && curl -s https://vigilmon.online/heartbeat/YOUR_PG_HEARTBEAT_ID

Or TCP monitor on port 5432.


Step 7: Monitor SSL Certificate Renewal

Cleavr automates Let's Encrypt certificate renewal via its agent. If renewal fails (agent down, DNS misconfigured, rate limit hit), the cert expires and your domain goes HTTPS-down — browsers block access and API clients get TLS errors.

The Step 1 HTTP monitor with SSL monitoring covers the expiry detection. Add an additional cron heartbeat that fires after each successful renewal to catch silent renewal failures early:

# /etc/letsencrypt/renewal-hooks/post/vigilmon-cert-renewed.sh
#!/bin/bash
curl -s https://vigilmon.online/heartbeat/YOUR_CERT_RENEWAL_HEARTBEAT_ID

In Vigilmon, create a Cron Heartbeat with a 60 day expected interval. Let's Encrypt renews at 60 days remaining, so if renewal hasn't happened for 60 days, something is wrong.


Step 8: Monitor Disk Space

A full disk on a managed server breaks deployments immediately — the deployment script cannot write new files. It also breaks database writes, log rotation, and SSL certificate renewal. Disk exhaustion is one of the most common causes of cascading failures on self-hosted stacks.

#!/bin/bash
# /usr/local/bin/disk-check.sh
THRESHOLD=85

USAGE=$(df / | awk 'NR==2 {print $5}' | tr -d '%')

if [ "$USAGE" -lt "$THRESHOLD" ]; then
  curl -s https://vigilmon.online/heartbeat/YOUR_DISK_HEARTBEAT_ID
fi

Schedule every 5 minutes on each server. Set the Vigilmon heartbeat interval to 5 minutes with a 3 minute grace period.

If you have multiple mount points (e.g., separate /var, /home, or /data volumes), check each one independently and create a heartbeat per mount.


Step 9: Monitor Deployment Webhook Health

Cleavr can trigger deployments via webhooks from GitHub, GitLab, or Bitbucket. If the webhook receiver on your server becomes unreachable (port blocked, nginx config error), pushes to your repository silently fail to trigger deployments — you think you've deployed but the old version is still running.

Add an HTTP monitor for the deployment webhook receiver port:

  1. Click Add MonitorTCP Port.
  2. Set Port to the port your Cleavr webhook receiver listens on (check Cleavr dashboard under the app's deployment settings).
  3. Set Check interval to 5 minutes.
  4. Click Save.

Optionally, monitor deployment success rate via a post-deployment cron heartbeat:

# Add to Cleavr's post-deployment hook in the dashboard
curl -s https://vigilmon.online/heartbeat/YOUR_DEPLOY_HEARTBEAT_ID

Set the expected interval to match your deployment frequency — if you deploy daily, set it to 24 hours and alert if no successful deployment has been detected in 48 hours.


Step 10: Configure Alert Channels

  1. Go to Alert Channels in Vigilmon and add Slack, email, PagerDuty, or a webhook.
  2. Set web app HTTP monitors to alert on 1 failure — a single failed check means your site is down for real users.
  3. Set the Cleavr agent TCP monitor to alert after 2 consecutive failures — agent restarts are brief.
  4. Set database TCP monitors and process heartbeats to alert on 1 failure.
  5. Set disk heartbeats to alert on 1 missed ping.
  6. Create a Slack alert for all app HTTP failures (immediate), and a PagerDuty escalation for failures lasting more than 5 minutes.

Summary

| Monitor | Target | What It Catches | |---|---|---| | Web app HTTP | https://yourapp.com | Full-stack failure (nginx + app + DB) | | Cleavr agent TCP | :27001 | Agent down, deployments blocked | | nginx heartbeat | Cron per server | Web server crashed, all apps unreachable | | PHP-FPM heartbeat | Cron per PHP version | 502 errors on all PHP apps | | PM2 heartbeat | Cron per app | Node.js app crashed, PM2 not restarting | | MySQL/PostgreSQL TCP | :3306 / :5432 | Database down, 500 errors in apps | | SSL cert monitor | https://yourapp.com | Certificate expired, browsers blocking | | SSL renewal heartbeat | Post-renewal hook | Renewal failed, cert will expire | | Disk heartbeat | Cron every 5 min | Disk full, deployments and writes failing | | Webhook receiver TCP | Deployment port | Push-to-deploy broken silently |

Cleavr's control plane visibility is limited to what its agent can report — if the agent is down or the network partition is between nodes and the SaaS plane, the dashboard may show servers as healthy while they're actually failing. Vigilmon fills that gap with external monitoring that's independent of Cleavr's infrastructure, giving you ground truth on what your users are actually experiencing.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →