简体中文 · English · MIT license · Release guide
NodePeek is a self-hosted Linux server monitor that shows who is using CPU, memory and disk space, alongside networking, Docker, temperatures, hardware and UPS events. It keeps history in local SQLite and serves a lightweight HTTP dashboard on port 9100.
No cloud account, frontend build step, CDN or external database. Choose an unprivileged User Edition or a root Admin Edition.
All documentation screenshots use synthetic data: example users, fictional hardware, documentation-only addresses and generated metrics. They are not captures of a real server.
Network & disk I/O, Docker, and Power each have independent time controls (15m–30d presets and custom dates up to 90 days). Changing Resource trends does not change these sections.
Development workflow and CI: contributing guide. Repository: Shall-We-Dance/NodePeek; product name: NodePeek.
Power defaults to the last 24 hours; its time range also filters the event log. Temperature sensors are collapsed initially. If files change between disk scans, live capacity stays visible and inconsistent ownership values are marked as historical until the next scan.
| Area | What NodePeek records and displays |
|---|---|
| CPU & memory | Live host totals, stacked per-user trends, load, process counts and readable process I/O. UID ≥ 1000 shown individually; lower UIDs grouped under expandable System. |
| Storage | Mounted filesystem capacity, each user's share of each disk, per-user cards across disks and independent historical charts. A disk's capacity bar represents 100% of total capacity, including free space. |
| Network | RX/TX history and counters; labels for physical interfaces, ZeroTier, Docker bridges and virtual interfaces. |
| Docker | Containers, images, Compose projects, state changes, CPU/memory history and available I/O counters. |
| Hardware | Interactive 2D motherboard schematic with adaptive CPU sockets, installed/empty DIMMs, physical interfaces, drives, BIOS and OS; detailed specifications on selection. |
| Power & health | Readable temperature sensors, uptime, UPS charge/runtime/load, mains/battery transitions and imported apcupsd events. |
| Interface | English, 简体中文, 한국어, Español and 日本語, with a 文 / A picker and responsive layouts. |
Both editions have the same dashboard and history format. The difference is the operating-system privileges used for collection.
| User Edition — no sudo | Admin Edition — sudo/root | |
|---|---|---|
| Release asset | nodepeek-1.4.1-user.tar.gz |
nodepeek-1.4.1-admin.tar.gz |
| Installer | Run as your regular account | Run with sudo/root |
| Runtime | Your account; refuses root | Root system service |
| Installation | ~/.local/share/nodepeek |
/opt/nodepeek |
| Configuration | ~/.config/nodepeek/config.toml |
/etc/nodepeek/config.toml |
| History | ~/.local/state/nodepeek |
/var/lib/nodepeek |
| Service | systemctl --user |
System systemctl |
| Other users' private files / process I/O | Only existing readable access; often partial | More complete where the OS/filesystem allows |
| Memory-module DMI details | Often unavailable | Available when supported and dmidecode is installed |
| Docker / UPS | Existing CLI/socket/daemon permissions apply | Existing tools and daemon configuration still required |
| After logout / reboot | Depends on your user-service/linger policy | Starts at boot once enabled |
User paths honor XDG_DATA_HOME, XDG_CONFIG_HOME and XDG_STATE_HOME. Neither installer modifies sudoers, group memberships, filesystem access rules, UPS configuration or network settings. Root cannot bypass every restriction: remote root-squash, unavailable sensors and changing files can still produce partial results.
Requirements: Linux, Python 3.11+ with venv and pip, and network access to install the pinned Python dependencies. These are portable Python source distributions, not standalone binaries or offline wheel bundles. Optional system utilities are described below. No Node.js is needed to run the app.
Download the desired .tar.gz and SHA256SUMS from the repository's GitHub Releases page. Check the downloaded asset against its listed SHA-256 before extracting it.
tar -xzf nodepeek-1.4.1-user.tar.gz
cd nodepeek-1.4.1-user
sh install.shThe installer creates a private virtual environment and starts a user systemd service. If the user systemd manager is unavailable, run it in a foreground session instead:
sh install.sh --no-service
~/.local/share/nodepeek/start.shThe foreground process ends when its session ends unless your session manager keeps it alive. A user service's lifetime after logout depends on the machine's existing linger policy; the installer does not request administrator privileges to change it. Check it with loginctl show-user "$USER" -p Linger.
tar -xzf nodepeek-1.4.1-admin.tar.gz
cd nodepeek-1.4.1-admin
sudo sh install.shThe installer copies the code into a root-owned directory, creates its virtual environment and enables nodepeek.service. It runs no monitoring code from your writable extraction directory. For a non-systemd machine, use sudo sh install.sh --no-service, then run sudo /opt/nodepeek/start.sh under your service supervisor.
Preview either installation without changing anything:
sh install.sh --dry-runIf venv or pip is missing, use a Python installation that includes them; User Edition cannot install OS packages without an administrator. Debian/Ubuntu administrators can provide python3-venv through their package manager.
NodePeek serves its dashboard over HTTP on port 9100. Access it using an address on which the service is listening:
http://SERVER_IP:9100/
For access through any server IPv4 interface, set the following in the edition's configuration file, then restart its service:
[server]
host = "0.0.0.0"
port = 9100Use a specific interface IP to limit the listener, or 127.0.0.1 for local-only access. The existing default host = "auto" selects an available ZeroTier IPv4, otherwise localhost; the actual listening URL appears in the service log. ZeroTier is optional.
The dashboard has no built-in login. You manage routing, firewall rules and who can reach port 9100. See deployment and data boundaries.
- Disk level: one full-capacity bar combining users, unassigned usage, reserved blocks and free space. Each user percentage is divided by the whole disk's capacity.
- User level: search by username or UID, inspect their storage across mounted disks, and jump between user and disk cards.
- Gray means unknown or unattributed: unreadable/changed files, unscanned areas and filesystem accounting differences are not presented as a known user's files.
- Disk history has its own range: defaults to 7 days; choose 12h / 24h / 3d / 7d / 30d / 90d or a custom interval between 12 hours and 90 days. Changing it does not change the CPU/memory range above.
Disk scanning runs every six hours by default, in the background. The history chart updates its query every minute; it does not force a new disk scan. One available scan appears as a bar, multiple scans as a stepped stacked history. Empty periods are not invented measurements.
After deletions, recorded user allocations can exceed live used space. The upper bar then shows live used/reserved/free capacity; a second bar shows user allocations from the last completed scan, with its timestamp. Both use current total disk capacity as 100%. The historical remainder is not a measurement of past free space. If recorded allocations exceed current capacity, the bar is clipped with an explicit note.
An adaptive, interactive 2D motherboard view.
The dedicated Hardware section brings the server inventory into one compact diagram. Storage types use reported transport, rotation flags, and controller identity: NVMe, SATA/SAS SSD or HDD, and RAID virtual disks. ATA without transport remains ATA; RAID member media and bay positions cannot be inferred.
The diagram adapts to reported socket and DIMM counts, including one-, two- and four-socket systems. Click a CPU, memory slot, motherboard, network interface, drive, BIOS or OS to inspect it. Installed parts are solid, confirmed empty slots are dashed, and unknown occupancy is gray/hatched. Full specifications remain available in a collapsed section.
This is a schematic, not a reconstruction of physical placement or CPU-to-memory wiring. Disk bay positions are unknown. Without readable DMI, the view uses OS-reported processors and does not infer empty sockets or DIMM counts from RAM capacity. Selection survives language changes and inventory refreshes.
DMI fields use an allowlist: serial numbers, UUIDs, asset tags and MAC addresses are omitted. A RAID controller model is labeled as controller-reported; it is not claimed to be the model of each member drive. Inventory updates independently once per hour.
UPS integration detects local apcupsd or NUT. It reads their existing status interfaces and, when readable, the apcupsd event file. It does not configure your UPS or send shutdown/control commands. A monitoring gap or reboot is not automatically labeled a power failure.
Edit the edition's configuration file and restart its service. config.example.toml lists all options.
[server]
host = "auto"
port = 9100
[monitor]
interval = 5
raw_retention_days = 2
history_retention_days = 90
disk_scan_interval = 21600
disk_roots = ["auto"]
[ups]
backend = "auto"
nut_target = ""
apcupsd_target = "127.0.0.1:3551"
events_file = "/var/log/apcupsd.events"disk_roots = ["auto"] includes /home and automatically discovered mounted data filesystems, excluding system mount trees. To include directories on the root filesystem explicitly, use paths such as ["auto", "/fast", "/data", "/public"]. Scans do not follow symlinks, do not cross filesystem boundaries within a scan root, and deduplicate hard links.
| Optional tool/source | Used for |
|---|---|
lscpu, lsblk (util-linux) |
CPU and storage specifications |
dmidecode |
Memory slots, DIMM models and firmware data; normally requires root |
lspci / lsusb |
PCI and USB hardware descriptions |
docker CLI |
Readable daemon/container status and statistics; honors its existing context |
apcaccess or upsc |
Existing apcupsd or NUT server status |
Kernel /proc and /sys |
Processes, interfaces and available temperature sensors |
Missing optional tools do not prevent core monitoring. Unavailable values show as — or gray; permissions and partial scans are reported.
| Action | User Edition | Admin Edition |
|---|---|---|
| Status | systemctl --user status nodepeek |
sudo systemctl status nodepeek |
| Restart | systemctl --user restart nodepeek |
sudo systemctl restart nodepeek |
| Logs | journalctl --user -u nodepeek -n 100 |
sudo journalctl -u nodepeek -n 100 |
| Disable | systemctl --user disable --now nodepeek |
sudo systemctl disable --now nodepeek |
The installer refuses to overwrite an existing code directory. For an update, back up data, stop the old service and install into a new code directory using --prefix /absolute/new/path. It preserves the edition's existing configuration/history and updates the service to the new path. Keep the old code until the new version works. Do not run two collectors against the same database or port. When switching editions, use the migration instructions; the data paths and ownership differ.
Use SQLite's backup API for an online backup, or stop the service before copying its data directory. Copying only a live .sqlite3 file can miss uncheckpointed WAL data. See operations for backup, migration and removal steps.
- CPU is normalized to the entire host, so one fully busy core on a 16-thread host is about 6.25%. The dashed Host total includes work not attributable to readable user processes.
- Per-process memory is RSS; shared pages can be counted more than once. It is not a unique-physical-memory accounting system.
- Default history keeps raw samples for two days and minute/hour summaries for ninety days. There is no resource history from before the software was running.
- Disk accounting uses allocated filesystem blocks, not apparent file lengths. Metadata, reserved blocks and inaccessible files explain differences from host capacity usage.
- Processes that start and exit between samples can be missed. Hardware and integration availability depend on your host and edition's permissions.
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements-dev.txt
.venv/bin/python -m pytest -q
# Optional: node tests/test_users.cjs (and the other tests/test_*.cjs files)
python3 scripts/build_locales.py
python3 scripts/build_release.py
python3 scripts/verify_release.py distTo install the source checkout, choose sh install.sh --edition user or sudo sh install.sh --edition admin. For local development, copy config.example.toml to config.toml and run .venv/bin/python run.py --host 127.0.0.1 --port 9100.
To regenerate the synthetic README images:
.venv/bin/python -m playwright install chromium
.venv/bin/python scripts/render_readme.pySee the release guide for uploadable assets and reproducible packaging. Public files come from an explicit allowlist, not a recursive archive of a running installation.
Original NodePeek code: MIT. Bundled Apache ECharts retains its Apache-2.0 license; see third-party notices.






