The wiki is where the runbooks live, which means it is the one internal tool whose outage you discover during another outage. It is also the tool most likely to be unmonitored, because it is internal, boring, and almost always up. This guide sets up external monitoring for the four self-hosted knowledge bases people actually run: Outline, BookStack, Docmost, and Wiki.js, using the health routes three of them ship and a login-page check for the fourth.
Everything in the first section runs on CronAlert's free plan. Keyword assertions and heartbeats are Pro ($5/month) and are marked. The examples use wiki.example.com behind a reverse proxy.
What each wiki exposes
| Health route | What it checks | Success | Failure | |
|---|---|---|---|---|
| Outline | GET /_health | SELECT 1 on PostgreSQL | 200, body OK | 500 |
| BookStack | GET /status | database (migrations table), cache write/read, session write/read | 200, {"database":true,"cache":true,"session":true} | 500 with the failing key false |
| Docmost | GET /api/health | PostgreSQL ping and Redis ping | 200, status JSON with database and redis | 503 (NestJS health convention) |
| Docmost | GET /api/health/live | process up | 200, ok | |
| Wiki.js | none found | use /login + keyword | 200 | error page or hang |
All of the health routes are unauthenticated and sit outside each application's login, which is what makes them usable from outside even when the wiki itself requires sign-in. Outline's is mounted on every service, so if you run separate web and worker processes behind one hostname, the proxy decides which one answers. Docmost's health controller uses the NestJS Terminus module, whose convention is 503 on a failed check; the controller itself does not set the code, so expect 200 and treat anything else as down.
Step 1: the health monitor
- Add an HTTP monitor on the health route for your wiki:
https://wiki.example.com/_health,/status, or/api/health. Expected status200, timeout10seconds. - On Pro, add the assertion that makes the body meaningful: contains
OKfor Outline, not_containsfalsefor BookStack (so a 200 with a false component, which should not happen but costs nothing to guard against, still fails), contains"redis"for Docmost to confirm the real health JSON came back rather than a proxy page. - For Wiki.js, monitor
https://wiki.example.com/loginwith expected200and, on Pro, containswikior another string you confirm is in the page source withcurl. Wiki.js answers a database outage with an error page or a long hang, so the keyword and the 10-second timeout are doing the work here.
Because the monitor goes through the public hostname, a green check also covers DNS, TLS, and the reverse proxy; SSL certificate monitoring is included on every plan, and a wiki's certificate expiring is exactly the kind of thing nobody notices until the incident call. Intervals are 3 minutes on Free and 1 minute on Pro; alerts go to your team's channels. For a wiki, send the alert somewhere that is not the wiki.
Step 2: a public document as a content canary (Pro)
Health proves the database answers SELECT 1. It does not prove the application can render a document, which is a separate failure when a bad upgrade, a broken migration, or a full disk for the search index takes the content layer down while the health route stays green. Each wiki can publish a page without login:
- Outline: share a document publicly (Share → publish to web) and monitor the share URL with contains a phrase from the document.
- BookStack: if public viewing is enabled, monitor a page URL; if not, create a public-visible "Status canary" page in a public shelf. Assert on its heading text.
- Docmost: public sharing of a page produces a
/share/…URL; monitor it with a keyword from the page. - Wiki.js: a page with guest read permission at a fixed path.
Make the canary page say something unique (canary-7f3a) so the assertion cannot match a navigation element or an error page. This monitor also catches the migration-in-progress state after an upgrade, when the app is up but every page is a 500. Keyword monitoring covers the match types; each monitor carries one assertion.
Step 3: the login page, and the SSO trap
Most wikis sit behind single sign-on, and many sit behind a proxy-level gate too: Cloudflare Access, Authelia, oauth2-proxy, or a corporate SSO proxy. The health route is exempt from the application's login, but a proxy gate in front of everything redirects it to the identity provider like any other path. The monitor follows the redirect, lands on the login page, gets a 200, and stays green while the wiki is down.
Two fixes. If the gate supports service tokens (Access does; most SSO proxies have a bypass header or path rule), put the token headers in the monitor's custom headers, or exempt the health path at the proxy. Otherwise, use a keyword assertion for something only the health response contains (OK, "database":true) so the login page fails the check. The Cloudflare Tunnel guide walks through the Access case, and monitoring the identity provider itself covers the outage that makes a healthy wiki unusable.
If the wiki is only reachable on a Tailscale or WireGuard network, HTTP monitors cannot reach it. Run curl --fail against the health route from a cron job on a machine inside the network and ping a heartbeat only on success, as in monitoring internal tools.
Step 4: attachments and search
Uploads are the second storage system in every wiki. Outline stores files locally under FILE_STORAGE_LOCAL_ROOT_DIR or in an S3-compatible bucket; BookStack under public/uploads and storage/uploads; Docmost locally, in S3, or in Azure. A wiki whose database is fine but whose storage bucket has the wrong credentials shows pages with broken images, which nobody reports because the text still loads. Upload one known image to the canary page and monitor its direct URL (Outline's and Docmost's attachment URLs are signed and expire, so for those use the public share page containing the image and assert on the image's markup; BookStack's /uploads/images/… URLs are stable and can be monitored directly). If the bucket is S3-compatible, monitoring MinIO and S3 storage covers the storage side.
Search is harder to check from outside because every search route requires login. The practical signal is the canary page: Outline and Docmost build search from the same PostgreSQL, so a document that renders is a document that is indexed. If search is critical, a cron script that logs in with a read-only account, searches for the canary string, and pings a heartbeat on a hit is twenty lines; most teams do not need it.
Step 5: backups (Pro)
BookStack's documentation is specific: mysqldump the database, and archive .env (it holds APP_KEY, without which the restore cannot decrypt stored values), public/uploads, storage/uploads, and themes. Outline needs pg_dump plus the local data directory or your bucket, and the SECRET_KEY from its environment. Docmost needs pg_dump plus its storage. Make the job report:
# /etc/cron.daily/bookstack-backup
set -euo pipefail
cd /var/www/bookstack
DEST=/srv/backups/bookstack/$(date +%F); mkdir -p "$DEST"
mysqldump -u bookstack -p"$DB_PASS" bookstack | gzip > "$DEST/db.sql.gz"
tar -czf "$DEST/files.tar.gz" .env public/uploads storage/uploads themes
# ship $DEST off the host: rclone copy "$DEST" remote:bookstack/$(date +%F) ...
curl -fsS --max-time 10 --retry 3 https://cronalert.com/api/heartbeat/YOUR-TOKEN Create a heartbeat monitor with an expected interval of 1 day and a grace of a few hours. set -e means a failed dump never reaches the ping. For Outline swap in pg_dump and tar of the storage directory, or an rclone sync of the bucket. Monitoring database backups covers restore testing, which for a wiki is worth doing once: the day you need the runbooks back is not the day to learn the APP_KEY was not in the archive.
What not to monitor
- Authenticated pages with a real user's session. A monitor holding a session cookie can read the whole wiki. Use the health route and a public canary page instead; if you must authenticate, use a dedicated read-only account and a script, not a monitor's headers.
- Outline's or Docmost's Redis directly. Both need Redis, and Docmost's health route already includes it. Outline's does not, but exposing Redis to check it is the wrong trade; a Redis outage in Outline shows up as failed logins and collaboration, which the canary page partly catches, and as errors in the container log.
- The admin or settings pages. They return 200 login redirects when locked and 200 when open; neither state is an outage. If anything, an inverse monitor expecting your proxy's 403 on an admin path proves the restriction holds, as the Vaultwarden guide does for
/admin.
Reading an alert
| Alert | Likely cause | First thing to check |
|---|---|---|
| Health route timeout or connection error | Host, container, or proxy down | Container status; proxy logs |
Outline /_health 500 | PostgreSQL unreachable | Postgres container; DATABASE_URL |
BookStack /status 500 | The false key names it: database, cache, or session | MySQL; cache driver (Redis or file permissions); session driver |
Docmost /api/health non-200 | Postgres or Redis ping failed | The JSON names which; both containers |
| Health green, canary page red | Migration running, app error, search/storage full | Application log; disk space |
| Health green, image canary red | Storage credentials or bucket policy changed | Storage config; bucket access |
| Everything 200 but keyword missing | Monitor landed on an SSO login page | Proxy gate; service-token headers |
| Certificate alert | Renewal stopped | Proxy or ACME logs |
| Backup heartbeat overdue | Cron not running, dump failed, destination full | Run the script by hand |
Frequently asked questions
Is /_health safe to leave public on Outline?
It returns OK or a 500 and nothing else, and the official Docker image polls it every minute itself. Leaving it reachable costs you nothing and is the only way to monitor the database connection from outside.
BookStack's /status returns 200 but my wiki is slow. Why?
The three checks are cheap and do not exercise search or page rendering. Slowness shows up on the canary page's response time and, past the timeout, as a failed check there; timeouts are the only slowness alarm an HTTP monitor has.
Can I put the wiki on a status page?
Yes, and an internal status page is a good home for internal tools: every plan includes one. Show the health monitor, not the canary, so the page does not leak a document URL.
Which parts are free?
The health route monitor (or Wiki.js login page) and certificate monitoring are free. The keyword assertions on health, the canary page and image monitors, and the backup heartbeat need Pro at $5/month.
Get started
One free monitor on the health route means the wiki's outage is reported by something other than the person who needed the runbook. Create a free CronAlert account and add it, then publish a canary page. Related reading: monitoring internal tools, monitoring Docker self-hosted services, monitoring Nextcloud and Immich, monitoring documentation sites, and incident response for small teams, which is where the runbooks come in.