tutorial

Monitoring Shiori with Vigilmon

Shiori is a self-hosted Pocket alternative written in Go — here's how to monitor its web UI, REST API authentication, tag endpoints, SSL certificate, and bookmark download worker with Vigilmon.

Shiori is a clean, self-hosted bookmark manager written in Go — a single binary that stores bookmarks with titles, excerpts, thumbnails, and full offline copies of the page. No cloud service, no tracking, and a REST API that works with scripts and mobile apps alike. But because Shiori quietly handles authentication and background page downloads in the same process, a broken database connection or stalled download worker can be invisible until you try to read a bookmark offline. Vigilmon watches Shiori's web UI, authentication API, and download worker health so problems surface immediately rather than silently accumulating.

What You'll Set Up

  • HTTP monitor for the Shiori web UI (port 8080)
  • HTTP monitor for the Shiori REST API authentication endpoint (/api/v1/auth/login)
  • HTTP monitor for the authenticated tag API (/api/v1/tags)
  • SSL certificate expiry alerts for HTTPS Shiori deployments
  • Heartbeat monitor that confirms Shiori's background bookmark download worker is processing pages

Prerequisites

  • Shiori running and accessible on port 8080 (or via a reverse proxy)
  • Shiori admin credentials (username and password)
  • A free Vigilmon account

Step 1: Monitor the Shiori Web UI

Shiori's Go HTTP server listens on port 8080 by default. A GET / returns the login page (or the bookmark list for authenticated sessions) — a 200 response confirms the Go server is up and the SQLite, MySQL, or PostgreSQL backend is connected.

  1. Log in to vigilmon.online and click Add Monitor.
  2. Set Type to HTTP / HTTPS.
  3. Enter your Shiori URL: http://your-server:8080 (or https://shiori.yourdomain.com if reverse-proxied).
  4. Set Check interval to 1 minute.
  5. Set Expected HTTP status to 200.
  6. Click Save.

If Shiori is configured with a base path (e.g. /shiori/), use the full path. The login page response confirms not just that Go is running but that the HTML templates and static assets are being served correctly.


Step 2: Monitor the REST API Authentication Endpoint

The Shiori REST API at /api/v1/auth/login accepts a POST with admin credentials and returns a JSON object containing an access_token field. This is the highest-signal health check available — it confirms the Go HTTP server is handling API routes, the authentication middleware is working, and the database is returning user records.

  1. Click Add Monitor in Vigilmon.
  2. Set Type to HTTP / HTTPS.
  3. Enter the login URL: http://your-server:8080/api/v1/auth/login
  4. Set HTTP method to POST.
  5. Set Request body to:
    {"username": "your-admin-username", "password": "your-admin-password"}
    
  6. Set Request headers: Content-Type: application/json
  7. Set Expected HTTP status to 200.
  8. Under Response body check, enter access_token to confirm the token was issued.
  9. Set Check interval to 5 minutes.
  10. Click Save.

The access_token body check is essential — a misconfigured database connection causes Shiori to return a 500 or a 200 with an error JSON rather than a valid token.


Step 3: Monitor the Authenticated Tag API

The tag API at GET /api/v1/tags requires a valid Bearer token and returns the list of all tags in the Shiori database. Monitoring this endpoint confirms that authenticated API routes are accessible and the database is returning data beyond the authentication layer.

Because Shiori tokens expire, this monitor is best implemented as a scripted check using Vigilmon's webhook-based custom monitor or an external cron script:

#!/bin/bash
# /etc/cron.d/shiori-tag-check

SHIORI_URL="http://localhost:8080"
VIGILMON_HEARTBEAT="https://vigilmon.online/heartbeat/def456"

# Authenticate and retrieve token
TOKEN=$(curl -s -X POST "${SHIORI_URL}/api/v1/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "your-password"}' \
  | grep -o '"access_token":"[^"]*"' | cut -d'"' -f4)

if [ -z "$TOKEN" ]; then
  echo "Shiori auth failed" >&2
  exit 1
fi

# Fetch tags with the token
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
  "${SHIORI_URL}/api/v1/tags" \
  -H "Authorization: Bearer ${TOKEN}")

if [ "$STATUS" = "200" ]; then
  curl -s "${VIGILMON_HEARTBEAT}" > /dev/null
fi

For a simpler setup, add a second HTTP monitor in Vigilmon pointing to /api/v1/tags with a hardcoded Bearer token and accept that it will alert when the token expires (a useful reminder to rotate credentials).


Step 4: SSL Certificate Alerts for HTTPS Deployments

Shiori is typically reverse-proxied behind nginx, Caddy, or Traefik, which handles TLS termination. The proxy's certificate must stay valid — an expiry locks all clients out.

  1. Open the HTTPS monitor for your Shiori domain (created in Step 1).
  2. Enable Monitor SSL certificate under the SSL settings.
  3. Set Alert when certificate expires in less than 21 days.
  4. Click Save.

For Caddy deployments, certificates auto-renew by default. For nginx with certbot, verify the systemd timer is active:

systemctl status certbot.timer

# Test without issuing a certificate
sudo certbot renew --dry-run

For Traefik, check the ACME JSON file for certificate expiry dates:

cat /etc/traefik/acme.json | python3 -c "
import json, sys, base64, datetime
data = json.load(sys.stdin)
for resolver in data.values():
    for cert in resolver.get('Certificates', []):
        raw = base64.b64decode(cert['certificate'])
        print(cert['domain']['main'])
"

Step 5: Heartbeat Monitoring for the Bookmark Download Worker

Shiori can automatically download offline copies of bookmarked pages for e-reader mode. This background operation runs within the Shiori process — if it stalls, bookmarks are saved as metadata only, with no offline content available. A heartbeat that adds a test bookmark and verifies the download status confirms the worker is processing.

  1. In Vigilmon, click Add MonitorCron Heartbeat.
  2. Set Expected ping interval to 60 minutes.
  3. Copy the heartbeat URL (e.g. https://vigilmon.online/heartbeat/ghi789).

Set up a cron job that adds a bookmark and checks that Shiori has populated the download fields:

#!/bin/bash
# /etc/cron.hourly/shiori-heartbeat

SHIORI_URL="http://localhost:8080"
VIGILMON_HEARTBEAT="https://vigilmon.online/heartbeat/ghi789"

# Authenticate
TOKEN=$(curl -s -X POST "${SHIORI_URL}/api/v1/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "your-password"}' \
  | python3 -c "import sys,json; print(json.load(sys.stdin).get('access_token',''))")

if [ -z "$TOKEN" ]; then
  echo "Auth failed" >&2
  exit 1
fi

# Add a lightweight test bookmark
BOOKMARK=$(curl -s -X POST "${SHIORI_URL}/api/v1/bookmarks" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "tags": [{"name": "healthcheck"}]}')

BOOKMARK_ID=$(echo "$BOOKMARK" | python3 -c "import sys,json; print(json.load(sys.stdin).get('id',''))")

if [ -z "$BOOKMARK_ID" ]; then
  echo "Bookmark creation failed" >&2
  exit 1
fi

# Wait for the download worker (up to 30 seconds)
for i in $(seq 1 6); do
  sleep 5
  STATUS=$(curl -s "${SHIORI_URL}/api/v1/bookmarks/${BOOKMARK_ID}" \
    -H "Authorization: Bearer ${TOKEN}" \
    | python3 -c "import sys,json; b=json.load(sys.stdin); print(b.get('hasArchive', False))")
  if [ "$STATUS" = "True" ]; then
    curl -s "${VIGILMON_HEARTBEAT}" > /dev/null
    # Clean up the test bookmark
    curl -s -X DELETE "${SHIORI_URL}/api/v1/bookmarks" \
      -H "Authorization: Bearer ${TOKEN}" \
      -H "Content-Type: application/json" \
      -d "[${BOOKMARK_ID}]"
    exit 0
  fi
done

echo "Download worker did not process bookmark within 30 seconds" >&2
exit 1

If the download worker is not running or is stalled, the hasArchive field stays false and the heartbeat is never sent — Vigilmon alerts after the expected interval.


Step 6: Configure Alert Channels

  1. Go to Alert Channels in Vigilmon and add Slack, email, or a webhook.
  2. Set Consecutive failures before alert to 2 on the web UI monitor — brief Go server restarts or container redeploys can cause a single probe to fail.
  3. For the authentication API monitor, a single failure is a meaningful signal — set Consecutive failures before alert to 1.

Summary

| Monitor | Target | What It Catches | |---|---|---| | Web UI | http://your-server:8080/ | Go server down, database unreachable | | Auth API | /api/v1/auth/login (POST) | Authentication failure, database connectivity | | Tag API heartbeat | Heartbeat URL | Authenticated API broken, database read failure | | SSL certificate | Shiori domain | Reverse proxy certificate expiry | | Download heartbeat | Heartbeat URL | Bookmark download worker stalled |

Shiori's simplicity is its strength — a single Go binary, minimal dependencies, and a clean REST API. Vigilmon keeps that simplicity honest: if the database disconnects, the download worker stalls, or the reverse proxy certificate expires, you'll know within minutes rather than discovering it when you're offline and need a saved article.

Monitor your app with Vigilmon

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

Start free →