# Uptime Kuma

Self-hosted uptime monitoring with a clean dashboard, multi-type monitors, and ntfy/Signal notifications.

## Overview

| Property | Value |
|----------|-------|
| **Host** | Raspberry Pi 5 (`100.77.151.40`) |
| **Compose file** | `hosts/edge/rpi5-vish/uptime-kuma.yaml` |
| **Web UI** | `http://100.77.151.40:3001` |
| **Docker image** | `louislam/uptime-kuma:latest` |
| **Network mode** | `host` |
| **Data directory** | `/home/vish/docker/kuma/data` |

## Current compose config

```yaml
services:
  uptime-kuma:
    image: louislam/uptime-kuma:latest
    container_name: uptime-kuma
    network_mode: host
    volumes:
      - /home/vish/docker/kuma/data:/app/data
      - /var/run/docker.sock:/var/run/docker.sock:ro
    restart: unless-stopped
```

The `docker.sock` mount (read-only) enables the Docker container monitor type for pi5-local containers.

---

## Docker Container Monitoring

Kuma supports a "Docker Container" monitor type that checks container state directly via the Docker API rather than via HTTP/TCP.

### How it works

- Kuma connects to a registered **Docker Host** (socket or TCP)
- Polls the Docker daemon and checks if the named container is in `running` state
- Reports the container's healthcheck status in the message field (`healthy`, `unhealthy`, `starting`, or blank if no healthcheck)
- Up/down is based purely on running vs not-running — not on service-level health

### Docker Hosts configured

| Name | Type | Connection | Covers |
|------|------|------------|--------|
| `pi5-local` | socket | `/var/run/docker.sock` | pi5 containers only |

### Docker Container monitors (pi5)

| Monitor name | Container | Interval |
|--------------|-----------|----------|
| `uptime-kuma (pi5)` | `uptime-kuma` | 60s |

To add more: in the Kuma UI, create a new monitor → type "Docker Container" → select `pi5-local` → enter the container name.

---

## Socket vs TCP — Which to Use

### Socket (what is configured)

- Kuma reads `/var/run/docker.sock` directly on the same host
- Only works for containers **on the same host as Kuma** (pi5)
- No network exposure, no TLS config required
- Mount as `:ro` (read-only) — sufficient for monitoring

### TCP (remote Docker daemon)

- Requires exposing Docker daemon on port `2375` (plain) or `2376` (TLS) on each remote host
- On Synology DSM, this is non-trivial to configure and secure
- Exposes a full root-equivalent interface to the Docker daemon over the network
- Kuma's own docs warn against exposing Kuma to the internet when TCP is enabled
- **Not recommended for this homelab** — the security tradeoff is not worth it for container state checks alone

### Why TCP is not needed here

Portainer BE already provides container state visibility across all hosts via its agent model (Atlantis, Calypso, Concord NUC, Homelab VM, RPi5). Opening Docker TCP on each host just to duplicate that in Kuma adds attack surface without adding meaningful monitoring capability.

For remote hosts, HTTP/TCP monitors in Kuma are a better fit — they test actual service availability rather than just container running state.

### When Docker socket monitoring is useful

- Containers with **no HTTP endpoint** (workers, agents, background jobs)
- Catching containers that have crashed before `restart: unless-stopped` kicks back in
- A lightweight "is it even running" layer alongside existing HTTP checks

Good candidates on pi5: `dozzle-agent`, `scrutiny-collector`, `diun` (none of these expose an REDACTED_APP_PASSWORD can check).

---

## Monitor Types in Use

| Type | Use case |
|------|----------|
| HTTP(s) | Web services, APIs — checks response code and optionally keyword |
| TCP | Non-HTTP services (databases, game servers, custom ports) |
| Ping | Network-level host reachability |
| Docker Container | Container running state (pi5-local only, via socket) |

---

## Notifications

Configured notification channels:
- **ntfy** — push notifications for status changes. **All 112 active monitors** have ntfy linked.
- **Signal** — via signal-cli-rest-api on homelab-vm (`100.67.40.126:8080`)

### ntfy configuration (notification ID: 1)

| Setting | Value |
|---------|-------|
| Server URL | `https://ntfy.vish.gg` (fixed 2026-03-22 — was `http://192.168.0.210:8081`) |
| Topic | `homelab-alerts` |
| Priority | 5 (high) |
| Auth | none |
| Default | yes — all monitors use this channel |

**Why the fix was needed:** Pi-5 (`192.168.0.66`) cannot reach homelab-vm (`192.168.0.210`) directly — firewall blocks LAN ICMP/TCP between them. The old URL `http://192.168.0.210:8081` timed out on every notification attempt, silently swallowing all alerts. Changed to the public `https://ntfy.vish.gg` which Pi-5 can reach.

To update the ntfy URL in future:
```bash
ssh pi-5 "docker exec uptime-kuma sqlite3 /app/data/kuma.db \\"
UPDATE notification SET config = json_set(config, '$.ntfyserverurl', 'https://ntfy.vish.gg')
WHERE id = 1;
\\""
ssh pi-5 "docker restart uptime-kuma"
```

---

## Database

Kuma stores all configuration in SQLite at `/home/vish/docker/kuma/data/kuma.db`.

Key tables: `monitor`, `docker_host`, `heartbeat`, `notification`, `user`

To inspect monitors directly:
```bash
ssh pi-5 "docker exec uptime-kuma node -e \"
const sqlite3 = require('@louislam/sqlite3');
const db = new sqlite3.Database('/app/data/kuma.db');
db.all('SELECT id,name,type,active FROM monitor', (e,rows) => { console.log(JSON.stringify(rows,null,2)); db.close(); });
\""
```

> Note: changes to the DB take effect after a container restart — Kuma caches monitors in memory.

---

## Useful Commands

```bash
# View logs
ssh pi-5 "docker logs uptime-kuma --tail 50"

# Restart
ssh pi-5 "docker restart uptime-kuma"

# Check socket is mounted
ssh pi-5 "docker inspect uptime-kuma | python3 -c \"import sys,json; print([c for c in json.load(sys.stdin)[0]['HostConfig']['Binds']])\""
```

---

## Monitor Groups (as of 2026-03-21)

Monitors are organised into groups matching the host hierarchy:

```
Homelab
├── Atlantis      — [ATL] arr suite, DSM, Portainer (pt.vish.gg), Plex, etc.
├── Calypso       — [CAL] arr suite, DSM, Gitea, Authentik, etc.
├── Concord_NUC   — NUC services
├── Raspberry Pi 5
├── Guava         — TrueNAS services
├── Setillo       — remote Synology
├── Proxmox_NUC   — Proxmox host
├── Seattle       — Contabo VPS services
├── Matrix-Ubuntu — Matrix/Synapse services
│   ├── Matrix (https://matrix.thevish.io)
│   ├── Matrix-Ubuntu SSH (192.168.0.154:22)
│   ├── mx.vish.gg (Matrix) (https://mx.vish.gg)
│   └── LiveKit SFU (https://livekit.mx.vish.gg/livekit/jwt/healthz)
└── Moon
    └── Moon SSH (100.64.0.6:22)
```

### DB manipulation for group changes

Kuma uses a `parent` column on the `monitor` table for group hierarchy:

```bash
# Set a monitor's parent group
ssh pi-5 "docker exec uptime-kuma sqlite3 /app/data/kuma.db \
  'UPDATE monitor SET parent=<group_id> WHERE id=<monitor_id>;'"

# Find group IDs
ssh pi-5 "docker exec uptime-kuma sqlite3 /app/data/kuma.db \
  'SELECT id, name FROM monitor WHERE type=\"group\";'"

# Always restart after DB changes
ssh pi-5 "docker restart uptime-kuma"
```

### Monitor audit — fixes applied 2026-03-22

Full audit of all 112 monitors found the following issues and fixes:

| ID | Monitor | Issue | Fix |
|----|---------|-------|-----|
| 1 | Libreddit | Disabled — stale service | Deleted |
| 10 | [ATL] Wireguard | URL incorrectly set to `https://joplin.thevish.io/` | Cleared URL |
| 17 | [ATL] Openspeedtest | Disabled — stale | Deleted |
| 18 | Matrix | hostname `100.83.230.112` (Atlantis) — wrong host | Changed to `192.168.0.154:8008` (matrix-ubuntu) |
| 56 | [CAL] Openspeedtest | CF Origin cert causes TLS verify failures | Set `ignore_tls=1` |
| 81 | Cocalc | Disabled — stale | Deleted |
| 104 | NTFY (local) | `100.67.40.126:8081` unreachable from Pi-5 | Left as-is (port check, not critical) |
| all | ntfy channel | URL `http://192.168.0.210:8081` unreachable from Pi-5 | Changed to `https://ntfy.vish.gg` |

### Key monitor IDs (updated 2026-03-22)

| ID | Name | Type | Notes |
|----|------|------|-------|
| 3 | Homelab | group | Top-level group |
| 4 | Atlantis | group | |
| 13 | [ATL] Portainer | http | `https://pt.vish.gg/` — fixed 2026-03-21 |
| 49 | Calypso | group | |
| 105 | Headscale | http | `https://headscale.vish.gg:8443/` — fixed 2026-03-21 |
| 110 | Whisparr | http | `http://100.83.230.112:6969/` — fixed 2026-03-21 |
| 114 | Moon | group | Added 2026-03-21 |
| 115 | Matrix-Ubuntu | group | Added 2026-03-21 |
| 116 | Moon SSH | port | `100.64.0.6:22` |
| 117 | LiveKit SFU | http | `https://livekit.mx.vish.gg/livekit/jwt/healthz` |
| 118 | Matrix-Ubuntu SSH | port | `192.168.0.154:22` |
| 119 | mx.vish.gg (Matrix) | http | `https://mx.vish.gg/` |

---

## Related docs

- `docs/admin/monitoring.md` — overall monitoring strategy
- `hosts/edge/rpi5-vish/uptime-kuma.yaml` — compose file
