github kOlapsis/maintenant v1.2.14
Degraded mode & runtime-optional startup

latest releases: v1.3.5, v1.3.4, v1.3.3...
one month ago

The headline of this release is that maintenant no longer needs a container runtime to start. The Docker / Kubernetes socket becomes an observable dependency rather than a startup gate: the app always boots, serves the UI and API, and surfaces a missing runtime as a degraded state that recovers on its own.

This release also fixes a long-standing retention bug that left archived containers piling up forever.


Degraded runtime startup

Previously, maintenant exited at startup if the Docker or Kubernetes socket was unreachable. That made the tool unusable for two common situations: monitoring only endpoints / SSL / heartbeats with no local runtime, and surviving a daemon restart or a host deploy without crashing.

The runtime connection is now non-blocking and non-fatal. The app starts in every case and treats "no runtime" as a first-class state.

How it behaves

  • Bounded connect attempt. A new TryConnect(ctx) (~3s budget) probes the runtime at startup ? Docker Ping, Kubernetes ServerVersion under a context timeout. On failure the app logs a warning and continues; Swarm detection is guarded behind IsConnected().
  • Auto-recovery. A background supervisor loop keeps trying to connect. When the runtime comes back, container monitoring (reconcile + event stream) is wired exactly once per connection cycle ? no duplicate watchers, no manual restart.
  • Daemon loss detection. If the event stream closes (the daemon goes away mid-run), the runtime is marked disconnected and a runtime.availability_changed SSE event is broadcast so connected clients react in real time.
  • Last-known data stays visible. Container read endpoints (list / detail / transitions) keep serving the last persisted state and add "stale": true when the runtime is disconnected, so the UI can label the data instead of going blank.
  • Live actions fail cleanly. Endpoints that require a live runtime (e.g. the log stream) return 503 {"error":"container monitoring unavailable"} instead of panicking.
  • No stats spam. The resource collector skips StatsSnapshot ticks while disconnected; host-stat collection continues unaffected.

API & health

GET /api/v1/health now reports the runtime state:

{
  "runtime": { "name": "docker", "connected": false }
}

Container read payloads carry "stale": true while the runtime is down.

UI

A new RuntimeDegradedBanner (semantic CSS variables only, light + dark) appears on the Containers and Dashboard pages while the runtime is unavailable, and disappears automatically when it recovers ? driven by the runtime.availability_changed SSE event via the runtime store. Endpoint, Certificate, and Heartbeat surfaces are unaffected and show no banner, since those monitors never needed a runtime.

This also enables a deliberate workflow: pause container monitoring during a deployment by stopping the daemon, without maintenant crash-looping ? monitoring resumes on its own once the runtime is back.


Fixes

  • Retention purge unblocked (#25). The retention loop could fail with FOREIGN KEY constraint failed when deleting an archived container that still had surviving children (state transitions, resource snapshots, or a resource alert config ? the latter is never purged). The three child tables lacked ON DELETE CASCADE, so archived rows accumulated indefinitely. Migration 21_containers_cascade_delete rebuilds state_transitions, resource_snapshots, and resource_alert_configs with ON DELETE CASCADE on container_id, so an archived container and its history are now dropped atomically.

Internals & CI

  • OCI standard labels added to the Dockerfile for better registry metadata.
  • LICENSE_PUBLIC_KEY moved to a repository variable (not a secret) in the Docker build workflow. The key is public by nature, so it stays inspectable in build logs instead of being masked.

Upgrade notes

  1. Nothing to configure for degraded mode ? it is the default behavior as of v1.2.14. Deployments that only monitor endpoints / SSL / heartbeats can now run with no Docker or Kubernetes socket mounted at all.
  2. Migration 21_containers_cascade_delete runs automatically at startup. It rebuilds three tables; on large histories this is a one-time operation at first boot. A down.sql is provided (rebuilds the tables without the cascade) should you need to roll back to v1.2.13.
  3. No new environment variables.

Documentation

  • Updated: Containers (new Degraded Mode section: auto-recovery, last-known data, 503 on live actions, real-time SSE banner), Configuration.

Don't miss a new maintenant release

NewReleases is sending notifications on new releases.