tutorial

Monitoring Joomla CMS with Vigilmon

Joomla powers millions of websites globally — but self-hosted CMS platforms need active monitoring. Here's how to monitor Joomla frontend health, backend admin, MySQL, PHP-FPM, cache, and extension security with Vigilmon.

Joomla is one of the three most widely deployed open source CMS platforms globally, used for community portals, government websites, multilingual sites, and e-commerce deployments via extensions. When you self-host Joomla, you own the reliability story: no managed hosting team watches your frontend, alerts on slow page loads, or warns you when a PHP-FPM pool saturates. Vigilmon gives you that coverage — uptime monitoring, latency alerts, and MySQL health checks for your Joomla installation.

What You'll Set Up

  • Joomla frontend and administrator uptime monitors
  • MySQL database connectivity and query latency checks
  • PHP-FPM pool saturation alerts
  • Joomla cache hit rate monitoring
  • Extension security and core version currency alerts
  • Disk space monitoring for media uploads

Prerequisites

  • A self-hosted Joomla 4.x or 5.x installation (Apache or nginx + PHP-FPM + MySQL/MariaDB)
  • SSH access to the server
  • A free Vigilmon account

Why Monitoring Matters for Joomla

Joomla's PHP architecture means several independent layers can fail independently: the web server, PHP-FPM, MySQL, Joomla's caching layer, and the extension ecosystem. A failed PHP-FPM pool queues requests silently until nginx returns a 502. A saturated MySQL connection pool returns errors that Joomla renders as blank pages rather than informative 500s. And Joomla's extension ecosystem — components, modules, and plugins from third-party developers — is a significant attack surface; the Joomla Vulnerable Extensions List (VEL) tracks known-vulnerable extensions that need prompt removal or update.

Monitoring Joomla means watching all five layers: web, PHP, database, cache, and security posture.


Key Metrics to Monitor

| Metric | Why It Matters | Alert Threshold | |--------|---------------|-----------------| | Frontend HTTP status | Public website availability | Any non-200 or 5xx | | Frontend p95 response time | Visitor experience | > 2 seconds | | Administrator backend HTTP | CMS management access | Unavailable | | MySQL connectivity | All content lives in DB | Any failure | | PHP-FPM pool utilization | Request throughput capacity | > 90% | | Cache hit rate | DB query reduction | < 60% | | Vulnerable extension count | Security posture | Any > 0 | | Joomla core version lag | Security patch currency | > 1 minor version behind | | PHP error rate | Template rendering errors | Any fatal errors | | Disk usage on /images/ | Media upload capacity | > 80% |


Step 1: Monitor the Joomla Frontend

The Joomla public site is your primary uptime check. Add a Vigilmon HTTP monitor for your site root or a lightweight health endpoint:

  1. Log in to vigilmon.online and click Add Monitor.
  2. Set Type to HTTP / HTTPS.
  3. Enter your Joomla URL: https://yourjoomlasite.com.
  4. Set Check interval to 1 minute.
  5. Set Expected HTTP status to 200.
  6. Click Save.

For a richer signal, create a simple Joomla health endpoint. Create a file at the webroot:

<?php
// health.php — place in Joomla webroot
// Check DB connectivity
define('_JEXEC', 1);
define('JPATH_BASE', __DIR__);
require_once JPATH_BASE . '/includes/defines.php';
require_once JPATH_BASE . '/includes/framework.php';

$app = JFactory::getApplication('site');
$db = JFactory::getDbo();
try {
    $db->setQuery('SELECT 1')->execute();
    http_response_code(200);
    echo json_encode(['status' => 'ok', 'db' => 'ok']);
} catch (Exception $e) {
    http_response_code(503);
    echo json_encode(['status' => 'error', 'db' => 'unavailable']);
}

Point Vigilmon at https://yourjoomlasite.com/health.php for a check that also validates database connectivity.

Set an alert: notify immediately on any HTTP 5xx response or if p95 response time exceeds 2 seconds.


Step 2: Monitor the Joomla Administrator Backend

The Joomla admin interface (/administrator) is a distinct PHP application entry point — it can fail independently of the frontend. Add a second monitor:

  1. Click Add Monitor in Vigilmon.
  2. Set Type to HTTP / HTTPS.
  3. Enter: https://yourjoomlasite.com/administrator/.
  4. Set Check interval to 5 minutes (admin is less latency-sensitive than the public site).
  5. Set Expected HTTP status to 200 or 303 (redirect to login).
  6. Click Save.

Alert condition: notify if administrator backend becomes unavailable — this blocks content editors and site management.


Step 3: Monitor MySQL Database Health

Joomla stores all content, menus, users, extensions, and configuration in MySQL/MariaDB. A database failure renders the entire site unusable. Monitor MySQL directly from your server using a Vigilmon heartbeat with a cron-driven probe:

# /usr/local/bin/joomla-db-check.sh
#!/bin/bash
DB_HOST="localhost"
DB_USER="joomla_user"
DB_PASS="yourpassword"
DB_NAME="joomla_db"
HEARTBEAT_URL="https://vigilmon.online/api/heartbeat/YOUR_HEARTBEAT_ID"

# Test query latency
START=$(date +%s%N)
mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" \
  -e "SELECT COUNT(*) FROM jos_content WHERE state=1;" > /dev/null 2>&1
EXIT_CODE=$?
END=$(date +%s%N)
LATENCY_MS=$(( (END - START) / 1000000 ))

if [ $EXIT_CODE -eq 0 ] && [ $LATENCY_MS -lt 1000 ]; then
    curl -s "$HEARTBEAT_URL" > /dev/null
fi

Add to cron (crontab -e):

*/5 * * * * /usr/local/bin/joomla-db-check.sh

In Vigilmon, create a Heartbeat monitor and configure it to alert if no ping is received within 10 minutes. This catches both database unavailability and query latency exceeding 1 second.


Step 4: Monitor PHP-FPM Pool Utilization

Joomla runs on PHP-FPM, which uses a worker pool. When the pool is fully saturated, new requests queue (then fail). Monitor pool utilization via the PHP-FPM status page.

Enable the PHP-FPM status page in your pool configuration (/etc/php/8.x/fpm/pool.d/www.conf):

pm.status_path = /status

Expose it through nginx on a non-public path (restrict to localhost):

location ~ ^/(status|ping)$ {
    allow 127.0.0.1;
    deny all;
    fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

Create a probe script:

#!/bin/bash
# /usr/local/bin/phpfpm-check.sh
STATUS=$(curl -s http://127.0.0.1/status?json)
ACTIVE=$(echo "$STATUS" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['active processes'])")
TOTAL=$(echo "$STATUS" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['max children reached'])")
MAX=$(echo "$STATUS" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['total processes'])")

UTIL=$(( ACTIVE * 100 / MAX ))
HEARTBEAT_URL="https://vigilmon.online/api/heartbeat/YOUR_PHPFPM_HEARTBEAT_ID"

if [ $UTIL -lt 90 ]; then
    curl -s "$HEARTBEAT_URL" > /dev/null
fi

Run every minute via cron. Alert threshold: pool utilization > 90% triggers request queuing.


Step 5: Monitor Joomla Cache Hit Rate

Joomla's caching layers (conservative component-level cache and progressive page-level cache) reduce database load significantly. A low cache hit rate means every page request hits MySQL. Monitor cache effectiveness:

#!/bin/bash
# /usr/local/bin/joomla-cache-check.sh
# Reads Joomla's cache directory statistics
CACHE_DIR="/var/www/joomla/cache"
HEARTBEAT_URL="https://vigilmon.online/api/heartbeat/YOUR_CACHE_HEARTBEAT_ID"

# Count cached files as a proxy for cache activity
CACHED_FILES=$(find "$CACHE_DIR" -name "*.php" -newer /tmp/joomla-cache-baseline 2>/dev/null | wc -l)
TOTAL_REQUESTS=$(tail -n 1000 /var/log/nginx/access.log | grep -c "GET")

# Update baseline
touch /tmp/joomla-cache-baseline

# Simple heuristic: if cache directory is actively populated, cache is working
if [ "$CACHED_FILES" -gt 0 ] || [ -d "$CACHE_DIR/page" ]; then
    curl -s "$HEARTBEAT_URL" > /dev/null
fi

For more precise cache metrics, use Joomla's built-in debug console (enable in Global Configuration → System → Debug System) to log cache hit/miss statistics, then parse them from the Joomla debug log.

Alert condition: cache hit rate below 60% triggers excessive MySQL query load.


Step 6: Monitor Extension Security

Outdated or vulnerable Joomla extensions represent the most common attack vector. The Joomla Vulnerable Extensions List (VEL) tracks known-vulnerable extensions. Create a weekly security check:

#!/bin/bash
# /usr/local/bin/joomla-extension-check.sh
# Compares installed extensions against VEL feed
VEL_FEED="https://vel.joomla.org/vel-feed.json"
JOOMLA_DB_USER="joomla_user"
JOOMLA_DB_PASS="yourpassword"
JOOMLA_DB_NAME="joomla_db"
HEARTBEAT_URL="https://vigilmon.online/api/heartbeat/YOUR_SECURITY_HEARTBEAT_ID"

# Fetch installed extensions
INSTALLED=$(mysql -u "$JOOMLA_DB_USER" -p"$JOOMLA_DB_PASS" "$JOOMLA_DB_NAME" \
  -se "SELECT element, manifest_cache FROM jos_extensions WHERE type='component' AND enabled=1;")

# Fetch VEL (simplified check)
VEL_DATA=$(curl -s "$VEL_FEED" 2>/dev/null)
VULN_COUNT=0

while IFS=$'\t' read -r element manifest; do
    EXT_NAME=$(echo "$element" | sed 's/com_//')
    if echo "$VEL_DATA" | grep -qi "$EXT_NAME"; then
        VULN_COUNT=$((VULN_COUNT + 1))
    fi
done <<< "$INSTALLED"

if [ "$VULN_COUNT" -eq 0 ]; then
    curl -s "$HEARTBEAT_URL" > /dev/null
fi
# If VULN_COUNT > 0, heartbeat is NOT sent — Vigilmon alerts on missed heartbeat

Run weekly via cron:

0 8 * * 1 /usr/local/bin/joomla-extension-check.sh

Configure the Vigilmon heartbeat with a 8-day grace period — if not received within 8 days, alert.


Step 7: Monitor Disk Space for Media Uploads

Joomla stores all uploaded media in the /images/ directory. A full disk prevents new uploads and can corrupt write operations. Add a Vigilmon heartbeat for disk monitoring:

#!/bin/bash
# /usr/local/bin/joomla-disk-check.sh
MEDIA_DIR="/var/www/joomla/images"
HEARTBEAT_URL="https://vigilmon.online/api/heartbeat/YOUR_DISK_HEARTBEAT_ID"

# Get disk usage percentage for the partition hosting media
USAGE=$(df "$MEDIA_DIR" | awk 'NR==2 {print $5}' | tr -d '%')

if [ "$USAGE" -lt 80 ]; then
    curl -s "$HEARTBEAT_URL" > /dev/null
fi

Add to cron (every 15 minutes):

*/15 * * * * /usr/local/bin/joomla-disk-check.sh

Alert threshold: disk usage > 80% on the media partition.


Step 8: Configure Alerting

In Vigilmon, set up notification channels for your Joomla monitors:

  1. Go to Settings → Notifications.
  2. Add your preferred channels: email, Slack, PagerDuty, or webhook.
  3. For critical monitors (frontend, MySQL), set immediate notification on first failure.
  4. For non-critical monitors (disk, cache), set 3 consecutive failures before alerting to reduce noise.

Recommended alert routing:

| Monitor | Severity | Channel | |---------|----------|---------| | Frontend down | Critical | Slack + SMS | | Admin backend down | High | Slack | | MySQL failure | Critical | Slack + SMS | | PHP-FPM > 90% | High | Slack | | Vulnerable extension | High | Email | | Disk > 80% | Medium | Email | | Cache hit rate < 60% | Low | Email |


Step 9: Test Your Monitors

Before relying on your monitors in production, verify each one fires correctly:

# Simulate a MySQL failure
sudo systemctl stop mysql
# → Vigilmon should alert within 10 minutes (heartbeat missed)
sudo systemctl start mysql

# Simulate frontend failure
sudo systemctl stop php8.2-fpm
# → Vigilmon should alert within 1-2 minutes
sudo systemctl start php8.2-fpm

# Test disk alert
# Create a large test file (careful with disk space)
dd if=/dev/zero of=/var/www/joomla/images/test-large.bin bs=1M count=100
# → Run disk check script and verify it withholds the heartbeat
rm /var/www/joomla/images/test-large.bin

Conclusion

A production Joomla site needs monitoring at every layer of its stack: the PHP frontend, the MySQL database, the PHP-FPM worker pool, the caching subsystem, and the extension security posture. With Vigilmon heartbeats and HTTP monitors covering each of these, you get early warnings before minor issues become site outages or security incidents.

The most important monitors to add first: frontend HTTP uptime (catches the most failures) and MySQL heartbeat (catches the second-most). Add PHP-FPM saturation and extension security checks as your second priority — they prevent the slow-degradation failures that uptime checks miss.

Start monitoring your Joomla site with Vigilmon →

Monitor your app with Vigilmon

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

Start free →