Sponsor Swag
Esc

Self-hosted monitoring · AGPLv3 · in development

Signals stacked and
left for someone to read.

Cairn OBS watches your networks, hosts, services and clusters, and answers "is everything OK?" in one screen. An agent on each host reports to one server, which judges the readings, draws the maps, sends the alerts and writes the reports. It reads and never changes anything, and it runs on your own hardware, from a single container to a cluster watching thousands of VMs and pods.

AGPLv3 — no paid tierGo · SvelteSQLite or PostgreSQLDebian, Ubuntu, RHEL · amd64, arm64
cairn obs · dashboard
The Cairn OBS dashboard: 121 of 121 hosts reporting, six cards that need attention, led by a failed drive on a Pure array, and gauges for hosts reporting, busiest CPU, fullest disk and containers.

A test fleet of 121 hosts, two clusters, three hypervisors and two Pure arrays.

Features

Everything you run, on one screen

Hosts, services, clusters, storage and secrets, judged in one place, so one broken thing shows as one problem and not forty alerts.

◇

Hosts and services

CPU, memory, disks and their fill dates, network, RAID and SMART, Docker containers and systemd units that should be running, and backups that should be fresh. Tell it what's running now and it expects that from then on.

▤

Checks from every side

Websites, TLS certificates, DNS records, mail and other servers' banners, open ports and ping, run from each host. A service is down only when two vantage points agree, so one bad network path doesn't wake anyone.

▲

Maps drawn from what's running

The network map and the service map are worked out from what the agents see, interfaces, tunnels, containers and listening services, not from a file someone forgot to update. Correct them once and the corrections stick.

◈

Clusters and VMs

Pods and VMs on Kubernetes, OpenShift and OKD, KubeVirt, libvirt, Proxmox, vSphere and Nutanix, read from their APIs. No agent inside every pod or VM, and a VM is linked to the host it runs on.

●

Storage and secrets

Pure FlashArray and FlashBlade health, capacity and performance history, matched to the volumes your clusters use. HashiCorp Vault and OpenBao seal, HA and Raft state, leases and every PKI certificate.

✦

Alerts and reports

Alerts to ntfy, Discord, email, PagerDuty or a webhook, each with its own level, plus maintenance windows and acknowledgements. Reports on uptime, incidents, certificate expiry, disk forecasts and backup freshness.

network map
The network map: three subnets linked to the internet, and below them two Kubernetes clusters, two Pure arrays, Proxmox, vCenter and Prism Central, with the ones that need a look listed on the right.
Network mapSites, the hosts in them and how they link, worked out from what the agents see. Clusters, hypervisors and arrays sit beside them.
service map
The service map: services grouped by subnet and cluster, with newly found services and dependencies such as stack needs postgresql on port 5432 waiting to be confirmed.
Service mapWhat depends on what, found from who talks to whom. New services and links wait for you to confirm them.
clusters
The clusters page: cluster-00 with 12 of 12 nodes ready and 886 workloads, and cluster-01 on OpenShift updating to 4.20.4 with a degraded ingress operator.
ClustersNodes, pods, VMs and volumes by state, plus OpenShift's own view of an upgrade in progress.

Read-only

It looks, it never touches

There's no remote shell and no "restart this" button. The agent reads the host, and the few things that need root go through a small helper that can only read. A stolen Cairn OBS session shows someone your dashboards. It doesn't hand them your servers.

  • No commands run on monitored hosts, ever
  • Read-only API tokens for clusters, arrays and Vault
  • Every change to settings is in the audit log

Sign-in

Your directory, your roles

Start with local users, with passkeys or a password and a one-time code, then connect any OpenID Connect provider: Okta, Entra ID, Google, Keycloak and the rest. Viewers see the dashboards, operators also see log lines and the audit log, and admins change settings.

  • Local users with passkeys, or password plus TOTP
  • Generic OpenID Connect, roles from groups or addresses
  • Viewer, operator and admin roles

How it works

One agent per host, one server

obs-beacon-agent reads each host and reports to obs-beacond, which judges the readings, runs the alerts and serves the web interface.

Reports, over mutual TLSReads, state and what you see

agents → obs-beacond → {database, web interface, alerts}

◇

Add a host with one line

Add host gives you a single install command with a one-time join token. The agent installs from the package, makes its own key, and the server's built-in certificate authority signs it. The token expires in an hour and works once.

▤

Mutual TLS, always

Agents and the server talk over TLS with a client certificate on every agent. Nothing is plain HTTP, and nothing depends on a VPN to be safe.

▲

Nothing lost when the link drops

If the server can't be reached, the agent queues its reports on disk and sends them when it's back, so the history has no hole in it.

◈

Configure it in the browser

Checks, alert channels, maintenance windows and expected containers are set in the web interface. Prefer files? A config file wins over the interface for its section, and you can export and import YAML.

●

One cluster agent per cluster

A cluster agent reads the Kubernetes API and the hypervisors' APIs and reports workloads in bulk, so thousands of pods and VMs come in without thousands of agents.

✦

Signed releases

Every release has .deb and .rpm packages and static binaries for amd64 and arm64, checked against SHA256SUMS signed with the Cairn OBS minisign key.

Where it runs

One container, or a cluster of them

The same server binary runs as a single container on a small box, or as several copies sharing PostgreSQL in Kubernetes or OpenShift.

Small

One container, one file

Install the server package, or run its container with Docker or Podman. It keeps everything in one SQLite file, gets its own certificate from Let's Encrypt if you give it a hostname, and prints a one-time setup link on first start. Nothing else to run.

  • .deb and .rpm packages, or one container
  • Built-in ACME for its own certificate
  • First admin made from a one-time link

Large

Several copies on PostgreSQL

For a big fleet, run several copies on one PostgreSQL database. Only one of them sends alerts at a time, and they upgrade one by one, so the web interface and the agents' endpoints stay up through an upgrade. It's built to watch thousands of VMs, pods and containers; what testing measured is below.

  • Runs under OpenShift's restricted-v2 security context, unchanged
  • Kustomize bases for OpenShift, OKD and plain Kubernetes
  • Rolling upgrades with no gap
Agent reports and traffic inBrowsers and shared state

load balancer → copies of obs-beacond → one PostgreSQL

PartChoiceWhy
Server and agentGoStatic binaries with no runtime to install, for amd64 and arm64.
Web interfaceSvelte 5, TypeScriptBuilt to static files and served by the server itself, so there's no second service.
StorageSQLite or PostgreSQLOne file for a small install; a shared database when you run several copies.
HostsDebian, Ubuntu, RHEL familyWith systemd, on amd64 and arm64. Windows, Alpine and macOS agents are planned.
ClustersKubernetes, OpenShift, OKDRead-only service account. The server image runs as any user ID with a read-only root.
Releasesminisign, SHA256SUMSEvery file checked, and the checksum list signed.

Measured

1,000 hosts and 10,000 workloads, nothing lost

The load test runs fake agents and fake clusters against real copies of obs-beacond. On 13 November 2026, on one workstation: two copies on PostgreSQL, 1,000 host agents reporting every 15 seconds, and three clusters with 9,000 pods, 900 VMs and their controllers between them, two pods changing every second in each. Partway through, both copies were restarted one at a time. Eight minutes:

MeasuredResultDetail
Host reports2.6 ms at p9932,000 sent, 32,000 taken, none lost, through both restarts.
Pages19 ms at p99A page every half second, the Workloads and Clusters pages among them.
Cluster changes61 ms at p95From a change in one cluster to it showing on both copies.
Restarts3.3 sEach copy out of the load balancer within 0.5 s of stopping and ready again 3.3 s later, with alerts moving to the other copy.
MemoryAbout 75 MBPer copy, for all 1,000 hosts and the three clusters.

License

AGPLv3 — the whole thing, no exceptions

Every feature on this page ships under the same license. There's no paid tier and no locked features.

Self-host it, fork it, run it as a service. The license terms are the same for everyone, including us. There's no separate commercial edition: the code you can read is the code that runs.

AGPLv3's network-use clause means that if you change Cairn OBS and offer it to others over a network, including as a hosted service, you have to make your changed source available to those users too. That's on purpose. It's the same protection that keeps this project from being taken closed-source downstream.

Full license text

The complete AGPLv3 terms apply to everything in the repository, with no per-component exceptions.

Read AGPLv3 →

About the name

A cairn is a message left for
whoever comes after you.

The name is the working metaphor for what this monitor does.

The name

Stones, stacked so they can be read at a glance

A cairn is one of the oldest pieces of infrastructure people build: a pile of stones, placed by hand, left on a trail so that someone who comes later, a stranger who never met the person who built it, can look at it and know someone was here, and this is the way through. Hill-walkers use them. Arctic travellers build Inuksuit for the same reason. Long before GPS, a cairn was the original out-of-band signal: unattended, and readable by anyone who knew how.

That's what a monitor should be. Whoever is on call at 3 a.m. didn't set it up and wasn't there when the problem started. They need to look at one screen and see what's wrong, where, and what it's taking down with it. Each reading is a pebble. The monitor is the cairn: the stones stacked into something you can find your way by, in exactly the conditions a cairn was built for, poor visibility and somebody who needs to get through.

Signals stacked, and left for someone to read.

OBS is just what it says on the label: observability.

Why this exists

Monitoring shouldn't be a project of its own

Most monitoring ends up as one of two things. A hosted service that bills per host and holds your data somewhere else, or a stack you assemble yourself: a metrics store, an exporter for every kind of thing, a dashboard tool, an alert router, and a pile of hand-written configuration tying them together, which nobody has time to keep current.

Cairn OBS is one agent per host and one server. It works out the layout from what's actually running, it's set up in the browser, and it reads clusters, hypervisors, storage arrays and Vault directly. It never runs commands on what it watches. And it ships AGPLv3, so the monitor you depend on during an outage is one whose source you can read.

It started as the monitor for Coffey Labs' own servers, and it runs there first. Log aggregation, the original Cairn OBS, comes back later, rebuilt on this design and fed by the same agent.