# Checkmate: a self-hosted uptime monitor that grew into a status page

> AGPL-licensed TypeScript monitoring that checks HTTP, TCP, DNS and Docker, keeps incident history, publishes public status pages, and now ships as one container image next to MongoDB. The interesting parts are the encryption key rotation story and the fact that its Helm chart lags behind the image.

**bluewave-labs/Checkmate** — Checkmate is an open-source, self-hosted tool designed to track and monitor server hardware, uptime, response times, and incidents in real-time with beautiful visualizations. Don't be shy, join here: https://discord.com/invite/NAb6H3UTjK :)

- Repository: https://github.com/bluewave-labs/Checkmate
- Website: https://checkmate.so/
- Stars: 10,977 · Forks: 1,231
- Language: TypeScript
- License: AGPL-3.0
- Published: 2026-10-06 · Updated: 2026-10-06 · Language: en
- Canonical page: https://hysenlabs.com/projects/bluewave-labs-checkmate

## Getting a running instance from two commands

The prerequisites are Docker and Git, and the README calls the reference Compose file the quickest route. It starts two services: the Checkmate application image from `ghcr.io/bluewave-labs/checkmate` and a separate MongoDB.

```bash
curl -O https://raw.githubusercontent.com/bluewave-labs/checkmate/master/docker/docker-compose.yaml
JWT_SECRET="$(openssl rand -hex 32)" docker compose up -d
```

Then you open http://localhost:52345. The port is configurable through `PORT`, and `HEALTH_PORT`, default 52346, serves `/livez`, `/readyz` and `/metrics` from whichever process runs the job worker.

The README is unusually explicit about what all-in-one does and does not mean. The application is packaged in a single image, but MongoDB is not embedded in it and stays required. The reference file starts MongoDB for you, and a custom deployment is expected to set `DB_CONNECTION_STRING` to an external instance. Building the image locally is `docker build -f docker/Dockerfile -t checkmate .` from a checkout, and TLS is not the image's job: the instruction is to put any reverse proxy, Caddy, Traefik or nginx, in front of port 52345.

If you would rather not run Compose, there is a long list of one-click targets: Repocloud, PikaPods, Coolify, Elestio, Easypanel, Cloudzy, Sive Host and a Helm chart under `charts/helm/checkmate`.

## Four environment variables decide whether the deployment works

Configuration is entirely environment variables on the server container, and the README documents them in a table that is more precise than most. Three are required.

`DB_CONNECTION_STRING` takes a MongoDB URI such as `mongodb://mongodb:27017/uptime_db`. `JWT_SECRET` signs auth tokens and the suggested generation is `openssl rand -hex 32`, which is why the Compose one-liner passes a fresh one on the command line. `CLIENT_HOST` is the URL users actually reach the app at, and it does double duty: CORS validation plus the links embedded in notifications and emails.

The fourth variable is the one that deserves a paragraph of its own. `ENCRYPTION_KEY` is optional, but it is what encrypts stored Docker TLS client keys at rest. Two details are easy to get wrong. It accepts a comma-separated list, where the first key encrypts and every key decrypts, and it must be identical on the API and every worker, since a mismatch means some workers cannot read what others wrote.

The rotation procedure is documented without downtime in three deploys: send `OLD_KEY,NEW_KEY` everywhere, wait for the worker to re-encrypt every row, then send `NEW_KEY,OLD_KEY` everywhere, and only then drop `OLD_KEY`. The `HEALTH_PORT` split exists for the same reason, giving you a probe endpoint that does not depend on the main port being ready.

## What a monitor can check, and what Capture adds

The core loop is straightforward: Checkmate regularly checks whether a server or website is reachable and performing, then keeps real-time alerts and reports on availability, downtime and response time. The monitor types have widened noticeably across the three most recent releases.

Docker arrived as a first-class monitor type in v3.12.0, published 2026-09-13, with host and container detail pages, container logs viewable from the detail page, charts for container metrics, and TLS for remote Docker daemons with the client key encrypted at rest. v3.11.0, published 2026-08-26, added DNS monitors, domain registration expiry monitoring, selectable time ranges on status pages and outbound proxy support at both global and per-monitor level.

Hardware metrics come from a separate project. Capture is the optional agent, and the README is careful that it is not required to run Checkmate. What it adds is CPU, RAM, disk and temperature readings from remote machines, and it can run anywhere Go runs, which the README lists as Linux, Windows, Mac, Raspberry Pi.

The performance claim is a single sentence: stress-tested with more than 1000 active monitors with no particular issues or performance bottlenecks. That is the README's own framing rather than a published benchmark, so treat the number as a claim to check against your own monitor count.

## The single-image migration that broke the old deployment names

v3.10.0, published 2026-07-28, is the release to read before deploying anything, and its notes are written as an action item rather than a changelog. Checkmate now ships as a single image, `ghcr.io/bluewave-labs/checkmate`, and the per-service images `checkmate-client`, `checkmate-backend`, `checkmate-mongo` and `checkmate-backend-mono` are deprecated.

The instructions say to switch to the new docker-compose.yaml, that the database and data are unaffected, and that migrations run automatically on first start. The `checkmate-backend-mono` tag is called out separately as a transitional alias that will not be updated again, with a direct warning not to pin `:latest` on it because it has not received updates since the rework merged and this release is the last published under that name.

The same release records a major backend refactor into domain layers for monitors, checks and incidents, plus route, controller and utils cleanup. That is the kind of change that leaves a large surface of small behaviour changes, and a few are named: incidents are now deleted when their monitor is, the status page custom CSS injection is fixed, CSP configuration is fixed, and the JSON body limit was raised.

The migration risk is on the deployment side, not the data side, which is the good version of this kind of change. The one place it lingers is the Helm chart, covered below.

## The Helm chart is pinned to the world that just ended

The README flags this without much ceremony, and it is the most useful sentence in the installation section for anyone running Kubernetes. The Helm chart has not yet been migrated to the all-in-one image: it still deploys the legacy `checkmate-client`, `checkmate-backend` and `checkmate-mongo` images, pinned at v3.8.1.

So a cluster deployment is not on v3.12.0. It is roughly four releases behind, and it is missing everything in those releases, which includes Docker monitoring as a monitor type, container logs, outbound proxy support, domain expiry monitoring, the encryption module with key rotation, and the Signalgrid and Rocket.Chat notification channels. That is a substantial gap for a project whose whole value is knowing when something is down.

The chart's own install instructions live at `charts/helm/checkmate/INSTALLATION.md`, so the chart is a separate artifact with its own maintenance cadence. Nothing in the README says when it will be migrated, which means the practical approach is to check the chart's image tags yourself rather than assume they track the main release line.

This is also the honest test of the project's upgrade story. The Compose path is in good shape and the data survives. The Helm path is behind and will stay behind until someone updates it.

## How it sits against Uptime Kuma and a hosted service

The repository topics name `uptimerobot` and `uptimerobot`-adjacent terms alongside `statuspage` and `uptime-status`, which tells you the comparison the project has in mind. The hosted services in that space give you monitoring without anything to operate, and that is a real advantage when nobody on the team wants to own a container that fails silently.

Against Uptime Kuma specifically, Checkmate's differentiators are on the infrastructure side rather than the uptime side. Docker containers became monitor types, Capture reaches hardware metrics on remote machines, and TLS for remote Docker daemons means the connection is authenticated rather than plaintext on the network. v3.12.0 also adds an encryption module for secrets with key rotation, which is the sort of feature that shows up in a security review.

The public status page is a genuine second product here, with selectable time ranges, monitor tags in the selector, domain expiry monitoring feeding into it, and maintenance windows that carry tags. If your external users need to see incidents, that is a differentiator against a bare ping monitor.

The trade is licence and effort. AGPL-3.0 obliges you to offer source for a modified version you serve over a network, which is a real constraint for some organisations, and the default branch is `develop`, so a casual `git pull` of the wrong branch is a genuine footgun. The repository also ships a `CLAUDE.md`, a `Checkmate.CodeCanvas` directory and 122 open issues, which reads like a project with an active contributor community and a correspondingly long queue.

## Conclusion

Checkmate suits a small team that wants uptime monitoring and public status pages on its own hardware, without a vendor bill and without an agent on every machine. Skip it if you need the fleet-scale features of a dedicated observability platform, or if the AGPL-3.0 licence conflicts with how you intend to distribute a modified build. Concretely: run the reference Compose file to get a feel for the UI, read the environment variable table for `ENCRYPTION_KEY` and `CLIENT_HOST` before you put anything behind TLS, and note that the Helm chart at `charts/helm/checkmate` still deploys the pre-3.10 per-service images pinned at v3.8.1 rather than the all-in-one image everyone else uses.

## FAQ

### What does Checkmate monitor?

Uptime, response times and incidents for HTTP endpoints, plus DNS monitors added in v3.11.0. v3.12.0 made Docker containers a monitor type in their own right, with host and container detail pages, container logs and TLS for remote daemons. Hardware metrics come from the optional Capture agent, which reports CPU, RAM, disk and temperature from remote machines.

### Do I need MongoDB to run Checkmate?

Yes. The all-in-one image packages the application only, and the README says MongoDB is not embedded in it and remains required. The reference Compose file starts a MongoDB service for you, and a custom deployment points `DB_CONNECTION_STRING` at an external instance such as `mongodb://mongodb:27017/uptime_db`.

### What is the Capture agent and is it required?

Capture is a separate project for pulling data from remote servers, and the README states it is not required to run Checkmate. What it adds is hardware visibility: CPU, RAM, disk and temperature. It runs anywhere Go runs, which the README lists as Linux, Windows, Mac and Raspberry Pi.

### What licence is Checkmate under?

AGPL-3.0. That matters more than most licences for a self-hosted web application, because it obliges you to offer source for a modified version you make available over a network. Read the LICENSE file before forking a deployment you intend to change.

## Sources

- [bluewave-labs/Checkmate on GitHub](https://github.com/bluewave-labs/Checkmate)
- [License: AGPL-3.0](https://github.com/bluewave-labs/Checkmate/blob/develop/LICENSE)
- [Project website](https://checkmate.so/)
- [README](https://github.com/bluewave-labs/Checkmate/blob/develop/README.md)
- [Releases](https://github.com/bluewave-labs/Checkmate/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/bluewave-labs-checkmate
