InvoiceShelf is a self-hosted open-source invoicing and billing application built on PHP/Laravel. You get beautiful invoices, estimates, recurring billing, and expense tracking — all on your own infrastructure, free from SaaS subscription fees. The trade-off: you own the uptime. When InvoiceShelf goes down, invoices stop going out, payment links stop working, and PDF generation silently fails. Vigilmon gives you the visibility layer that InvoiceShelf doesn't include out of the box.
What You'll Set Up
- HTTP uptime monitoring for the web interface
- Health check for the database connection
- Payment gateway connectivity probe
- PDF generation service availability
- Email notification delivery heartbeat
- Instant alerts for any failure
Prerequisites
- InvoiceShelf running on a server (default port 80 or 443)
- A free Vigilmon account
Why InvoiceShelf Monitoring Matters
InvoiceShelf is a revenue-critical application. A failure here is never just a technical nuisance — it has immediate business consequences:
- Web interface down — clients can't view or pay invoices online, and you can't log expenses or create new bills
- Database unavailable — all data is inaccessible; transactions fail silently if the connection pool exhausts
- PDF generation failure — invoice PDFs can't be generated or attached to emails; clients receive broken download links
- Email delivery broken — recurring invoice emails and payment reminders stop being sent with no error visible in the UI
- Payment gateway unreachable — any integrated payment processor (Stripe, PayPal) becomes unavailable; online payments fail at checkout
Each of these failures can linger for hours without active monitoring because InvoiceShelf has no built-in alerting for service-level issues.
Step 1: Monitor the InvoiceShelf Web Interface
InvoiceShelf serves its frontend at port 80 or 443. Add an HTTP uptime monitor for the login page — this confirms nginx/Apache is running, PHP-FPM is responding, and the app is serving requests:
- Log in to vigilmon.online and click Add Monitor.
- Set Type to
HTTP / HTTPS. - Enter
http://your-invoiceshelf-domain.com(orhttps://if you've configured SSL). - Set Check interval to
1 minute. - Set Expected HTTP status to
200. - Click Save.
For a richer health signal, InvoiceShelf exposes the underlying Laravel /api/ping endpoint. Monitor that too:
- Add a second monitor with URL
http://your-invoiceshelf-domain.com/api/ping. - Set Expected HTTP status to
200. - Set Expected response body to
pong(InvoiceShelf returns a simple ping/pong response).
If the homepage returns 200 but the API is broken, you'll catch it.
Step 2: Add a Database Health Endpoint
InvoiceShelf uses MySQL or PostgreSQL under the hood. A database failure results in blank pages, login errors, or 500s that are hard to diagnose remotely. Add a Laravel health route that confirms the DB connection.
SSH into your InvoiceShelf server and create a health check route. InvoiceShelf's routes file is at routes/api.php — add:
// routes/api.php
use Illuminate\Support\Facades\DB;
Route::get('/health', function () {
try {
DB::connection()->getPdo();
return response()->json([
'status' => 'ok',
'database' => 'connected',
'timestamp' => now()->toIso8601String(),
]);
} catch (\Exception $e) {
return response()->json([
'status' => 'error',
'database' => 'unreachable',
], 500);
}
});
Clear the route cache and verify it works:
php artisan route:cache
curl http://your-invoiceshelf-domain.com/api/health
# {"status":"ok","database":"connected","timestamp":"..."}
Now add a Vigilmon monitor for this endpoint:
- Click Add Monitor → HTTP / HTTPS.
- URL:
http://your-invoiceshelf-domain.com/api/health - Expected status:
200 - Expected body contains:
"database":"connected" - Save.
If the database becomes unreachable, the response body changes and Vigilmon alerts you.
Step 3: Monitor Payment Gateway Connectivity
If you've connected InvoiceShelf to Stripe or another payment provider, you should verify the gateway is reachable from your server — not just that InvoiceShelf is up. A network routing change, a firewall misconfiguration, or a Stripe regional outage can silently break payment collection while the rest of your app appears healthy.
Add a TCP connectivity monitor to verify your server can reach the payment gateway:
- Click Add Monitor → TCP.
- Host:
api.stripe.com, Port:443. - Check interval:
5 minutes. - Save.
For PayPal:
- Host:
api.paypal.com, Port:443. - Same settings.
If your server loses connectivity to the payment gateway, you'll be alerted within 5 minutes — before clients start complaining that payments aren't going through.
Step 4: Monitor PDF Generation
InvoiceShelf generates PDFs using barryvdh/laravel-dompdf (or a similar renderer). PDF generation can silently fail if the renderer is misconfigured, disk is full, or memory limits are hit. Add an endpoint that triggers a lightweight PDF render and confirms it succeeds.
Add a test route:
// routes/api.php
use Barryvdh\DomPDF\Facade\Pdf;
Route::get('/health/pdf', function () {
try {
$pdf = Pdf::loadHTML('<h1>Health Check</h1>');
$content = $pdf->output();
if (strlen($content) > 0) {
return response()->json(['status' => 'ok', 'pdf' => 'rendered']);
}
return response()->json(['status' => 'error', 'pdf' => 'empty'], 500);
} catch (\Exception $e) {
return response()->json(['status' => 'error', 'message' => $e->getMessage()], 500);
}
});
Monitor it in Vigilmon:
- URL:
http://your-invoiceshelf-domain.com/api/health/pdf - Expected status:
200 - Expected body contains:
"pdf":"rendered" - Check interval:
5 minutes
This is a synthetic transaction — it exercises the PDF stack end-to-end on every check.
Step 5: Heartbeat for Email Notification Delivery
InvoiceShelf sends invoice emails, payment reminders, and recurring invoice notifications via Laravel queued jobs. If the queue worker stops (process crash, OOM kill, misconfigured supervisor), emails stop going out silently.
Add a heartbeat ping to your queue worker to confirm it's alive:
Create a simple Artisan command:
// app/Console/Commands/VigilmonHeartbeat.php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;
class VigilmonHeartbeat extends Command
{
protected $signature = 'vigilmon:heartbeat';
protected $description = 'Ping Vigilmon heartbeat to confirm queue worker is alive';
public function handle(): int
{
$url = env('VIGILMON_HEARTBEAT_URL');
if ($url) {
Http::timeout(5)->get($url);
}
return Command::SUCCESS;
}
}
Schedule it every 10 minutes in app/Console/Kernel.php (or routes/console.php on Laravel 11+):
Schedule::command('vigilmon:heartbeat')->everyTenMinutes();
In Vigilmon:
- Click Add Monitor → Cron Heartbeat.
- Set expected interval:
10 minutes. - Copy the heartbeat URL and set it as
VIGILMON_HEARTBEAT_URLin your.env. - Save.
If the scheduled task stops running or the queue worker crashes, Vigilmon alerts you within 10 minutes.
Step 6: Configure Alert Channels
- In Vigilmon, go to Alert Channels → Add Channel.
- Add Slack (paste your incoming webhook URL) or email.
- Set Consecutive failures before alert to
2on web monitors to avoid false alarms from transient network blips. - Enable the channel on every monitor.
Alert example when InvoiceShelf goes down:
🔴 DOWN: invoiceshelf.yourdomain.com
Status: 502 Bad Gateway
Detected: 3 minutes ago
Recovery alert:
✅ RECOVERED: invoiceshelf.yourdomain.com is back UP
Downtime: 8 minutes
Summary
| Monitor | URL / Target | What It Catches |
|---|---|---|
| Web interface | / | nginx down, PHP-FPM crash, app boot failure |
| API ping | /api/ping | API layer failure independent of frontend |
| Database health | /api/health | MySQL/PostgreSQL connection failure |
| Payment gateway | api.stripe.com:443 | Network routing to payment provider broken |
| PDF generation | /api/health/pdf | Renderer crash, disk full, memory limit |
| Queue heartbeat | Cron heartbeat | Worker crash, email queue stopped |
InvoiceShelf gives you full control over your billing infrastructure. Vigilmon gives you the visibility to keep it running reliably — so the first person to know about an outage is you, not an unpaid client.
Get started free at vigilmon.online.