LastSkywalkerandCursor 4530cd43ce
Build & Release / build (push) Successful in 4m37s
Build & Release / macos (push) Skipped
fix(update): don't report a clean Windows stop after self-update
svc.Run reports SERVICE_STOPPED as soon as the service handler returns.
Existing installs only restart a process that dies without that report,
so the handler now stays inside Execute until the process exits.

Also drop Playwright session dumps that were committed with the previous
update fix, and ignore that directory.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-31 21:28:04 +03:00
2026-03-26 15:16:11 +03:00
2025-10-01 21:21:00 +03:00
2026-03-26 20:46:48 +03:00
2025-10-10 18:56:56 +03:00
2025-10-01 21:21:00 +03:00
2026-03-26 15:16:11 +03:00
2025-10-10 18:56:56 +03:00

Node Stats

Node Stats is an open-source, self-hosted system monitoring and infrastructure monitoring dashboard built with Go and React. Monitor your servers, Docker containers, and system resources in real-time with a beautiful, modern web interface. Perfect for DevOps engineers, system administrators, and developers who need comprehensive server monitoring, container monitoring, and infrastructure metrics visualization.

What is Node Stats?

Node Stats is a lightweight, self-hosted alternative to commercial monitoring solutions like Grafana, Prometheus, or Datadog. It provides real-time system metrics collection, Docker container monitoring, and a beautiful dashboard interface without the complexity of enterprise monitoring tools. Built with Go for performance and React for a modern user experience, Node Stats is ideal for monitoring single servers, development environments, or small infrastructure deployments.

Key Capabilities

  • Server Monitoring: Real-time CPU, memory, disk, and network metrics
  • Docker Monitoring: Container statistics, resource usage, and health monitoring
  • System Metrics: Temperature sensors, system information, and hardware monitoring
  • Self-Hosted: Complete control over your data with no external dependencies
  • Lightweight: Minimal resource footprint compared to enterprise monitoring solutions
  • Modern UI: Beautiful, customizable dashboard themes with real-time updates

Features

  • Real-time Monitoring: Live CPU usage, memory usage, disk I/O, network traffic, and Docker container metrics
  • Beautiful UI: Modern monitoring dashboard with multiple customizable themes (Neon Terminal, Glass Aurora, Cards Flow, Slate Pro)
  • RESTful API: Clean REST API endpoints for all system metrics and Docker statistics
  • Docker Support: Comprehensive Docker container monitoring with resource usage tracking
  • Persistent Storage: SQLite database for historical metrics and data retention
  • User Authentication: Secure login system with JWT tokens and refresh tokens
  • Temperature Monitoring: Hardware temperature sensor monitoring for system health
  • Multi-theme Support: Switch between different dashboard themes for personalized monitoring experience

Use Cases

Node Stats is perfect for:

  • Development Teams: Monitor development servers and staging environments
  • DevOps Engineers: Track infrastructure health and resource utilization
  • System Administrators: Monitor server performance and system metrics
  • Docker Users: Monitor containerized applications and Docker host resources
  • Home Lab Enthusiasts: Self-hosted monitoring for personal servers and homelabs
  • Small to Medium Infrastructure: Lightweight monitoring solution without enterprise complexity
  • Privacy-Conscious Users: Self-hosted alternative to cloud-based monitoring services

Roadmap

  • ✅ Real-time metrics monitoring (CPU, memory, disk, network, Docker containers, temperature sensors)
  • ✅ Modern UI dashboard with multiple themes (Neon Terminal, Glass Aurora, Cards Flow, Slate Pro)
  • ✅ RESTful API endpoints for all metrics
  • ✅ User authentication (registration, login, refresh tokens, user management)
  • ✅ SQLite database for historical metrics storage
  • ✅ Application configuration via UI on first launch (setup wizard for initial configuration)
  • ✅ Prometheus metrics export (/api/v1/metrics, enabled via PROMETHEUS_ENABLED=true)
  • ✅ Swagger UI for API documentation (/swagger/)
  • ✅ PostgreSQL database support (alternative to SQLite via DB_TYPE=postgres)
  • ✅ Health check endpoint (/api/v1/health) for load balancers and Kubernetes probes
  • ✅ Live metrics stream via Server-Sent Events (/api/v1/stream)
  • ✅ Configurable data retention (METRICS_RETENTION_DAYS for automatic cleanup of old metrics)
  • ✅ Hosts registration and management
  • ✅ Admin/user roles
  • ✅ Backend unit tests for service layer
  • ✅ Multi-node statistics synchronization and aggregation (Raft consensus replication — nodes form a cluster via the setup wizard and replicate state across peers; see "Clustering (Raft)" below)
  • ❌ Alert system (configurable notifications when metric thresholds are exceeded)
  • ✅ Stack detection with aggregation into apps with icons and minimal stats
  • ❌ Auto config for reverse proxy for apps routing
  • 🚫 Application port tunneling (tunnel selected application ports from closed machines through the central node to local machine for fast, direct, and secure access) — declined; NetBird solves this better
  • ✅ Container logs monitoring (real-time viewing and filtering of Docker container logs)
  • ❌ Additional time-series databases support (integration with databases better suited for time-series data like InfluxDB, TimescaleDB)

Screenshots

UI collage (dark glass / neon and light themes). Click an image on GitHub to open the full-size PNG.

Sign in
Sign in — NODE-STATS logo, email/password fields, primary Sign In action.
Machines overview
Machines — fleet cards: hostname, OS, IP/MAC, kernel, last seen, latency, uptime.
Live metrics dark theme
Live metrics (dark) — CPU, memory, disk, network, sensors with sparklines and load.
Docker containers
Containers — Docker compose groups, running/total, CPU/memory rings, ports, I/O.
Live metrics light theme
Live metrics (light) — same metrics layout on a light, patterned dashboard theme.
Admin users
Admin · Users — email invites, one-time links, directory with roles (e.g. Admin).
Admin nodes
Admin · Nodes — Raft cluster status, peers, and registered hosts.

Installation & Quick Start

Pick the path that matches your machine. The database and configuration are not baked in ahead of time — you choose them in the setup wizard on first run, and the stack reconfigures itself automatically.

curl -fsSL https://gitea.sky-apps.uk/LastSkywalker/node-page/raw/branch/main/scripts/install.sh | bash

This detects your OS/arch, checks Docker + Compose, creates a stack dir (~/.node-stats, or /opt/node-stats as root), pulls the image, sets the right host capabilities (pid/ipc: host, /host mount) for accurate metrics, and brings the stack up. Then open http://localhost:9090 to finish setup.

Manage it later:

curl -fsSL https://gitea.sky-apps.uk/LastSkywalker/node-page/raw/branch/main/scripts/install.sh | bash -s -- update      # pull + recreate
curl -fsSL https://gitea.sky-apps.uk/LastSkywalker/node-page/raw/branch/main/scripts/install.sh | bash -s -- uninstall   # stop (add --purge to wipe data)

No network? The stack lives in the dir above, so this is the same uninstall by hand:

cd /opt/node-stats && docker compose down --remove-orphans        # stop, keep data (use ~/.node-stats if not root)
cd /opt/node-stats && docker compose down --remove-orphans -v && rm -rf /opt/node-stats   # wipe data too

Overrides: NODE_STATS_DIR (stack dir), NODE_STATS_PORT (HTTP port), NODE_STATS_IMAGE (pin a :vX.Y.Z tag).

Linux SBC / lean host — native install (no Docker, arm64 + amd64)

For Orange Pi, Raspberry Pi, or any Linux box where you'd rather not run Docker, install the self-contained native binary (it reads /proc directly, so you get real host metrics) as a systemd service:

curl -fsSL https://gitea.sky-apps.uk/LastSkywalker/node-page/raw/branch/main/scripts/install.sh | sudo bash -s -- native

Downloads the matching linux/{amd64,arm64} release binary (checksum-verified), installs it to /usr/local/bin, and registers a node-stats systemd service (data/config in /var/lib/node-stats). Open http://localhost:8080 to finish setup. Manage with curl -fsSL https://gitea.sky-apps.uk/LastSkywalker/node-page/raw/branch/main/scripts/install.sh | sudo bash -s -- update-native (or uninstall-native). Pin a version with NODE_STATS_VERSION=vX.Y.Z. (Without sudo/systemd it installs to ~/.local/bin and prints how to run it manually.)

Proxmox VE — one command on the host (LXC)

Spin up node-stats as a tiny Debian LXC, community-scripts.org style. Run this on the Proxmox VE host (the hypervisor, as root):

bash -c "$(curl -fsSL https://gitea.sky-apps.uk/LastSkywalker/node-page/raw/branch/main/scripts/proxmox-lxc.sh)"

It creates an unprivileged Debian 12 container, installs the native release inside (systemd service), and prints http://<container-ip>:8080. Because it runs on the PVE host, it also auto-attaches the Proxmox connector (mints a read-only PVEAuditor token and wires it in) — so the hypervisor + every VM/LXC show up automatically, no clicks. Disable with PROXMOX_AUTOCONNECT=0. Full guide (options, day-2 commands, and how to get it listed on community-scripts.org): docs/PROXMOX-LXC.md.

macOS / Windows — native binary (best host metrics)

Docker Desktop runs in a Linux VM, so its host metrics reflect the VM, not your machine. For true host metrics, download the native single binary from the latest release:

  • macOS (Apple Silicon): node-stats_<version>_darwin_arm64.tar.gz
  • Windows (x64): node-stats_<version>_windows_amd64.zip
  • Linux (x64/arm64): node-stats_<version>_linux_{amd64,arm64}.tar.gz
tar -xzf node-stats_*_darwin_arm64.tar.gz
./node-stats                 # serves http://localhost:8080
./node-stats update          # self-update to the latest release

The binary is fully self-contained (frontend embedded, pure-Go SQLite — no CGO).

Windows — one-line install (Docker Desktop, PowerShell)

irm https://gitea.sky-apps.uk/LastSkywalker/node-page/raw/branch/main/scripts/install.ps1 | iex

Requires Docker Desktop. Same VM-metrics caveat as macOS. If your execution policy blocks it, run from an elevated prompt with powershell -ExecutionPolicy Bypass.

Synology NAS — Docker (Container Manager)

Synology runs node-stats as a Docker container. It works on x86 (Intel/AMD) models (amd64) and 64-bit ARM models (arm64) — the image ships both; old 32-bit ARM models aren't supported. You need the Container Manager package (DSM 7.2+) or the older Docker package (DSM 7.0–7.1).

Easiest — SSH + the installer. Enable SSH (Control Panel → Terminal & SNMP → Enable SSH service), connect, then run — pointing the stack at a folder on your volume so data persists across DSM updates:

sudo NODE_STATS_DIR=/volume1/docker/node-stats \
  bash -c "$(curl -fsSL https://gitea.sky-apps.uk/LastSkywalker/node-page/raw/branch/main/scripts/install.sh)"

Open http://<nas-ip>:9090 to finish setup. sudo is required because the Docker socket is root-owned. The container reads the DSM host's /proc and the Docker socket (pid: host / /host mount), so the machine card shows the NAS's real CPU/RAM/disk and its containers.

To install and join an existing cluster in one go, add the join env vars and call agent-join.sh instead of install.sh:

sudo NODE_STATS_DIR=/volume1/docker/node-stats \
  NODE_STATS_JOIN_URL="http://<leader-ip>:9090" \
  NODE_STATS_JOIN_KEY="<one-shot token>" \
  bash -c "$(curl -fsSL https://gitea.sky-apps.uk/LastSkywalker/node-page/raw/branch/main/scripts/agent-join.sh)"

The leader's admin panel (Admin → Nodes → Add a node) generates this exact command when you pick the Synology NAS platform — copy it, paste it over SSH, done.

Manual / Container Manager GUI route. Prefer the advanced docker-compose flow below with the stack dir set to /volume1/docker/node-stats. Keep .env.agent a file, not a folder. The controller sidecar needs the project dir identity-mounted (NODE_STATS_STACK_HOST_DIR=/volume1/docker/node-stats), which the SSH installer sets for you — the GUI Project import doesn't, so SSH is the recommended path.

HTTPS. Use DSM's built-in reverse proxy (Control Panel → Login Portal → Advanced → Reverse Proxy) pointed at localhost:9090, then set COOKIE_SECURE=true in .env.agent and docker compose restart node-stats. SSE works out of the box (see docs/REVERSE-PROXY.md).

Auto-updates

node-stats checks GitHub Releases and shows an "update available" badge to admins. Toggle auto-update in settings: Docker deployments pull the new image and recreate via the controller; native installs use node-stats update.

Release channel (stable / beta). Pick the update line in the admin update popup — it applies to every install type and is remembered. stable follows the latest full release; beta follows the bleeding edge (the rolling :beta image on Docker, the newest prerelease release on native). To start a fresh install on beta, pass NODE_STATS_CHANNEL=beta to any installer, e.g.:

NODE_STATS_CHANNEL=beta bash -c "$(curl -fsSL https://gitea.sky-apps.uk/LastSkywalker/node-page/raw/branch/main/scripts/install.sh)"
Advanced: manual docker-compose

The installer is just a convenience wrapper around docker compose. To run it by hand, create a stack directory and let the image generate the base compose:

mkdir -p ~/.node-stats/data/docker && cd ~/.node-stats
: > .env.agent            # MUST be a file (it is bind-mounted to /app/.env);
                          # a directory mount silently swallows the wizard's config
cat > .env <<'EOF'
NODE_STATS_IMAGE=gitea.sky-apps.uk/lastskywalker/node-page:latest
NODE_STATS_PORT=9090
NODE_STATS_STACK_HOST_DIR=__set_to_this_dir__
COMPOSE_PROJECT_NAME=node-stats
EOF
docker run --rm gitea.sky-apps.uk/lastskywalker/node-page:latest gen-compose > docker-compose.yml
printf 'services:\n  node-stats:\n    pid: host\n    ipc: host\n' > docker-compose.override.yml  # Linux only
docker compose up -d

JWT_SECRET/REFRESH_SECRET are generated by the setup wizard into .env.agent — you do not set them by hand. The wizard also switches the database (SQLite ↔ Postgres) and the controller sidecar regenerates this docker-compose.yml and restarts the app for you.

Clustering (Raft)

Multiple Node Stats instances form a cluster using Raft consensus replication — there is no central "main" that other nodes push to. State is replicated across all peers.

How to join a cluster:

  1. On a running cluster node (the leader), generate a one-shot connect key.
  2. On a fresh node, open the setup wizard and choose "Join an existing cluster".
  3. Paste the connect key and the cluster node URL, then submit. The node posts to POST /api/v1/setup/join-raft-cluster; the leader adds it as a voter and replicates state to it. The wizard shows progress while the leader catches the new node up.

The join handler writes the resolved RAFT_* values (node id, bind/advertise addresses, data dir, etc.) to the node's .env, so cluster membership survives restarts and image rebuilds. See docker-compose.cluster.yml for a ready-to-run two-node example and the full list of RAFT_* environment variables.

Local Development

The project uses Overmind with a Procfile to run backend and frontend in parallel. Backend uses Air for live reload; frontend uses Vite with proxy to the API.

Prerequisites:

# Install backend dependencies
go mod download

# Install frontend dependencies
cd frontend && yarn install && cd ..

# Set required environment variables
export JWT_SECRET=your-jwt-secret-key
export REFRESH_SECRET=your-refresh-secret-key

# Optional: customize server address (default: :8080)
export ADDR=:8080

# Run backend + frontend together
./scripts/dev
  • Backend (Air): http://localhost:8080 — live reload on Go file changes
  • Frontend (Vite): http://localhost:5173 — proxies /api and /ws to backend

Backend Only (Go)

# Install dependencies
go mod download

# Set required environment variables
export JWT_SECRET=your-jwt-secret-key
export REFRESH_SECRET=your-refresh-secret-key

# Optional: customize server address (default: :8080)
export ADDR=:8080

# Run the server
go run cmd/server/main.go

Frontend Only (React + TypeScript)

cd frontend
yarn install
yarn dev

The frontend development server typically runs on http://localhost:5173 (Vite default port). It proxies API requests to http://localhost:8080.

API Documentation

Node Stats provides a comprehensive REST API for accessing all system metrics programmatically. All endpoints return JSON data and support real-time metrics retrieval.

System Metrics Endpoints

  • GET /api/cpu - CPU usage metrics including per-core statistics and load averages
  • GET /api/memory - Memory usage metrics including RAM, swap, and memory statistics
  • GET /api/disk - Disk usage metrics including I/O statistics and filesystem information
  • GET /api/network - Network statistics including interface traffic and connection data
  • GET /api/docker - Docker containers information including resource usage and container status
  • GET /api/system - System information including hostname, uptime, and platform details
  • GET /api/sensors - Hardware temperature sensors and thermal monitoring data

Authentication Endpoints

  • POST /api/auth/register - User registration
  • POST /api/auth/login - User authentication
  • POST /api/auth/refresh - Refresh access token
  • POST /api/auth/logout - User logout

All API endpoints support CORS and can be integrated with external monitoring tools, automation scripts, or other applications.

Pulling Pre-built Images

# Pull from GitHub Container Registry
docker pull gitea.sky-apps.uk/lastskywalker/node-page:latest

# Run the container (default port 8080)
docker run -p 8080:8080 \
  -e ADDR=:8080 \
  -e JWT_SECRET=your-jwt-secret-key \
  -e REFRESH_SECRET=your-refresh-secret-key \
  -v ./stats.db:/app/stats.db \
  gitea.sky-apps.uk/lastskywalker/node-page:latest

Configuration

Node Stats is configured via environment variables:

  • ADDR - Server address and port (default: :8080)
  • GIN_MODE - Gin framework mode: release or debug (default: release)
  • JWT_SECRET - Secret key for JWT access tokens (required)
  • REFRESH_SECRET - Secret key for JWT refresh tokens (required)
  • DB_TYPE - Database type (default: sqlite)
  • DB_DSN - Database connection string or file path. Local dev: stats.db; Docker: /app/stats.db (mounted from ./data/docker/stats.db)
  • DEBUG - Enable debug mode: true or false (default: false)
  • Clustering (Raft): RAFT_ENABLED, RAFT_CLUSTER_ID, RAFT_NODE_ID, RAFT_BIND_ADDR, RAFT_ADVERTISE_ADDR, RAFT_ADVERTISE_PUBLIC_URL, RAFT_DATA_DIR, RAFT_BOOTSTRAP — see "Clustering (Raft)" above and docker-compose.cluster.yml. Usually set by the setup-wizard join flow.
  • Local metrics host id: This server always stores its own collected metrics under hosts.id = 1. Rebuilds update that row (same DB file).

Architecture & Technology Stack

Node Stats is built using modern web technologies and follows Clean Architecture principles for maintainability and scalability.

Technology Stack

  • Frontend: React 19 + TypeScript 5.9 + Tailwind CSS for a modern, responsive user interface
  • Backend: Go (Golang) with Gin web framework for high-performance API server
  • Database: SQLite (default) or PostgreSQL via GORM
  • Monitoring: Real-time system metrics collection using native Go libraries
  • Authentication: JWT-based authentication with refresh token support
  • Containerization: Docker and Docker Compose for easy deployment

Architecture Principles

  • Clean Architecture: Separation of concerns with domain, application, infrastructure, and presentation layers
  • RESTful API Design: Standard REST endpoints for all system metrics
  • Real-time Updates: Server-Sent Events (SSE) for real-time metric streaming
  • Modular Design: Feature-based module structure for easy extensibility

Development

Project Structure

├── cmd/server/          # Application entry point
├── internal/
│   ├── app/            # Application configuration
│   └── modules/        # Feature modules (CPU, Memory, etc.)
├── frontend/           # React frontend
├── .github/workflows/  # CI/CD pipelines
└── Dockerfile         # Container definition

Development

Building from Source

# Clone the repository
git clone https://github.com/yourusername/node-stats.git
cd node-stats

# One-command build (backend + frontend)
./scripts/build

Or build manually: go build -o bin/server ./cmd/server and cd frontend && yarn && yarn build.

Helper scripts (in scripts/): ./scripts/dev — run backend + frontend; ./scripts/build — build both; ./scripts/clean-db — remove SQLite DB (prompts for confirmation, reads DB_DSN from .env or uses stats.db).

Running Tests

# Backend tests
go test ./...

# Frontend tests
cd frontend
yarn test

Contributing

Contributions are welcome! Whether it's bug fixes, new features, or documentation improvements, your help makes Node Stats better.

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Test thoroughly
  5. Commit your changes (git commit -m 'Add some amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

Node Stats is inspired by and can be used alongside:

  • Grafana - Advanced visualization and alerting (Node Stats is lighter)
  • Prometheus - Time-series database and monitoring (Node Stats uses SQLite)
  • Netdata - Real-time performance monitoring (Node Stats focuses on simplicity)
  • Portainer - Docker management UI (Node Stats adds system monitoring)

Keywords & Tags

Monitoring Tools: system monitoring, server monitoring, infrastructure monitoring, docker monitoring, container monitoring, system metrics, server metrics, real-time monitoring, self-hosted monitoring

Technologies: Go, Golang, React, TypeScript, Docker, SQLite, REST API, JWT authentication, Gin framework, Tailwind CSS

Use Cases: DevOps monitoring, server health monitoring, Docker container stats, system performance tracking, homelab monitoring, development server monitoring, infrastructure health checks

Features: CPU monitoring, memory monitoring, disk monitoring, network monitoring, temperature sensors, Docker stats, system information, real-time dashboard, monitoring dashboard

License

MIT License - see LICENSE file for details

S
Description
No description provided
Readme MIT
65 MiB
0 Stars 1 Watchers 0 Forks
v0.13.5
Latest
2026-10-31 17:15:30 +03:00
Languages
Go 69.4%
TypeScript 23.9%
Shell 2.7%
Python 2.5%
JavaScript 0.6%
Other 0.9%