tutorial

Monitoring Selfoss RSS Reader with Vigilmon

Selfoss is a self-hosted RSS/Atom/JSON feed aggregator written in PHP. Learn how to monitor its web server, PHP-FPM process, feed scheduler, database, and REST API with Vigilmon.

Selfoss is a self-hosted RSS, Atom, and JSON feed aggregator with a clean web interface and a REST API. It runs on PHP (with Apache or nginx + PHP-FPM) and stores feed data in SQLite, MySQL, or PostgreSQL. Self-hosting your RSS reader keeps your reading habits private and your subscriptions under your control — but it also means you're responsible for keeping the feed scheduler running, the database accessible, and the web interface available. Vigilmon covers every layer of your Selfoss stack, from the web server and PHP-FPM process to the cron-driven feed fetch scheduler.

What You'll Set Up

  • HTTP uptime monitor for the Selfoss web interface
  • PHP-FPM process health via a custom health endpoint
  • Cron heartbeat for the feed fetch scheduler
  • Database connectivity monitor (SQLite / MySQL / PostgreSQL)
  • REST API endpoint response time monitor
  • Feed parsing error rate alerting
  • SSL certificate expiry alerts

Prerequisites

  • Selfoss installed on a server with nginx or Apache + PHP-FPM
  • A cron job configured for php /path/to/selfoss/cliupdate.php
  • A free Vigilmon account

Step 1: Monitor the Selfoss Web Interface

Selfoss serves its single-page app and API from the same PHP application on port 80/443. Start with a basic HTTP monitor:

  1. Log in to vigilmon.online and click Add Monitor.
  2. Set Type to HTTP / HTTPS.
  3. Enter the URL: https://rss.yourdomain.com/ (or your Selfoss base URL).
  4. Set Check interval to 1 minute.
  5. Set Expected HTTP status to 200.
  6. Click Save.

Selfoss's root page returns the main HTML shell. A 200 response confirms nginx is serving the application and PHP-FPM is handling the bootstrap PHP script.


Step 2: Monitor PHP-FPM Process Health

PHP-FPM runs as a separate process pool that nginx proxies to via a Unix socket or TCP port. PHP-FPM can crash, run out of worker processes, or become unresponsive while nginx continues serving its error pages with a 502 status — or, if you've misconfigured error handling, with a misleading 200.

Add a dedicated health endpoint in Selfoss's configuration:

Option A: Use the Selfoss API health endpoint

Selfoss exposes a REST API. Check the stats endpoint for a JSON response:

GET https://rss.yourdomain.com/api/stats

Add this as a Vigilmon monitor:

  1. Click Add MonitorHTTP / HTTPS.
  2. URL: https://rss.yourdomain.com/api/stats.
  3. Expected status: 200.
  4. Under Response body, add a contains check for "total" to confirm valid JSON is returned.
  5. Check interval: 2 minutes.
  6. Click Save.

Option B: Add a standalone PHP health file

Create /var/www/selfoss/health.php:

<?php
header('Content-Type: application/json');
echo json_encode(['status' => 'ok', 'php' => PHP_VERSION]);

Monitor https://rss.yourdomain.com/health.php expecting 200 with body containing "status":"ok". This file bypasses Selfoss's routing and hits PHP-FPM directly.


Step 3: Monitor the Feed Fetch Scheduler

Selfoss fetches feeds via a CLI script run by cron: php /path/to/selfoss/cliupdate.php. This is the core function of the entire application — if the cron job stops running, your feeds go stale without any error showing in the UI.

Set up a Vigilmon cron heartbeat:

  1. Click Add MonitorCron Heartbeat.
  2. Set the expected interval to match your cron schedule (e.g. 30 minutes if you run updates every 30 minutes).
  3. Copy the heartbeat URL.
  4. Add the heartbeat ping to your cron command:
# /etc/cron.d/selfoss
*/30 * * * * www-data php /var/www/selfoss/cliupdate.php && \
  curl -s https://vigilmon.online/heartbeat/YOUR_HEARTBEAT_ID

The && ensures Vigilmon is only pinged on successful completion. If cliupdate.php exits with an error (database unreachable, PHP error, disk full), the heartbeat is skipped and Vigilmon alerts after one missed interval.


Step 4: Monitor Database Connectivity

Selfoss supports SQLite, MySQL, and PostgreSQL. Database downtime means every page load fails with a PHP error, and the feed scheduler can't write new items.

SQLite

If you use SQLite (the default), add a heartbeat that verifies the database file is readable and writable:

#!/bin/bash
# /opt/selfoss/db-health.sh
DB="/var/www/selfoss/data/selfoss.db"
sqlite3 "$DB" "SELECT COUNT(*) FROM items;" > /dev/null 2>&1 && \
  curl -s https://vigilmon.online/heartbeat/DB_HEARTBEAT_ID

Schedule every 5 minutes via cron.

MySQL / MariaDB

For MySQL, add a TCP port monitor:

  1. Click Add MonitorTCP Port.
  2. Host: your-mysql-host.
  3. Port: 3306.
  4. Check interval: 1 minute.
  5. Click Save.

PostgreSQL

For PostgreSQL:

  1. Click Add MonitorTCP Port.
  2. Host: your-postgres-host.
  3. Port: 5432.
  4. Check interval: 1 minute.
  5. Click Save.

TCP checks confirm the database process is listening. Combine with the SQLite heartbeat pattern (adapted for mysql --execute or psql --command) for a write-level health check that catches permission and corruption issues.


Step 5: Monitor the REST API Endpoint Response Time

Selfoss's REST API powers both the web interface and any third-party clients (iOS/Android apps). Slow API responses degrade the reading experience even when the server is technically "up". Monitor response time with Vigilmon's threshold alerts:

  1. Open the https://rss.yourdomain.com/api/stats monitor.
  2. Enable Response time alert.
  3. Set Alert when response time exceeds 3000 ms.
  4. Click Save.

/api/stats performs a lightweight database COUNT query — if it's taking over 3 seconds, something is wrong with your database connection pool or PHP-FPM is under load. Catching this early prevents timeouts from cascading to all feed reads.


Step 6: Monitor Feed Parsing Error Rate

Selfoss logs feed parsing errors to its error log (configured in config.ini as logger_destination). High error rates indicate broken feed URLs, encoding issues, or network connectivity problems to external feed sources.

Create a heartbeat that checks recent error counts:

#!/bin/bash
# /opt/selfoss/error-rate-check.sh
LOG="/var/www/selfoss/data/logs/default.log"
# Count errors in the last 30 minutes
ERRORS=$(find "$LOG" -newer /tmp/selfoss_last_check 2>/dev/null | \
  xargs grep -c "ERROR\|CRITICAL" 2>/dev/null || echo 0)
touch /tmp/selfoss_last_check

if [ "$ERRORS" -lt 20 ]; then
  curl -s https://vigilmon.online/heartbeat/ERROR_RATE_HEARTBEAT_ID
fi

Create a Vigilmon heartbeat monitor with a 30 minute interval. If parsing errors spike (broken feed, DNS failure for a feed source), the heartbeat stops and Vigilmon alerts.


Step 7: Monitor SSL Certificate Expiry

Enable SSL monitoring on your HTTPS monitor:

  1. Open the https://rss.yourdomain.com/ monitor.
  2. Enable Monitor SSL certificate.
  3. Set Alert when certificate expires in less than 21 days.
  4. Click Save.

Selfoss is typically a personal-use tool accessed over HTTPS. A lapsed certificate means you can't log in to read your feeds — and browser security warnings can make it look like the site is compromised. A 21-day window gives you plenty of time to trigger a renewal:

# Certbot renewal
certbot renew --nginx

# Or if using Caddy (auto-renewal, verify it's working)
caddy reload --config /etc/caddy/Caddyfile

Step 8: Monitor OPML Import/Export Service

Selfoss's OPML import and export endpoints (/opml routes) are less frequently used but critical when migrating feeds or backing up your subscription list. A PHP misconfiguration that breaks file upload handling can silently break OPML import while leaving the rest of the application functional.

Add a lightweight check for the OPML export endpoint (GET, no authentication required for some configurations):

  1. Click Add MonitorHTTP / HTTPS.
  2. URL: https://rss.yourdomain.com/opml (requires authentication — if behind HTTP auth, skip to the heartbeat alternative below).
  3. Expected status: 200 or 401 (if authentication is required, a 401 confirms the endpoint is reachable).
  4. Check interval: 10 minutes.
  5. Click Save.

Step 9: Configure Alert Channels

  1. Go to Alert Channels in Vigilmon.
  2. Add email and/or a Slack/webhook channel for alerts.
  3. Set Consecutive failures before alert to 2 on HTTP monitors — PHP-FPM restarts under OOM conditions can cause brief unavailability.
  4. Set a quiet hours window if you don't want 3 AM feed-fetch failure alerts for non-critical feed parsing errors.

For a self-hosted notification setup, route Vigilmon webhook alerts to Gotify or Ntfy:

# Gotify webhook example
curl -X POST "https://gotify.yourdomain.com/message?token=YOUR_TOKEN" \
  -F "title=Selfoss Alert" \
  -F "message={{monitor_name}} is {{status}}"

Summary

| Monitor | Target | What It Catches | |---|---|---| | Web interface (HTTP) | https://rss.yourdomain.com/ | nginx/PHP crash | | PHP-FPM health (HTTP) | /api/stats or /health.php | PHP-FPM failure | | Feed scheduler (Heartbeat) | cliupdate.php cron | Feeds going stale | | Database (TCP / Heartbeat) | Port 3306 / 5432 / SQLite file | DB connectivity loss | | API response time (HTTP) | /api/stats | Slow database queries | | Feed error rate (Heartbeat) | Log-based script | Feed parse failures | | SSL certificate | Selfoss domain | Certificate expiry | | OPML service (HTTP) | /opml | Import/export failure |

Selfoss keeps your reading life private and your feeds under your control — but only when the PHP stack, database, and cron scheduler are all working together. With Vigilmon watching the web interface, PHP-FPM health, feed scheduler heartbeat, and database connectivity, you'll know the moment your RSS reader needs attention rather than discovering it when you open the app to catch up on your morning reading.

Monitor your app with Vigilmon

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

Start free →