Monitor everything. Manage nothing.
Drop a single container. Your entire stack is monitored in seconds.
Documentation • Quick Start • Features • Configuration • API
Most self-hosters juggle 3-5 tools to monitor their stack: one for containers, one for uptime, one for certs, one for metrics, and yet another for a status page. maintenant replaces all of them.
| maintenant | Uptime Kuma | Portainer | Dozzle | |
|---|---|---|---|---|
| Container auto-discovery | Yes | No | Yes | Yes |
| HTTP/TCP endpoint checks | Yes | Yes | No | No |
| Cron/heartbeat monitoring | Yes | Yes | No | No |
| SSL certificate tracking | Yes | Yes | No | No |
| CPU/memory/network metrics | Yes | No | Limited | No |
| Image update detection | Yes | No | Yes | No |
| Network security insights | Yes | No | No | No |
| Public status page | Yes | Yes | No | No |
| Alerting (webhook, Discord) | Yes | Yes | Limited | No |
| Kubernetes native | Yes | No | Yes | No |
| Single binary, zero deps | Yes | Node.js | Docker API | Docker API |
One container. One dashboard. Everything monitored.
# docker-compose.yml
services:
maintenant:
image: ghcr.io/kolapsis/maintenant:latest
ports:
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /proc:/host/proc:ro
- maintenant-data:/data
environment:
MAINTENANT_ADDR: "0.0.0.0:8080"
MAINTENANT_DB: "/data/maintenant.db"
restart: unless-stopped
volumes:
maintenant-data:docker compose up -dOpen http://localhost:8080 — your containers are already there. No configuration needed.
kubectl apply -f deploy/kubernetes/maintenant auto-detects the in-cluster API. Read-only RBAC, namespace filtering, workload-level monitoring out of the box.
For detailed setup instructions, advanced configuration, and label reference, see the full documentation.
Zero-config auto-discovery for Docker and Kubernetes. Every container is tracked the moment it starts — state changes, health checks, restart loops, log streaming with stdout/stderr demux. Compose projects are auto-grouped. Kubernetes workloads (Deployments, DaemonSets, StatefulSets) are first-class citizens.
Define HTTP or TCP checks directly as Docker labels — no config files, no UI clicks. maintenant picks them up automatically when a container starts. Response times, uptime history, 90-day sparklines, configurable failure/recovery thresholds.
labels:
maintenant.endpoint.http: "https://api:3000/health"
maintenant.endpoint.interval: "15s"
maintenant.endpoint.failure-threshold: "3"Create a monitor, get a unique URL, add one curl to your cron job. maintenant tracks start/finish times, durations, exit codes, and alerts you when a job misses its deadline.
# One-liner for any cron job
curl -fsS -o /dev/null https://now.example.com/ping/{uuid}/$?Automatic detection from your HTTPS endpoints, plus standalone monitors for any domain. Alerts at 30, 14, 7, 3, and 1 day before expiry. Full chain validation.
Real-time CPU, memory, network I/O, and disk I/O per container. Historical charts from 1 hour to 30 days (Pro). Per-container alert thresholds with debounce to avoid noise. Top consumers view for instant triage.
Automatic detection of dangerous network configurations across your containers. Flags ports binding to 0.0.0.0, exposed database ports, host-network mode, privileged containers, and Kubernetes-specific risks (NodePort, LoadBalancer without NetworkPolicy). Each container image is mapped to its software ecosystem via OCI manifest inspection for CVE-relevant context.
Knows when your images have updates available. Scans OCI registries, compares digests. Compose-aware update and rollback commands with the correct --project-directory flag. Stop running docker pull blindly.
Unified alerts across all monitoring sources. Webhook and Discord channels included. Silence rules for planned maintenance. Exponential backoff retry on delivery. Slack, Teams, and email channels available with maintenant Pro.
Give your users a clean, real-time status page. Component groups, live SSE updates, severity aggregation across all monitors.
Built-in Model Context Protocol server. Query your infrastructure, read logs, and check alert status from any MCP-compatible AI assistant. Supports both stdio and Streamable HTTP transports with full OAuth2 authentication for remote clients (Claude web, Claude mobile, Claude Desktop).
| Variable | Default | Description |
|---|---|---|
MAINTENANT_ADDR |
127.0.0.1:8080 |
HTTP bind address |
MAINTENANT_DB |
./maintenant.db |
SQLite database path |
MAINTENANT_BASE_URL |
http://localhost:8080 |
Base URL (used for heartbeat ping URLs) |
MAINTENANT_ORGANISATION_NAME |
Maintenant |
Organisation name on the status page |
MAINTENANT_CORS_ORIGINS |
same-origin | CORS allowed origins (comma-separated) |
MAINTENANT_RUNTIME |
auto-detect | Force docker or kubernetes |
MAINTENANT_MAX_BODY_SIZE |
1048576 |
Max request body size in bytes (1 MB) |
MAINTENANT_UPDATE_INTERVAL |
24h |
Update intelligence scan interval |
MAINTENANT_LICENSE_KEY |
— | Pro license key (enables Pro features) |
MAINTENANT_MCP |
false |
Enable MCP server (Streamable HTTP on /mcp) |
MAINTENANT_MCP_CLIENT_ID |
— | OAuth2 client ID for MCP authentication |
MAINTENANT_MCP_CLIENT_SECRET |
— | OAuth2 client secret for MCP authentication |
MAINTENANT_K8S_NAMESPACES |
all | Namespace allowlist (comma-separated) |
MAINTENANT_K8S_EXCLUDE_NAMESPACES |
none | Namespace blocklist |
Full configuration reference in the documentation.
Container settings
labels:
maintenant.ignore: "true" # Exclude from monitoring
maintenant.group: "backend" # Custom group name
maintenant.alert.severity: "critical" # critical | warning | info
maintenant.alert.restart_threshold: "5" # Restart loop threshold
maintenant.alert.channels: "ops-webhook" # Route to specific channelsEndpoint monitoring
labels:
# Simple — one endpoint per container
maintenant.endpoint.http: "https://app:8443/health"
maintenant.endpoint.tcp: "db:5432"
# Indexed — multiple endpoints per container
maintenant.endpoint.0.http: "https://app:8443/health"
maintenant.endpoint.1.tcp: "redis:6379"
# Tuning
maintenant.endpoint.interval: "30s"
maintenant.endpoint.timeout: "10s"
maintenant.endpoint.http.method: "POST"
maintenant.endpoint.http.expected-status: "200,201"
maintenant.endpoint.http.tls-verify: "false"
maintenant.endpoint.http.headers: '{"Authorization":"Bearer tok"}'
maintenant.endpoint.failure-threshold: "3"
maintenant.endpoint.recovery-threshold: "2"TLS certificate monitoring
labels:
maintenant.tls.certificates: "example.com:443,api.example.com:443"Full stack example
services:
maintenant:
image: ghcr.io/kolapsis/maintenant:latest
ports:
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /proc:/host/proc:ro
- maintenant-data:/data
environment:
MAINTENANT_ADDR: "0.0.0.0:8080"
MAINTENANT_DB: "/data/maintenant.db"
api:
image: myapp:latest
labels:
maintenant.group: "production"
maintenant.endpoint.http: "http://api:3000/health"
maintenant.endpoint.interval: "15s"
maintenant.alert.severity: "critical"
maintenant.alert.channels: "ops-webhook"
postgres:
image: postgres:16
labels:
maintenant.endpoint.tcp: "postgres:5432"
maintenant.alert.severity: "critical"
redis:
image: redis:7-alpine
labels:
maintenant.endpoint.tcp: "redis:6379"
volumes:
maintenant-data:maintenant does not include built-in authentication — by design.
Like Dozzle, Prometheus, and most self-hosted monitoring tools, maintenant is designed to sit behind your existing reverse proxy + auth middleware. No need to manage yet another set of user accounts.
Internet -> Reverse Proxy (Traefik / Caddy / nginx)
-> Auth (Authelia / Authentik / OAuth2 Proxy)
-> maintenant
Example: Traefik + Authelia
services:
maintenant:
image: ghcr.io/kolapsis/maintenant:latest
labels:
traefik.enable: "true"
traefik.http.routers.maintenant.rule: "Host(`now.example.com`)"
traefik.http.routers.maintenant.middlewares: "authelia@docker"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /proc:/host/proc:ro
- maintenant-data:/data
environment:
MAINTENANT_ADDR: "0.0.0.0:8080"
MAINTENANT_DB: "/data/maintenant.db"
MAINTENANT_BASE_URL: "https://now.example.com"Note:
/ping/{uuid}(heartbeat pings) and/status/(public status page) are meant to be publicly accessible. Configure your proxy rules accordingly.
| Source | Events | Default Severity |
|---|---|---|
| Container | restart_loop, health_unhealthy |
Warning |
| Endpoint | consecutive_failure |
Critical |
| Heartbeat | deadline_missed |
Critical |
| Certificate | expiring, expired, chain_invalid |
Critical |
| Resource | cpu_threshold, memory_threshold |
Warning |
| Update | available |
Info |
Deliver to Discord or any HTTP webhook. Slack, Teams, and email available with maintenant Pro.
Full REST API under /api/v1/ for automation and integration.
Endpoint reference
| Resource | Endpoints |
|---|---|
| Containers | GET /containers GET /containers/{id} GET /containers/{id}/transitions GET /containers/{id}/logs |
| Endpoints | GET /endpoints GET /endpoints/{id} GET /endpoints/{id}/checks GET /endpoints/{id}/uptime/daily |
| Heartbeats | GET POST /heartbeats GET PUT DELETE /heartbeats/{id} POST /heartbeats/{id}/pause|resume |
| Certificates | GET POST /certificates GET PUT DELETE /certificates/{id} |
| Resources | GET /containers/{id}/resources/current|history GET /resources/summary|top |
| Alerts | GET /alerts GET /alerts/active GET POST /channels GET POST /silence |
| Webhooks | GET POST /webhooks POST /webhooks/{id}/test |
| Status Page | GET POST /status/groups|components|incidents|maintenance |
| Updates | GET /updates POST /updates/scan |
| Security | GET /security/insights GET /security/summary GET /security/insights/{id} |
| Events | GET /containers/events (SSE stream) |
| Health | GET /health |
┌──────────────────────────────────────────────────────┐
│ Single Go Binary │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ Vue 3 + TypeScript + Tailwind (embed.FS) │ │
│ │ Real-time SSE · uPlot charts · PWA │ │
│ └────────────────────────────────────────────┘ │
│ | │
│ ┌────────────────────────────────────────────┐ │
│ │ REST API v1 + SSE Broker │ │
│ └────────────────────────────────────────────┘ │
│ | | │
│ ┌─────────────┐ ┌──────────────────────┐ │
│ │ Docker │ │ Kubernetes │ │
│ │ Runtime │ │ Runtime │ │
│ └─────────────┘ └──────────────────────┘ │
│ | | │
│ ┌────────────────────────────────────────────┐ │
│ │ Containers · Endpoints · Heartbeats · │ │
│ │ Certificates · Resources · Alerts · │ │
│ │ Updates · Security · Status Page · │ │
│ │ Webhooks │ │
│ └────────────────────────────────────────────┘ │
│ | │
│ ┌────────────────────────────────────────────┐ │
│ │ SQLite (WAL · single-writer · zero │ │
│ │ external dependencies) │ │
│ └────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────┘
- Single binary — Frontend embedded via
embed.FS. One file to deploy. - Zero dependencies — SQLite is the only database. No Redis, no Postgres, no message queue.
- Real-time — SSE pushes every state change to the browser instantly.
- Read-only — maintenant never touches your containers. Observe only.
- Label-driven — Configure monitoring through Docker labels. No YAML to maintain.
- ~17 MB RAM — Lightweight enough to run on any VPS or Raspberry Pi.
maintenant is fully functional out of the box. The Pro Edition is available for teams that need advanced alerting, vulnerability intelligence, and extended notification channels.
| Feature | Community | Pro |
|---|---|---|
| Container auto-discovery | x | x |
| Endpoint monitoring (HTTP/TCP) | x | x |
| Heartbeat/cron monitoring | x (10 max) | x (unlimited) |
| TLS certificate monitoring | x | x |
| Resource metrics | x | x |
| Network security insights | x | x |
| Update intelligence (digest scan) | x | x |
| Alert engine (fire, recover, silence) | x | x |
| Webhook + Discord channels | x | x |
| Public status page (components, groups) | x | x |
| REST API + SSE + MCP | x | x |
| PWA support | x | x |
| Slack, Teams, Email channels | x | |
| Alert escalation + routing | x | |
| Maintenance windows | x | |
| Security posture dashboard | x | |
| CVE enrichment + risk scoring | x | |
| Incident management | x | |
| Subscriber notifications | x |
To activate Pro, set your license key in the environment:
MAINTENANT_LICENSE_KEY=your-license-keyLearn more at kolapsis.github.io/maintenant.
Contributions are welcome! Please open an issue first to discuss what you'd like to change.
Copyright 2025-2026 Benjamin Touchard / kOlapsis — Bordeaux, France
Licensed under the GNU Affero General Public License v3.0 (AGPL-3.0) or a commercial license.







