tutorial

Monitoring Linkwarden with Vigilmon: Uptime & Health Alerts for Your Self-Hosted Bookmark Manager

How to monitor a self-hosted Linkwarden bookmark manager with Vigilmon — using the heartbeat API endpoint, HTTP monitors, PostgreSQL health checks, and SSL certificate alerts for full-page archival services.

Linkwarden is a self-hosted, open-source bookmark manager that goes beyond saving URLs. It archives full page snapshots, supports team collaboration, and stores everything in a PostgreSQL database with files on local or cloud storage. It's the kind of tool you set up once and rely on daily — until one day it stops working and you've lost access to your archived research. Vigilmon provides external uptime monitoring for Linkwarden that watches the full stack: web server, database connectivity, and storage availability, alerting you before a silent failure becomes a data access crisis.

What You'll Build

  • A Vigilmon HTTP monitor on Linkwarden's heartbeat or API endpoint
  • A keyword assertion to verify the application is serving correctly
  • Database and storage health verification via heartbeat monitors
  • SSL certificate alerts for production deployments

Prerequisites

  • A running Linkwarden instance (default port: 3000)
  • A PostgreSQL database and file storage backend configured
  • A reverse proxy (Caddy or Nginx) with HTTPS — required for Vigilmon monitors
  • A free account at vigilmon.online

Step 1: Locate Linkwarden's Health Endpoint

Linkwarden's Next.js-based application responds on port 3000. You can use the root endpoint or — if available in your version — the /api/v1/heartbeat endpoint for a lightweight health check:

# Try the heartbeat endpoint
curl http://localhost:3000/api/v1/heartbeat

# Or use the root URL
curl -o /dev/null -s -w "%{http_code}" http://localhost:3000/

A healthy Linkwarden instance returns HTTP 200. If the Next.js process has crashed or the PostgreSQL connection has failed at startup, you'll get a connection refused error or a 500 response.

HTTPS first: Vigilmon requires HTTPS. Proxy Linkwarden with Caddy:

links.yourdomain.com {
  reverse_proxy localhost:3000
}

Step 2: Create a Vigilmon HTTP Monitor

  1. Log in to VigilmonAdd Monitor → HTTP.
  2. URL: https://links.yourdomain.com/api/v1/heartbeat (or https://links.yourdomain.com/ if the heartbeat endpoint isn't available in your version).
  3. Check interval: 60 seconds.
  4. Response timeout: 15 seconds (Next.js can take a moment on cold starts).
  5. Expected status: 200.
  6. Click Save.

Vigilmon immediately starts probing Linkwarden from an external location every 60 seconds. If the application stops responding, you'll receive an alert within 1–2 minutes.


Step 3: Add a Keyword Assertion

A 200 response confirms the HTTP layer is working, but a keyword assertion confirms the application content is correct — catching proxy error pages and partial startup states.

In the monitor settings, add a Keyword assertion:

  • Keyword: Linkwarden (appears in the page HTML or API response)
  • Keyword must be present: yes

This catches cases where Nginx returns a 200 "Bad Gateway" HTML page while Linkwarden is down, or where the Next.js server starts but returns an error page because PostgreSQL is unreachable.


Step 4: Monitor PostgreSQL Connectivity with a Heartbeat

Linkwarden's functionality depends entirely on PostgreSQL. If the database becomes unreachable — due to a PostgreSQL service crash, disk full, or network issue — Linkwarden will serve errors on every user action even though the web process is still running. The HTTP monitor won't catch this.

Create a Heartbeat monitor in Vigilmon:

  1. Add Monitor → Heartbeat.
  2. Expected interval: 5 minutes.
  3. Grace period: 10 minutes.
  4. Copy the heartbeat URL.

Add a server-side health check script:

#!/bin/bash
# /usr/local/bin/linkwarden-db-check.sh
# Verifies Linkwarden API can perform a DB-backed request, then pings heartbeat

LINKWARDEN_URL="https://links.yourdomain.com"
HEARTBEAT_URL="https://vigilmon.online/api/heartbeat/YOUR-HEARTBEAT-ID"

# Check the API responds correctly (adjust the endpoint as needed)
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "${LINKWARDEN_URL}/api/v1/heartbeat")

if [ "$STATUS" = "200" ]; then
  curl -fsS -X POST "$HEARTBEAT_URL"
fi
# /etc/cron.d/linkwarden-heartbeat
*/5 * * * * root /usr/local/bin/linkwarden-db-check.sh

If PostgreSQL goes down, Linkwarden's API starts returning errors, the heartbeat stops, and Vigilmon alerts you within the grace period.


Step 5: Monitor Storage Service Availability

Linkwarden archives full-page snapshots, which requires accessible file storage. If you're using local storage, a full disk silently breaks new archival jobs. If you're using an S3-compatible bucket, a misconfigured credential or bucket permission change causes archival to fail.

Add an indirect storage check via Linkwarden's archival API. Alternatively, for local storage, add a disk space heartbeat:

#!/bin/bash
# Ping heartbeat only if disk usage is below 85%
DISK=$(df /var/lib/linkwarden --output=pcent | tail -1 | tr -d '% ')
[ "$DISK" -lt 85 ] && curl -fsS -X POST https://vigilmon.online/api/heartbeat/STORAGE-HEARTBEAT-ID

Create a separate Heartbeat monitor for storage with a 1-hour interval and 30-minute grace period. If the disk fills up, the heartbeat stops, and Vigilmon alerts you before the disk is completely full.


Step 6: Monitor SSL Certificate Expiry

Linkwarden over HTTPS with an expired certificate locks all users out — including you. Vigilmon automatically checks the SSL certificate of any HTTPS monitor.

In your existing HTTP monitor settings:

  • SSL certificate alert: enable it.
  • Alert days before expiry: 14 days.

Caddy auto-renews certificates, but auto-renewal can fail when Caddy can't reach Let's Encrypt due to firewall rules or DNS misconfiguration. The 14-day alert gives you time to fix renewal before expiry causes a lockout.


Step 7: Configure Alerting

In Vigilmon under Settings → Notifications, configure your alert channels:

| Trigger | Action | |---|---| | Heartbeat API non-200 | Email — check systemctl status linkwarden and PostgreSQL | | Response timeout (> 15 s) | Email — Next.js cold start or DB query timeout | | Keyword Linkwarden missing | Email — reverse proxy misconfiguration | | DB heartbeat missed | Email — PostgreSQL unreachable; check systemctl status postgresql | | Storage heartbeat missed | Email — disk full or storage misconfigured; run df -h | | SSL expiry < 14 days | Email — force certificate renewal immediately |

Alert after: 1 consecutive failure for the web monitor (Linkwarden's Next.js layer is stable when running correctly).

Re-notify: every 15 minutes while the issue persists — inability to access archived bookmarks affects active research workflows.


Keeping Linkwarden Running with Docker Compose

Most Linkwarden deployments use Docker Compose. Add a health check to your compose configuration:

services:
  linkwarden:
    image: ghcr.io/linkwarden/linkwarden:latest
    environment:
      - DATABASE_URL=postgresql://postgres:password@postgres:5432/linkwarden
      - NEXTAUTH_SECRET=your-secret
      - NEXTAUTH_URL=https://links.yourdomain.com
    ports:
      - "3000:3000"
    depends_on:
      postgres:
        condition: service_healthy
    restart: unless-stopped

  postgres:
    image: postgres:15
    environment:
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=linkwarden
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

Docker health checks provide internal restart logic. Vigilmon provides the external view — what happens when systemd or Docker itself fails, or when the host loses network connectivity.


What Vigilmon Catches That Linkwarden Logs Miss

| Scenario | Linkwarden logs | Vigilmon | |---|---|---| | Next.js process crash, Docker restart fails | Crash logged, then silent | HTTP monitor fires within 60–120 s | | PostgreSQL crash → API errors | DB error per request | DB heartbeat stops arriving | | Disk full → archival jobs silently fail | Write error in logs | Storage heartbeat stops arriving | | SSL certificate expires | Not monitored | Certificate expiry alert fires | | Reverse proxy misconfiguration | Not in app logs | Keyword assertion catches wrong response | | VPS unreachable from internet | Logs inaccessible | External Vigilmon still detecting it |


Linkwarden holds your research archive — pages you may never be able to re-archive if they go offline. The application itself is reliable, but the infrastructure around it (PostgreSQL, storage, reverse proxy, TLS) has many failure points. Vigilmon monitors all of them, so a disk-full event or a database crash never silently takes your bookmark archive offline.

Set up monitoring for your Linkwarden instance in under 5 minutes — register free at vigilmon.online.

Monitor your app with Vigilmon

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

Start free →