Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tdash

Web dashboard for a Termux server: CPU / load / memory / battery / storage / network / runit service status, served as a small dark page that refreshes every 2s. Runs on Python's standard library.

tdash screenshot

Run

tdash runs on a Termux instance acting as a server and monitors that machine; its services are runit-managed, and the dashboard shows their status with restart/down controls.

Grab the single-file build from the latest release (tdash.pyz), then:

python3 tdash.pyz            # or: python3 tdash.py (source checkout)
python3 tdash.pyz -p mypassword

Open http://<device-ip>:8080/, log in as admin. Flags: --host 127.0.0.1 (localhost only), --no-stop sshd,crond (never-stoppable services), --no-batt-api (never call termux-battery-status), --no-auth (only behind a real auth layer AND localhost — see its warning). python3 tdash.py works from a source checkout instead.

Battery / CPU / network on Android 10+

Configure Shizuku so tdash can read CPU/network/battery without root:

  1. Install and start Shizuku (wireless-ADB or root).
  2. Put rish + rish_shizuku.dex on the Termux $PATH.
  3. Keep Shizuku alive: disable its battery optimization, and set the device's default USB configuration to Charge only (it runs over a wireless-ADB connection that must not be dropped for a cable).

Rooted devices skip all of this and read /proc//sys directly.

How it works

Termux (the untrusted_app domain) can't read /proc/stat, /proc/net/dev, or often /sys/class/power_supply/* without root. On a PermissionError, tdash starts a resident Shizuku rish loop (ADB shell domain) that mirrors those files plus dumpsys battery into /data/local/tmp, and reads the copies. Battery source order: sysfs → sysfs mirror → dumpsys mirror → termux-api. The loop writes atomically (temp-file + mv), skips unchanged writes, exits after 5 min without viewers (heartbeat), and is restarted on demand.

Server setup

The Termux instance is the server being monitored; keep it alive with termux-wake-lock (prevents Doze freezing it), and its services supervised by runit. runsvdir can occasionally die; a standalone watchdog that restarts it — independent of runit, so it survives a crash — pairs well with this: runsvdir watchdog.

Security

  • Basic Auth — fine on a trusted LAN; for public exposure put TLS + real auth in front (e.g. Cloudflare Tunnel + Access).
  • Rate-limited logins (5 fails → 5 min lockout). X-Forwarded-For is trusted only from the local tunnel (127.0.0.1), so LAN clients can't spoof it.
  • Service actions are whitelisted to restart/down; --no-stop services can't be stopped remotely.

Dev & release

Source layout: tdash.py + __main__.py (server), static/ (frontend, loaded at startup — restart after edits), scripts/mirror.sh (rish loop). Pre-commit lint runs py_compile, node --check, bash -n:

cp hooks/pre-commit .git/hooks/pre-commit && chmod +x .git/hooks/pre-commit

Pushing to main runs that lint, then rebuilds and replaces the single latest GitHub Release asset (tdash.pyz, the runnable single file): the old release is deleted, no version tags: https://github.com/inchei/tdash/releases/tag/latest.

To build tdash.pyz locally:

tmp=$(mktemp -d)
cp tdash.py __main__.py "$tmp/"; cp -r static scripts "$tmp/"
python3 -m zipapp "$tmp" -o tdash.pyz -p "/usr/bin/env python3"

License

GPL-3.0-or-later. See LICENSE.

About

minimal termux server dashboard with runit controls

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Contributors

Languages