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:
Europium 63 committed 2026-10-26 15:44:55 -07:00
commit ea1103f52b
35 files changed
+5579

No files matched your search

Executable
+139
View File
@@ -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).