Hard drive health dashboard powered by SMART data. Scrutiny runs smartctl against your drives on a schedule, stores historical metrics in a bundled InfluxDB instance, and surfaces failures — both raw SMART attribute failures and Backblaze-derived failure statistics — in a clean web UI.
This deployment uses the omnibus image, which bundles the web/API server, the drive collector (cron-scheduled), and InfluxDB into a single container. No separate database container is needed.
┌──────────────────────────────────────────┐
│ scrutiny (omnibus container) │
│ │
│ ┌────────────┐ ┌──────────────────┐ │
│ │ collector │ │ web / API :8080 │ │
│ │ (cron) │ │ │◄──┼── Traefik → browser
│ └─────┬──────┘ └────────┬─────────┘ │
│ │ │ │
│ └──────┬───────────┘ │
│ ▼ │
│ ┌────────────┐ │
│ │ InfluxDB │ │
│ └────────────┘ │
└──────────────────────────────────────────┘
│
/dev/sda, /dev/sdb, ... (host drives passed in)
The collector runs on a schedule (default: 6 hours) and sends SMART data to the internal InfluxDB. The web UI reads from InfluxDB and serves the dashboard.
mkdir -p /mnt/SSD/Containers/scrutiny/config
mkdir -p /mnt/SSD/Containers/scrutiny/influxdbOn the TrueNAS host, list all physical disks:
lsblk -d -o NAME,TYPE,SIZE,MODEL | grep diskOr with smartctl:
smartctl --scanNote the device paths (e.g. /dev/sda, /dev/nvme0n1) — you'll need to list them in compose.yaml.
Edit the devices: block to match your actual drives:
devices:
- /dev/sda
- /dev/sdb
- /dev/sdc
- /dev/nvme0n1
# add every drive you want monitoredScrutiny will only see drives explicitly listed here. Drives not listed are silently ignored.
cp example.env .env
# Edit .env — set SCRUTINY_DOMAIN at minimum
docker compose up -ddocker compose ps
docker compose logs -fWait 30–60 seconds for InfluxDB to initialize, then navigate to https://<SCRUTINY_DOMAIN>. The first SMART scan runs immediately on container start; subsequent scans follow the 6-hour schedule.
| Variable | Default | Description |
|---|---|---|
TZ |
America/New_York |
Timezone (controls cron schedule display) |
SCRUTINY_DOMAIN |
— | Hostname Traefik routes to Scrutiny |
SCRUTINY_PORT |
8096 |
Host port (direct LAN access only — Traefik ignores this) |
For advanced configuration (collector schedule, notification webhooks, alert thresholds), drop a scrutiny.yaml in /mnt/SSD/Containers/scrutiny/config/. Scrutiny reads it on startup.
Example — change the collector schedule to every 12 hours:
# /mnt/SSD/Containers/scrutiny/config/scrutiny.yaml
collector:
cron: "0 */12 * * *"Full config reference: https://github.com/AnalogJ/scrutiny/blob/master/example.scrutiny.yaml
Scrutiny requires two Linux capabilities to read SMART data:
| Capability | Required for |
|---|---|
SYS_RAWIO |
SATA/SAS ATA passthrough (most spinning and SATA SSD drives) |
SYS_ADMIN |
NVMe IOCTL passthrough (NVMe SSDs) |
These are granted via cap_add in compose.yaml — not full privileged: true. If you have no NVMe drives, SYS_ADMIN can be removed from the compose file.
| Data | Host path |
|---|---|
| Scrutiny config | /mnt/SSD/Containers/scrutiny/config |
| InfluxDB time-series data | /mnt/SSD/Containers/scrutiny/influxdb |
Scrutiny can push notifications to Slack, Discord, PagerDuty, email, and others via shoutrrr. Configure via scrutiny.yaml:
notify:
urls:
- "discord://token@webhookid"
- "slack://tokenA/tokenB/tokenC"Notifications fire when a drive's SMART status changes (passes → failed or failed → passes).
docker exec scrutiny scrutiny-collector-metrics rundocker compose pull
docker compose up -ddocker exec scrutiny influx ping