Linux · macOS · Windows Docker ready Python 3.11+ MIT License

UpDownBoard

A lightweight network monitoring dashboard. Each system gets a GREEN or RED tile. Click a RED one to see exactly what broke.

📷 View screenshots →

Router Proxmox Host prod-db-01 GitHub Jenkins Cloudflare DNS VPN NAS
bash — install-linux.sh
# download and run the installer
$ curl -fsSL https://raw.githubusercontent.com/feedmittens/updownboard/main/install-linux.sh \
    -o install.sh
$ chmod +x install.sh && ./install.sh

Ubuntu · Debian · Fedora · RHEL · Arch · and more  ·  Docker, standalone uvicorn, or behind Apache

zsh — install.sh
# download and run the installer
$ curl -fsSL https://raw.githubusercontent.com/feedmittens/updownboard/main/install.sh \
    -o install.sh
$ chmod +x install.sh && ./install.sh

macOS 12+  ·  Docker, standalone uvicorn, or behind Apache

PowerShell — install.ps1
# download and run the installer
PS> Invoke-WebRequest -Uri "https://raw.githubusercontent.com/feedmittens/updownboard/main/install.ps1" `
    -OutFile install.ps1
PS> .\install.ps1

Windows 10/11  ·  PowerShell 5.1+  ·  Docker, standalone uvicorn, or behind IIS

If scripts are blocked: Set-ExecutionPolicy -Scope CurrentUser RemoteSigned

What it does

UpDownBoard polls your configured systems on a schedule and shows their status as a grid of tiles. GREEN = all checks passing. RED = something is broken. Click a RED tile to see the exact check that failed and why. No agents, no cloud services, no dashboards-as-a-subscription. Just a YAML file, a Python process, and a browser.

🟢

RED / GREEN tiles

Dashboard auto-refreshes every 15 seconds. One glance tells you the state of your whole network.

🔍

Click to diagnose

Click any RED tile to expand which check failed — ping, TCP port, HTTP status, or SSH metric — and the exact error message.

📄

Plain-text status feed

/status returns human-readable text: current state + state-change history. Stick it on a secondary monitor with watch curl.

⚙️

YAML configuration

Add or remove systems by editing config.yaml and restarting. No database migrations, no UI forms.

📊

SSH metrics

Monitor CPU load, memory, and disk usage on remote Linux hosts over SSH — no agent required, just key auth and Python.

💾

Local history

State changes are persisted to SQLite. No external database. Query or export it yourself if you want.

🔔

Email notifications

Get alerted when systems go down or recover. Configurable SMTP, cadence, and message templates — all set from a built-in web UI.

Deployment options

The installer will ask you which mode fits — you don't have to decide before running it.

Easiest

Docker

The installer drops a docker-compose.yml, mounts your config.yaml, and starts the container. Works identically on Linux, macOS, and Windows. Runs as a systemd/launchd/Windows service that starts on boot.

Standalone

uvicorn direct

Installs directly into a Python virtualenv. Runs as a native systemd unit (Linux), launchd plist (macOS), or Windows Service via NSSM. No Docker required. Good for VMs, LXC containers, or bare metal.

Production

Behind Apache

Standalone install with an Apache virtual host configured for reverse proxy via mod_proxy. Gives you TLS termination, access logs, and auth via .htpasswd if you want it.

Windows

Behind IIS

Standalone install registered as a Windows Service, with an IIS site configured using Application Request Routing (ARR) as the reverse proxy. Fits naturally into Windows-centric environments.

Check types

Type What it checks Key options
ping ICMP reachability count, timeout
tcp TCP port open port, timeout, label
http HTTP/S GET — checks status code url, expect_status, timeout
ssh_metrics CPU load, memory, disk usage via SSH username, key_file, thresholds
snmp SNMP OID poll — routers, switches, Windows SNMP community, oid, port

What the config looks like

One YAML file. Every system you want to monitor is an entry with a name, a host, and a list of checks.

settings:
  poll_interval: 30       # seconds between check cycles
  history_limit: 500

systems:
  - name: "Router"
    host: "10.0.0.1"
    checks:
      - type: ping
      - type: snmp
        community: "public"
        oid: "1.3.6.1.2.1.1.1.0"

  - name: "Proxmox Host"
    host: "10.0.0.10"
    checks:
      - type: ping
      - type: tcp
        port: 8006
        label: "Web UI"

  - name: "Linux Server"
    host: "10.0.0.20"
    checks:
      - type: ping
      - type: ssh_metrics
        username: monitor
        key_file: "~/.ssh/id_ed25519"
        thresholds:
          cpu_percent: 85
          memory_percent: 90
          disk_percent: 85

  - name: "GitHub"
    host: "github.com"
    checks:
      - type: http
        url: "https://github.com"
        expect_status: 200