Initial public release — Inspector v0.7.0
Docker-watchdog with per-container restart rules, Gotify/Pushover notifications, and an embedded dashboard + web settings page. See README.md for an overview and INSTALL.md for the Docker quickstart.
This commit is contained in:
commit
ea1103f52b
35 files changed
+5579
No files matched your search
@@ -0,0 +1,139 @@
|
||||
# Inspector
|
||||
|
||||
Inspector is a small, opinionated Docker-watchdog. It polls the Docker
|
||||
daemon, applies per-container restart rules, pings Gotify and/or
|
||||
Pushover when things go wrong, and gives you a dashboard that shows
|
||||
what's happening right now and what happened earlier today.
|
||||
|
||||
Built for home-lab and small-fleet operators who want "it just works"
|
||||
container recovery without standing up a full observability stack.
|
||||
|
||||
## What Inspector does
|
||||
|
||||
- Polls each configured container on a fixed interval and classifies it:
|
||||
`HEALTHY`, `UNHEALTHY`, `STARTING`, `NOT RUNNING`, `ERROR`,
|
||||
`UNREACHABLE`, `CONTAINER NOT FOUND`, `NO HEALTH CHECK`, `UNKNOWN`.
|
||||
- Restarts a container when it crosses a configured error threshold —
|
||||
with cooldowns, grace periods, and an hourly restart cap so a flapping
|
||||
container doesn't DDoS your host.
|
||||
- Opt-in HTTP reachability checks per container (useful for VPN-routed
|
||||
containers whose tunnel drops while Docker still reports "healthy").
|
||||
- Opt-in Uptime Kuma integration as a second reachability source.
|
||||
- Advanced recovery via Portainer stack redeploy for containers whose
|
||||
network namespace is tied to a VPN sidecar.
|
||||
- Sends notifications on transitions, not on every poll — one line when
|
||||
something breaks, one line when it recovers.
|
||||
- Optional SQLite event history + a daily/weekly digest.
|
||||
- Scheduled maintenance windows (don't act during 2–6 AM).
|
||||
- Manual notification mute per container, from the dashboard.
|
||||
- Embedded web dashboard + events timeline + **web settings page** for
|
||||
editing `config.yml` without SSH.
|
||||
|
||||
## What Inspector is not
|
||||
|
||||
- Not a metrics system. It doesn't scrape Prometheus or push
|
||||
dashboards; use Grafana / Netdata / your real monitoring stack for
|
||||
that.
|
||||
- Not an orchestrator. It only acts on containers you've explicitly
|
||||
listed in `config.yml`.
|
||||
- Not multi-host. One Inspector per Docker socket.
|
||||
|
||||
## Install
|
||||
|
||||
See [`INSTALL.md`](./INSTALL.md). TL;DR:
|
||||
|
||||
```bash
|
||||
mkdir -p ~/docker/inspector && cd ~/docker/inspector
|
||||
curl -L -o compose.yml https://gitea.euronvault.com/euronvault/inspector/raw/branch/main/compose.yml
|
||||
curl -L -o config.yml https://gitea.euronvault.com/euronvault/inspector/raw/branch/main/config.example.yml
|
||||
$EDITOR config.yml
|
||||
echo "DOCKER_GID=$(getent group docker | cut -d: -f3)" > .env
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Everything lives in `config.yml` next to the compose file. Start from
|
||||
[`config.example.yml`](./config.example.yml) — every key is commented.
|
||||
Highlights:
|
||||
|
||||
- `inspector.interval_seconds` — poll cadence.
|
||||
- `inspector.dry_run` — classify + log, never restart.
|
||||
- `notifications.gotify` / `notifications.pushover` — enable either,
|
||||
both, or neither.
|
||||
- `containers.<name>.max_error_count` / `cooldown_seconds` /
|
||||
`grace_period_seconds` / `max_restarts_per_hour` — the restart knobs.
|
||||
- `containers.<name>.restart_on` — which statuses trigger a restart
|
||||
(leave empty for observe-only).
|
||||
- `containers.<name>.http_check` — opt-in HTTP ping.
|
||||
- `containers.<name>.recovery_action` — `restart_container` (default)
|
||||
or the advanced Portainer-based options.
|
||||
|
||||
### Dashboard and settings page
|
||||
|
||||
If `dashboard.enabled: true`, Inspector exposes a small web UI on
|
||||
`:8080`:
|
||||
|
||||
- `/` — container cards with current status, error bar, phase
|
||||
(cooldown / grace / failing / observe only / maintenance), and
|
||||
maintenance / mute toggles.
|
||||
- `/events` — per-day timeline of status changes, restarts, recoveries,
|
||||
and failures (requires `database.enabled: true`).
|
||||
- `/settings` — forms for every top-level config section plus one card
|
||||
per container. Saves preserve comments and key order in `config.yml`
|
||||
and keep a `.bak`. Fields that take effect on the next loop iteration
|
||||
(per-container thresholds, `dry_run`, `heartbeat`, `interval_seconds`)
|
||||
hot-apply; fields bound at startup are labeled **requires restart**.
|
||||
|
||||
Note on `.bak` inside Docker: when `config.yml` is bind-mounted as a
|
||||
single file (the compose default), the `.bak` lives in the container's
|
||||
overlay fs — the live file still updates cleanly, but the backup is
|
||||
lost when the container is removed. To keep the `.bak` on the host,
|
||||
bind-mount the directory instead of the single file.
|
||||
|
||||
### Notifications
|
||||
|
||||
Both channels are independent. If both are enabled, every alert goes to
|
||||
both. Inspector sends on transitions:
|
||||
|
||||
```
|
||||
🚨 first failure threshold crossed
|
||||
🔁 container restart triggered
|
||||
✅ restart / start completed
|
||||
✅ container recovered
|
||||
🛑 restart failed / hourly limit exceeded
|
||||
❓ configured container not found
|
||||
```
|
||||
|
||||
Gotify messages are Markdown; Pushover doesn't render Markdown so the
|
||||
`**bold**` passthrough is cosmetic — bodies are identical.
|
||||
|
||||
Pushover priorities map from Inspector's Gotify-style scale (default 5)
|
||||
to Pushover's `-2..2` range: `<=2 → -1`, `3..4 → 0`, `5..6 → 1`,
|
||||
`>=7 → 2`. Priority 2 (emergency) ships default `retry` / `expire` and
|
||||
your Pushover client prompts for acknowledgement.
|
||||
|
||||
## Docker socket security
|
||||
|
||||
Inspector talks to `/var/run/docker.sock`. That socket is effectively
|
||||
root on your host: anything that can write to it can start, stop,
|
||||
inspect, and (through bind mounts) read any file as root. Inspector
|
||||
mounts it read-write because it needs to restart containers.
|
||||
|
||||
Follow the usual home-lab precautions:
|
||||
|
||||
- Don't publish the dashboard port on an untrusted network. Use a
|
||||
reverse proxy with auth, a tailnet, or SSH tunneling.
|
||||
- Set a strong `dashboard.password`.
|
||||
- Store Portainer / Gotify / Pushover tokens in the config file on a
|
||||
host-only path with permissions `600`.
|
||||
|
||||
## Versioning
|
||||
|
||||
Semantic versioning (`MAJOR.MINOR.PATCH`). Image tags are published for
|
||||
every release; `latest` tracks the newest tag. Pin a specific version
|
||||
in production — see `INSTALL.md`.
|
||||
|
||||
## License
|
||||
|
||||
[MIT](./LICENSE).
|
||||
Reference in new issue
Block a user