Launching Laravel Health
I released cboxdk/laravel-health today. Installed it on cbox.dk, opened the dashboard, and immediately found two bugs. The OS version showed "unknown" and my Hetzner VM was detected as a container. Dogfooding works.
I released cboxdk/laravel-health today. Health checks, Kubernetes probes, Prometheus metrics, and a live dashboard for Laravel applications. Built on top of System Metrics for the system-level data.
I installed it on this site, opened the dashboard, and immediately found two bugs.
The package
One composer require gives you:
/health- liveness probe (database connectivity)/health/ready- readiness probe (database, cache, storage)/health/metrics- Prometheus format with system metrics/health/ui- live dashboard with auto-refresh
10 built-in checks (database, cache, queue, storage, Redis, CPU, memory, disk space, environment, schedule), token and IP-based auth, response caching, and an extensible architecture for custom checks. 113 tests, PHPStan level 9.
The bugs
I deployed it on cbox.dk, which runs on a Hetzner CAX arm64 VM with Ubuntu 24.04. Opened the dashboard and saw this:
Two problems. OS version showing "unknown" when it should show "24.04". And environment showing "Container" when it's a plain VM.
Bug 1: OS version "unknown"
System Metrics reads /etc/os-release for OS information. On Ubuntu, that file exists and contains VERSION_ID="24.04". So why "unknown"?
The FileReader has a security whitelist for allowed paths. It also uses realpath() to resolve symlinks and re-validates the resolved path against the whitelist. On systemd distros, /etc/os-release is a symlink to /usr/lib/os-release. The whitelist had /etc/os-release but not /usr/lib/os-release. The read silently failed and fell through to the "unknown" fallback.
One-line fix: add /usr/lib/os-release to the whitelist.
Bug 2: VM detected as container
The container detection in System Metrics was checking if cgroup data existed. If the system had cgroup v1 or v2, it assumed container. But cgroup v2 is the default on modern Linux - Ubuntu 22.04+, Debian 12+, Fedora 31+ - even on bare metal. Every modern VM reports cgroup v2. That isn't the same as being in a container.
I went through three iterations before getting this right. First I tried checking PID 1's cgroup path, assuming root / means VM. On the Hetzner box, PID 1 is in /init.scope - not root. Then I added an exclusion for init.scope, but that's systemd-specific and wouldn't work on OpenRC, runit, or other init systems.
The correct approach: stop trying to prove a negative. Instead of "this doesn't look like a container," only detect containers by checking for known container indicators. An allowlist, not heuristics.
The final detection checks three things, in order of reliability:
Sentinel files:
/.dockerenv(Docker),/run/.containerenv(Podman)PID 1 environment:
container=variable set by LXC and systemd-nspawnCgroup keywords:
kubepods,docker,containerd,crio,lxcin cgroup paths
No match means not a container. No heuristics, no exclusion lists, no edge cases to maintain.
Dogfooding
Both bugs were found within minutes of deploying on my own site. The OS detection bug had been there since v2.0 - over a year. Nobody reported it because the library worked correctly everywhere else: inside Docker containers (no symlink resolution needed for /proc files) and on macOS (different detection path entirely). It took running on a plain Linux VM to surface it.
The container detection bug was more fundamental. The assumption that "cgroup = container" was baked into the architecture. It required rethinking the detection strategy entirely, not just patching edge cases.
Both are fixed in system-metrics v2.3.1 and laravel-health v1.0.1. The dashboard now correctly shows Ubuntu 24.04.3 LTS, no container section, and environment "Host":
Install
composer require cboxdk/laravel-health
Full documentation: laravel-health docs.