Sign inSign up

b3rkay/raymontool

By b3rkay

Updated 22 days ago

A minimal, self-hosted SMART disk health monitor

Image
Monitoring & observability
0

3.4K

b3rkay/raymontool repository overview

RAYMONTOOL

This repository requires mandatory token authentication for security. If you don't add your token to the .env file, the installation will fail.

SMART disk monitoring — single static Go binary + a small smartctl collector, no reverse proxy, no middleware.

Two images ship together as a pair, always the same version tag:

  • raymontool — HTTP server + SQLite + web UI. scratch base, no shell.
  • raymontool-collector — runs smartctl against your disks and writes the results for the server to read.

Quick start

mkdir -p data/smart data/db
services:
  raymontool:
    image: b3rkay/raymontool:latest
    container_name: raymontool
    restart: unless-stopped
    network_mode: host
    volumes:
      - ./data/smart:/data/smart:ro
      - ./raymontool-db:/data
    environment:
      - RMT_COLLECTOR_TOKEN=${RMT_COLLECTOR_TOKEN}
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    healthcheck:
      test: ["CMD", "/raymontool", "-healthcheck"]
      interval: 30s
      timeout: 3s
      start_period: 10s
      retries: 3

  collector:
    image: b3rkay/raymontool-collector:latest
    container_name: raymontool-collector
    restart: unless-stopped
    network_mode: host
    privileged: true
    volumes:
      - ./data/smart:/data/smart
      - /dev:/dev
      - /:/hostroot:ro
    environment:
      - RAYMONTOOL_DATA_DIR=/data/smart
      - RMT_COLLECTOR_TOKEN=${RMT_COLLECTOR_TOKEN}
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    healthcheck:
      test: ["CMD", "/raymontool-collector", "-healthcheck"]
      interval: 30s
      timeout: 3s
      start_period: 10s
      retries: 3

docker compose up -d

Open http://<host>:2222.

Why two images

The server never touches disk hardware and never runs smartctl — it only reads JSON the collector already wrote to /data/smart. Only the collector needs raw /dev access and privileged: true, so only the collector carries that risk. The server stays on scratch, unprivileged, read-only on the shared volume.

If you want to harden this further, you can isolate the collector under a dedicated system user. Create a unprivileged user (e.g. smartmon) on the host, note its UID/GID, and pass them into the container:

collector:
  user: "1500:1500"   # smartmon UID:GID
  privileged: true

This way, even though the container needs privileged: true for smartctl, the process inside runs as smartmon rather than root. If the container is ever compromised, the attacker lands as an unprivileged host user with no meaningful permissions outside the container's scope.

Requirements

  • smartctl ships inside the collector image already (smartmontools, installed at build time) — nothing to install on the host.
  • The collector needs privileged: true and /dev:/dev to reach the disks. Without both, it starts but reports nothing.

Tags

  • latest — most recent build.
  • <version> — immutable, matches a specific release. Pin this in production; roll back by re-deploying an older tag.

Server and collector are always pushed as a matched pair under the same tag — never mix versions between the two.

Ports

  • 2222 — server HTTP/UI.
  • 2223 — collector's internal /trigger endpoint (manual "refresh now").

Both containers use network_mode: host, so no ports: mapping is needed or used.

Volumes

PathContainerPurpose
/data/smartbothcollector writes, server reads (mount read-only on the server side)
/dataserverSQLite database, persists across container recreation
/devcollectorraw disk access for smartctl

Health check

Both images include a built-in HEALTHCHECK (-healthcheck, checking each process's own /healthz on its trigger port) — no curl/wget needed since neither base image reliably has both a shell and curl. The collector's check only proves its trigger server (:2223) is alive and responsive, not that the last smartctl pass actually succeeded — for that, still watch its logs and the mtimes under /data/smart.

Architectures

linux/amd64, linux/arm64.

Tag summary

Content type

Image

Digest

sha256:1d6f682a5

Size

6.1 MB

Last updated

22 days ago

docker pull b3rkay/raymontool