Repository files navigation

ProxView

CILicense: MITDocker readyTypeScriptReact 19Fastify 5Read-only

A read-only pane of glass for every Proxmox VE cluster and Proxmox Backup Server you run.

ProxView is a free, self-hosted view-only monitoring dashboard for homelabbers running multiple Proxmox stations — a lightweight, no-licence alternative to Proxmox Datacenter Manager with a one-command deploy. It only ever reads: least-privilege audit API tokens for metrics and a read-only SSH key for temperatures. ProxView never starts, stops, migrates, or changes anything on your nodes — it's a dashboard, not a controller.

ProxView overview — multiple Proxmox VE nodes and a PBS server in one dark dashboard

  • 🖥️ Per-node CPU, memory, disk & temperatures across all your sites, live
  • 📦 VMs & CTs running on each node, with status and resource use
  • 📈 History charts (CPU / memory / temperature) with 1h · 24h · 7d ranges
  • 💾 PBS backup health — datastore fullness, backup freshness, GC & verify status
  • 🌡️ Temperatures via SSH (lm-sensors) — the one thing the Proxmox API can't give you
  • 🔔 Alerts that reach you — offline nodes, near-full datastores, stale backups, hot CPUs; on-screen and via Telegram, Slack, email or browser push (details)
  • 🔒 Secure by default — first-run admin setup, encrypted credentials, localhost-only core
  • 🌐 Optional remote access — guided in-app Cloudflare Tunnel & Tailscale wizards (no .env edits)

How it's meant to run

ProxView reaches each Proxmox VE / PBS station over its API (a read-only audit token) and, for temperatures, over SSH. That works best when ProxView and your stations can talk to each other privately:

  • All on one network? Point ProxView straight at each station's LAN IP.
  • Spread across sites? Put ProxView and your nodes on a Tailscale tailnet or a WireGuard tunnel and add each station by its private IP. Both are set up in one place — Settings → Connectivity.

Keep it off the public internet. ProxView is built for a private LAN or tailnet, not the WWW — it holds credentials for every cluster you run, so it shouldn't be world-facing. To reach it while you're away, prefer Tailscale (visible only to your own devices). For homelabbers who want a simple public URL anyway, a guided Cloudflare Tunnel wizard is included — if you use it, gate the hostname with Cloudflare Access so the dashboard is never left open to the world.

Running on a VPS reached over WireGuard/Tailscale? Publish the port on the tunnel interface, not loopback or 0.0.0.0. With compose, set BIND_ADDR to the host's tunnel IP (e.g. BIND_ADDR=10.0.0.7); with plain docker run, use -p 10.0.0.7:8080:8080. It's then reachable through the tunnel and refused on the public interface.

Quick start (Docker)

git clone https://github.com/freewaretools/proxview.git &&cd proxview
cp .env.example .env # optionally set PROXVIEW_SECRET_KEY (openssl rand -hex 32)
docker compose up -d --build

On first boot ProxView prints a one-time setup link to the logs — open it to create your admin account:

docker compose logs -f app # look for: Setup ProxView: http://localhost:8080/setup?token=...

Then open http://localhost:8080, sign in, and add your sites under Settings.

Try it with synthetic data first (no real cluster needed):

DEMO=1 docker compose up -d --build

Prefer not to build locally? A prebuilt multi-arch image is published to ghcr.io/freewaretools/proxview:latest on each tagged release — set that as the app service's image: in docker-compose.yml to pull instead of build.

Deploy as a Proxmox LXC (one command)

An optional convenience path, not the recommended one — Docker Compose / the image above is the primary way to run ProxView. This spins up a Debian 12 LXC and runs the Docker image inside it (nesting enabled), which some prefer to avoid on principle. It's simply the fastest way from zero to a running dashboard on a box you already have.

Run it on a Proxmox VE host as root — it creates the container, installs Docker, runs ProxView, provisions the admin, and prints a ready-to-use URL + login (no token dance):

bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

Defaults to an unprivileged CT — 2 vCPU / 1 GB RAM / 6 GB disk on vmbr0 (DHCP). Override anything with env vars:

CTID=131 STORAGE=local-zfs RAM_MB=2048 \
NET=192.168.1.50/24 GATEWAY=192.168.1.1 \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

By default it auto-generates a strong admin password and prints it. To choose your own, prepend it to the command (no file editing — this is not the compose path):

PROXVIEW_ADMIN_PASSWORD='choose-your-own' \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

The container is LAN-only — reach it across networks with the in-app Cloudflare/Tailscale wizards. (Tunables: CTID, CT_HOSTNAME, CORES, RAM_MB, DISK_GB, BRIDGE, NET, GATEWAY, STORAGE, PROXVIEW_PORT, PROXVIEW_IMAGE, PROXVIEW_ADMIN_USER, PROXVIEW_ADMIN_PASSWORD.)

Adding a Proxmox VE site

  1. In Proxmox: Datacenter → Permissions → API Tokens, create a token for a user with the PVEAuditor role at / (read-only). Copy the token ID (user@realm!name) and secret.
  2. In ProxView Settings → Add a site: name, https://<host>:8006, the token ID and secret. Leave Verify TLS off for the default self-signed cert.
  3. (Optional) Temperatures: expand Temperatures via SSH, add the node's host, an SSH user, and a read-only private key. Requires apt install lm-sensors on the node.

Proxmox Backup Server works the same way (https://<host>:8007, an Audit token — note PBS uses a colon before the secret, which ProxView handles for you).

Click any node to drill into per-metric history (CPU · memory · temperature · power):

Node detail — CPU, memory, temperature and power history charts

Notifications & alerts

ProxView doesn't just draw graphs — it watches your sites and tells you when something's wrong. Every alert shows on-screen as a banner, and you can add delivery channels so you hear about it even when the dashboard is closed:

  • ChannelsTelegram, Slack, email (SMTP), and browser (web) push. Add as many as you like under Settings → Notifications, each with its own minimum severity (e.g. critical-only Telegram + all-alerts email) and a one-click Send test.
  • Rules — 12 built-in conditions (node offline, memory/CPU/temp/power, datastore full, stale backups, GC/verify failed, lost quorum, …), each with an enable toggle, warning/ critical severity, and a threshold. Tune them under Settings → Alert rules.
  • Smart delivery — an alert must persist for a couple of polls before it fires (no paging on a single blip), optional reminders while it's still active, and a "resolved" note when it clears.

Channel credentials are stored AES-256-GCM encrypted at rest, just like your site tokens.

👉 Full setup guide, all rules and their defaults, and troubleshooting: docs/notifications.md.

Local development

npm install
npm run dev # backend (Fastify) on :8080, frontend (Vite) on :5173 with /api proxy

Remote access (optional, opt-in)

The core stack binds to 127.0.0.1 only. Expose it deliberately from Settings → Connectivity — each wizard links you to the provider to grab a token, then ProxView applies it in-app. No .env edits, no compose commands.

Settings → Remote access & connectivity — Cloudflare Tunnel, Tailscale and WireGuard wizards

  • Cloudflare Tunnel — public HTTPS, no open ports. Create a tunnel in Cloudflare Zero Trust (point the public hostname at http://localhost:8080, gate it with Cloudflare Access), paste the tunnel token, and connect. ProxView runs cloudflared for you.
  • Tailscale — tailnet-only HTTPS via Tailscale Serve. Paste a reusable auth key and connect; ProxView joins your tailnet and becomes reachable at https://proxview.<your-tailnet>.ts.net. Tick Funnel to also expose it publicly. Once ProxView is on the tailnet you can add sites by their 100.x IPs.

Both cloudflared and tailscaled ship inside the image and run in userspace — no extra container privileges. Tokens are stored AES-256-GCM encrypted alongside your site creds.

Serve on a friendly LAN URL, no port (Caddy)

Prefer http://proxview.home over http://192.168.1.50:8080? An optional Caddy reverse proxy serves ProxView on :80 / :443 with automatic HTTPS (Caddy's internal CA, so no public domain needed):

PROXVIEW_HOSTNAME=proxview.home \
docker compose -f docker-compose.yml -f docker-compose.caddy.yml up -d

Caddy handles the port and the cert; you still need name resolution (the app can't invent DNS):

  • .local names resolve automatically via mDNS on macOS/Windows — no setup.
  • Other names (.home, .lan, …) need an A record in your router / Pi-hole / AdGuard, or a hosts entry, pointing at the ProxView host.

LAN-only by intent. On a public VPS, prefer the Cloudflare/Tailscale wizards, or set CADDY_BIND to a private/tunnel IP.

Reach nodes across networks (WireGuard)

WireGuard needs kernel-level networking, so it runs as a compose add-on rather than in-app. In Settings → Connectivity, generate a keypair, fill wireguard/wg0.conf (see wireguard/wg0.conf.example), add the public key as a peer on your WG server, then: docker compose -f docker-compose.yml -f docker-compose.wireguard.yml up -d

Advanced: run the tunnels as compose sidecars instead

If you'd rather not run the tunnels inside the app container, the classic sidecar files are still here: set CF_TUNNEL_TOKEN / TS_AUTHKEY in .env and use docker compose --profile cloudflare up -d or docker compose -f docker-compose.yml -f docker-compose.tailscale.yml up -d.

Architecture

  • backend/ — Fastify + TypeScript. Holds credentials (AES-256-GCM encrypted), polls each site (/cluster/resources, /status/datastore-usage, SSH sensors -j), keeps live snapshots, writes time-series to SQLite, streams updates over SSE, and serves the built frontend.
  • frontend/ — React + Vite + Zustand. Dark, dense monitoring UI (uPlot charts).
  • Ships as one Docker image / one core service. Data (SQLite + secret key) lives in the ./data volume.

Configuration

EnvDefaultPurpose
PORT8080Host port the dashboard is published on
BIND_ADDR127.0.0.1Host interface to publish on. On a VPS, set to your WireGuard/Tailscale IP (e.g. 10.0.0.7) — never 0.0.0.0 on a public box
DEMO01 serves synthetic data
PROXVIEW_SECRET_KEYauto32-byte hex key for credential encryption
PROXVIEW_ADMIN_USER / PROXVIEW_ADMIN_PASSWORDAuto-provision the admin on first boot (skips the setup token). Handy for scripted deploys
POLL_INTERVAL_MS10000PVE/PBS poll cadence — seeds the default only; edit live under Settings → Alert rules
TEMP_INTERVAL_MS45000SSH temperature poll cadence — seeds the default only; edit live under Settings → Alert rules
RETENTION_DAYS30Time-series retention
COOKIE_SECURE0Set 1 when always behind HTTPS

Security notes

  • Read-only by design. ProxView never mutates your clusters — give it audit tokens only: PVE PVEAuditor, PBS Audit. Never root@pam.
  • Back up data/secret.key (or set PROXVIEW_SECRET_KEY): it decrypts your stored site credentials.
  • Keep it on a private network or tailnet. Prefer Tailscale over public exposure; if you use the Cloudflare Tunnel wizard, put Cloudflare Access in front.

Contributing

Issues and PRs are welcome — see CONTRIBUTING.md for dev setup and the (short) ground rules. The most important one: ProxView stays read-only.

License

MIT © 2026 freewaretools


ProxView is an independent project and is not affiliated with, endorsed by, or sponsored by Proxmox Server Solutions GmbH. Proxmox® is a registered trademark of Proxmox Server Solutions GmbH.

About

Free, self-hosted, read-only monitoring dashboard for multiple Proxmox VE + PBS sites — a no-licence alternative to Proxmox Datacenter Manager.

Topics

Resources

Contributing

Stars

12 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

ProxView

CILicense: MITDocker readyTypeScriptReact 19Fastify 5Read-only

A read-only pane of glass for every Proxmox VE cluster and Proxmox Backup Server you run.

ProxView is a free, self-hosted view-only monitoring dashboard for homelabbers running multiple Proxmox stations — a lightweight, no-licence alternative to Proxmox Datacenter Manager with a one-command deploy. It only ever reads: least-privilege audit API tokens for metrics and a read-only SSH key for temperatures. ProxView never starts, stops, migrates, or changes anything on your nodes — it's a dashboard, not a controller.

ProxView overview — multiple Proxmox VE nodes and a PBS server in one dark dashboard

  • 🖥️ Per-node CPU, memory, disk & temperatures across all your sites, live
  • 📦 VMs & CTs running on each node, with status and resource use
  • 📈 History charts (CPU / memory / temperature) with 1h · 24h · 7d ranges
  • 💾 PBS backup health — datastore fullness, backup freshness, GC & verify status
  • 🌡️ Temperatures via SSH (lm-sensors) — the one thing the Proxmox API can't give you
  • 🔔 Alerts that reach you — offline nodes, near-full datastores, stale backups, hot CPUs; on-screen and via Telegram, Slack, email or browser push (details)
  • 🔒 Secure by default — first-run admin setup, encrypted credentials, localhost-only core
  • 🌐 Optional remote access — guided in-app Cloudflare Tunnel & Tailscale wizards (no .env edits)

How it's meant to run

ProxView reaches each Proxmox VE / PBS station over its API (a read-only audit token) and, for temperatures, over SSH. That works best when ProxView and your stations can talk to each other privately:

  • All on one network? Point ProxView straight at each station's LAN IP.
  • Spread across sites? Put ProxView and your nodes on a Tailscale tailnet or a WireGuard tunnel and add each station by its private IP. Both are set up in one place — Settings → Connectivity.

Keep it off the public internet. ProxView is built for a private LAN or tailnet, not the WWW — it holds credentials for every cluster you run, so it shouldn't be world-facing. To reach it while you're away, prefer Tailscale (visible only to your own devices). For homelabbers who want a simple public URL anyway, a guided Cloudflare Tunnel wizard is included — if you use it, gate the hostname with Cloudflare Access so the dashboard is never left open to the world.

Running on a VPS reached over WireGuard/Tailscale? Publish the port on the tunnel interface, not loopback or 0.0.0.0. With compose, set BIND_ADDR to the host's tunnel IP (e.g. BIND_ADDR=10.0.0.7); with plain docker run, use -p 10.0.0.7:8080:8080. It's then reachable through the tunnel and refused on the public interface.

Quick start (Docker)

git clone https://github.com/freewaretools/proxview.git &&cd proxview
cp .env.example .env # optionally set PROXVIEW_SECRET_KEY (openssl rand -hex 32)
docker compose up -d --build

On first boot ProxView prints a one-time setup link to the logs — open it to create your admin account:

docker compose logs -f app # look for: Setup ProxView: http://localhost:8080/setup?token=...

Then open http://localhost:8080, sign in, and add your sites under Settings.

Try it with synthetic data first (no real cluster needed):

DEMO=1 docker compose up -d --build

Prefer not to build locally? A prebuilt multi-arch image is published to ghcr.io/freewaretools/proxview:latest on each tagged release — set that as the app service's image: in docker-compose.yml to pull instead of build.

Deploy as a Proxmox LXC (one command)

An optional convenience path, not the recommended one — Docker Compose / the image above is the primary way to run ProxView. This spins up a Debian 12 LXC and runs the Docker image inside it (nesting enabled), which some prefer to avoid on principle. It's simply the fastest way from zero to a running dashboard on a box you already have.

Run it on a Proxmox VE host as root — it creates the container, installs Docker, runs ProxView, provisions the admin, and prints a ready-to-use URL + login (no token dance):

bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

Defaults to an unprivileged CT — 2 vCPU / 1 GB RAM / 6 GB disk on vmbr0 (DHCP). Override anything with env vars:

CTID=131 STORAGE=local-zfs RAM_MB=2048 \
NET=192.168.1.50/24 GATEWAY=192.168.1.1 \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

By default it auto-generates a strong admin password and prints it. To choose your own, prepend it to the command (no file editing — this is not the compose path):

PROXVIEW_ADMIN_PASSWORD='choose-your-own' \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

The container is LAN-only — reach it across networks with the in-app Cloudflare/Tailscale wizards. (Tunables: CTID, CT_HOSTNAME, CORES, RAM_MB, DISK_GB, BRIDGE, NET, GATEWAY, STORAGE, PROXVIEW_PORT, PROXVIEW_IMAGE, PROXVIEW_ADMIN_USER, PROXVIEW_ADMIN_PASSWORD.)

Adding a Proxmox VE site

  1. In Proxmox: Datacenter → Permissions → API Tokens, create a token for a user with the PVEAuditor role at / (read-only). Copy the token ID (user@realm!name) and secret.
  2. In ProxView Settings → Add a site: name, https://<host>:8006, the token ID and secret. Leave Verify TLS off for the default self-signed cert.
  3. (Optional) Temperatures: expand Temperatures via SSH, add the node's host, an SSH user, and a read-only private key. Requires apt install lm-sensors on the node.

Proxmox Backup Server works the same way (https://<host>:8007, an Audit token — note PBS uses a colon before the secret, which ProxView handles for you).

Click any node to drill into per-metric history (CPU · memory · temperature · power):

Node detail — CPU, memory, temperature and power history charts

Notifications & alerts

ProxView doesn't just draw graphs — it watches your sites and tells you when something's wrong. Every alert shows on-screen as a banner, and you can add delivery channels so you hear about it even when the dashboard is closed:

  • ChannelsTelegram, Slack, email (SMTP), and browser (web) push. Add as many as you like under Settings → Notifications, each with its own minimum severity (e.g. critical-only Telegram + all-alerts email) and a one-click Send test.
  • Rules — 12 built-in conditions (node offline, memory/CPU/temp/power, datastore full, stale backups, GC/verify failed, lost quorum, …), each with an enable toggle, warning/ critical severity, and a threshold. Tune them under Settings → Alert rules.
  • Smart delivery — an alert must persist for a couple of polls before it fires (no paging on a single blip), optional reminders while it's still active, and a "resolved" note when it clears.

Channel credentials are stored AES-256-GCM encrypted at rest, just like your site tokens.

👉 Full setup guide, all rules and their defaults, and troubleshooting: docs/notifications.md.

Local development

npm install
npm run dev # backend (Fastify) on :8080, frontend (Vite) on :5173 with /api proxy

Remote access (optional, opt-in)

The core stack binds to 127.0.0.1 only. Expose it deliberately from Settings → Connectivity — each wizard links you to the provider to grab a token, then ProxView applies it in-app. No .env edits, no compose commands.

Settings → Remote access & connectivity — Cloudflare Tunnel, Tailscale and WireGuard wizards

  • Cloudflare Tunnel — public HTTPS, no open ports. Create a tunnel in Cloudflare Zero Trust (point the public hostname at http://localhost:8080, gate it with Cloudflare Access), paste the tunnel token, and connect. ProxView runs cloudflared for you.
  • Tailscale — tailnet-only HTTPS via Tailscale Serve. Paste a reusable auth key and connect; ProxView joins your tailnet and becomes reachable at https://proxview.<your-tailnet>.ts.net. Tick Funnel to also expose it publicly. Once ProxView is on the tailnet you can add sites by their 100.x IPs.

Both cloudflared and tailscaled ship inside the image and run in userspace — no extra container privileges. Tokens are stored AES-256-GCM encrypted alongside your site creds.

Serve on a friendly LAN URL, no port (Caddy)

Prefer http://proxview.home over http://192.168.1.50:8080? An optional Caddy reverse proxy serves ProxView on :80 / :443 with automatic HTTPS (Caddy's internal CA, so no public domain needed):

PROXVIEW_HOSTNAME=proxview.home \
docker compose -f docker-compose.yml -f docker-compose.caddy.yml up -d

Caddy handles the port and the cert; you still need name resolution (the app can't invent DNS):

  • .local names resolve automatically via mDNS on macOS/Windows — no setup.
  • Other names (.home, .lan, …) need an A record in your router / Pi-hole / AdGuard, or a hosts entry, pointing at the ProxView host.

LAN-only by intent. On a public VPS, prefer the Cloudflare/Tailscale wizards, or set CADDY_BIND to a private/tunnel IP.

Reach nodes across networks (WireGuard)

WireGuard needs kernel-level networking, so it runs as a compose add-on rather than in-app. In Settings → Connectivity, generate a keypair, fill wireguard/wg0.conf (see wireguard/wg0.conf.example), add the public key as a peer on your WG server, then: docker compose -f docker-compose.yml -f docker-compose.wireguard.yml up -d

Advanced: run the tunnels as compose sidecars instead

If you'd rather not run the tunnels inside the app container, the classic sidecar files are still here: set CF_TUNNEL_TOKEN / TS_AUTHKEY in .env and use docker compose --profile cloudflare up -d or docker compose -f docker-compose.yml -f docker-compose.tailscale.yml up -d.

Architecture

  • backend/ — Fastify + TypeScript. Holds credentials (AES-256-GCM encrypted), polls each site (/cluster/resources, /status/datastore-usage, SSH sensors -j), keeps live snapshots, writes time-series to SQLite, streams updates over SSE, and serves the built frontend.
  • frontend/ — React + Vite + Zustand. Dark, dense monitoring UI (uPlot charts).
  • Ships as one Docker image / one core service. Data (SQLite + secret key) lives in the ./data volume.

Configuration

EnvDefaultPurpose
PORT8080Host port the dashboard is published on
BIND_ADDR127.0.0.1Host interface to publish on. On a VPS, set to your WireGuard/Tailscale IP (e.g. 10.0.0.7) — never 0.0.0.0 on a public box
DEMO01 serves synthetic data
PROXVIEW_SECRET_KEYauto32-byte hex key for credential encryption
PROXVIEW_ADMIN_USER / PROXVIEW_ADMIN_PASSWORDAuto-provision the admin on first boot (skips the setup token). Handy for scripted deploys
POLL_INTERVAL_MS10000PVE/PBS poll cadence — seeds the default only; edit live under Settings → Alert rules
TEMP_INTERVAL_MS45000SSH temperature poll cadence — seeds the default only; edit live under Settings → Alert rules
RETENTION_DAYS30Time-series retention
COOKIE_SECURE0Set 1 when always behind HTTPS

Security notes

  • Read-only by design. ProxView never mutates your clusters — give it audit tokens only: PVE PVEAuditor, PBS Audit. Never root@pam.
  • Back up data/secret.key (or set PROXVIEW_SECRET_KEY): it decrypts your stored site credentials.
  • Keep it on a private network or tailnet. Prefer Tailscale over public exposure; if you use the Cloudflare Tunnel wizard, put Cloudflare Access in front.

Contributing

Issues and PRs are welcome — see CONTRIBUTING.md for dev setup and the (short) ground rules. The most important one: ProxView stays read-only.

License

MIT © 2026 freewaretools


ProxView is an independent project and is not affiliated with, endorsed by, or sponsored by Proxmox Server Solutions GmbH. Proxmox® is a registered trademark of Proxmox Server Solutions GmbH.

About

Free, self-hosted, read-only monitoring dashboard for multiple Proxmox VE + PBS sites — a no-licence alternative to Proxmox Datacenter Manager.

Topics

Resources

Contributing

Stars

12 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ProxView

CILicense: MITDocker readyTypeScriptReact 19Fastify 5Read-only

A read-only pane of glass for every Proxmox VE cluster and Proxmox Backup Server you run.

ProxView is a free, self-hosted view-only monitoring dashboard for homelabbers running multiple Proxmox stations — a lightweight, no-licence alternative to Proxmox Datacenter Manager with a one-command deploy. It only ever reads: least-privilege audit API tokens for metrics and a read-only SSH key for temperatures. ProxView never starts, stops, migrates, or changes anything on your nodes — it's a dashboard, not a controller.

ProxView overview — multiple Proxmox VE nodes and a PBS server in one dark dashboard

  • 🖥️ Per-node CPU, memory, disk & temperatures across all your sites, live
  • 📦 VMs & CTs running on each node, with status and resource use
  • 📈 History charts (CPU / memory / temperature) with 1h · 24h · 7d ranges
  • 💾 PBS backup health — datastore fullness, backup freshness, GC & verify status
  • 🌡️ Temperatures via SSH (lm-sensors) — the one thing the Proxmox API can't give you
  • 🔔 Alerts that reach you — offline nodes, near-full datastores, stale backups, hot CPUs; on-screen and via Telegram, Slack, email or browser push (details)
  • 🔒 Secure by default — first-run admin setup, encrypted credentials, localhost-only core
  • 🌐 Optional remote access — guided in-app Cloudflare Tunnel & Tailscale wizards (no .env edits)

How it's meant to run

ProxView reaches each Proxmox VE / PBS station over its API (a read-only audit token) and, for temperatures, over SSH. That works best when ProxView and your stations can talk to each other privately:

  • All on one network? Point ProxView straight at each station's LAN IP.
  • Spread across sites? Put ProxView and your nodes on a Tailscale tailnet or a WireGuard tunnel and add each station by its private IP. Both are set up in one place — Settings → Connectivity.

Keep it off the public internet. ProxView is built for a private LAN or tailnet, not the WWW — it holds credentials for every cluster you run, so it shouldn't be world-facing. To reach it while you're away, prefer Tailscale (visible only to your own devices). For homelabbers who want a simple public URL anyway, a guided Cloudflare Tunnel wizard is included — if you use it, gate the hostname with Cloudflare Access so the dashboard is never left open to the world.

Running on a VPS reached over WireGuard/Tailscale? Publish the port on the tunnel interface, not loopback or 0.0.0.0. With compose, set BIND_ADDR to the host's tunnel IP (e.g. BIND_ADDR=10.0.0.7); with plain docker run, use -p 10.0.0.7:8080:8080. It's then reachable through the tunnel and refused on the public interface.

Quick start (Docker)

git clone https://github.com/freewaretools/proxview.git &&cd proxview
cp .env.example .env # optionally set PROXVIEW_SECRET_KEY (openssl rand -hex 32)
docker compose up -d --build

On first boot ProxView prints a one-time setup link to the logs — open it to create your admin account:

docker compose logs -f app # look for: Setup ProxView: http://localhost:8080/setup?token=...

Then open http://localhost:8080, sign in, and add your sites under Settings.

Try it with synthetic data first (no real cluster needed):

DEMO=1 docker compose up -d --build

Prefer not to build locally? A prebuilt multi-arch image is published to ghcr.io/freewaretools/proxview:latest on each tagged release — set that as the app service's image: in docker-compose.yml to pull instead of build.

Deploy as a Proxmox LXC (one command)

An optional convenience path, not the recommended one — Docker Compose / the image above is the primary way to run ProxView. This spins up a Debian 12 LXC and runs the Docker image inside it (nesting enabled), which some prefer to avoid on principle. It's simply the fastest way from zero to a running dashboard on a box you already have.

Run it on a Proxmox VE host as root — it creates the container, installs Docker, runs ProxView, provisions the admin, and prints a ready-to-use URL + login (no token dance):

bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

Defaults to an unprivileged CT — 2 vCPU / 1 GB RAM / 6 GB disk on vmbr0 (DHCP). Override anything with env vars:

CTID=131 STORAGE=local-zfs RAM_MB=2048 \
NET=192.168.1.50/24 GATEWAY=192.168.1.1 \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

By default it auto-generates a strong admin password and prints it. To choose your own, prepend it to the command (no file editing — this is not the compose path):

PROXVIEW_ADMIN_PASSWORD='choose-your-own' \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

The container is LAN-only — reach it across networks with the in-app Cloudflare/Tailscale wizards. (Tunables: CTID, CT_HOSTNAME, CORES, RAM_MB, DISK_GB, BRIDGE, NET, GATEWAY, STORAGE, PROXVIEW_PORT, PROXVIEW_IMAGE, PROXVIEW_ADMIN_USER, PROXVIEW_ADMIN_PASSWORD.)

Adding a Proxmox VE site

  1. In Proxmox: Datacenter → Permissions → API Tokens, create a token for a user with the PVEAuditor role at / (read-only). Copy the token ID (user@realm!name) and secret.
  2. In ProxView Settings → Add a site: name, https://<host>:8006, the token ID and secret. Leave Verify TLS off for the default self-signed cert.
  3. (Optional) Temperatures: expand Temperatures via SSH, add the node's host, an SSH user, and a read-only private key. Requires apt install lm-sensors on the node.

Proxmox Backup Server works the same way (https://<host>:8007, an Audit token — note PBS uses a colon before the secret, which ProxView handles for you).

Click any node to drill into per-metric history (CPU · memory · temperature · power):

Node detail — CPU, memory, temperature and power history charts

Notifications & alerts

ProxView doesn't just draw graphs — it watches your sites and tells you when something's wrong. Every alert shows on-screen as a banner, and you can add delivery channels so you hear about it even when the dashboard is closed:

  • ChannelsTelegram, Slack, email (SMTP), and browser (web) push. Add as many as you like under Settings → Notifications, each with its own minimum severity (e.g. critical-only Telegram + all-alerts email) and a one-click Send test.
  • Rules — 12 built-in conditions (node offline, memory/CPU/temp/power, datastore full, stale backups, GC/verify failed, lost quorum, …), each with an enable toggle, warning/ critical severity, and a threshold. Tune them under Settings → Alert rules.
  • Smart delivery — an alert must persist for a couple of polls before it fires (no paging on a single blip), optional reminders while it's still active, and a "resolved" note when it clears.

Channel credentials are stored AES-256-GCM encrypted at rest, just like your site tokens.

👉 Full setup guide, all rules and their defaults, and troubleshooting: docs/notifications.md.

Local development

npm install
npm run dev # backend (Fastify) on :8080, frontend (Vite) on :5173 with /api proxy

Remote access (optional, opt-in)

The core stack binds to 127.0.0.1 only. Expose it deliberately from Settings → Connectivity — each wizard links you to the provider to grab a token, then ProxView applies it in-app. No .env edits, no compose commands.

Settings → Remote access & connectivity — Cloudflare Tunnel, Tailscale and WireGuard wizards

  • Cloudflare Tunnel — public HTTPS, no open ports. Create a tunnel in Cloudflare Zero Trust (point the public hostname at http://localhost:8080, gate it with Cloudflare Access), paste the tunnel token, and connect. ProxView runs cloudflared for you.
  • Tailscale — tailnet-only HTTPS via Tailscale Serve. Paste a reusable auth key and connect; ProxView joins your tailnet and becomes reachable at https://proxview.<your-tailnet>.ts.net. Tick Funnel to also expose it publicly. Once ProxView is on the tailnet you can add sites by their 100.x IPs.

Both cloudflared and tailscaled ship inside the image and run in userspace — no extra container privileges. Tokens are stored AES-256-GCM encrypted alongside your site creds.

Serve on a friendly LAN URL, no port (Caddy)

Prefer http://proxview.home over http://192.168.1.50:8080? An optional Caddy reverse proxy serves ProxView on :80 / :443 with automatic HTTPS (Caddy's internal CA, so no public domain needed):

PROXVIEW_HOSTNAME=proxview.home \
docker compose -f docker-compose.yml -f docker-compose.caddy.yml up -d

Caddy handles the port and the cert; you still need name resolution (the app can't invent DNS):

  • .local names resolve automatically via mDNS on macOS/Windows — no setup.
  • Other names (.home, .lan, …) need an A record in your router / Pi-hole / AdGuard, or a hosts entry, pointing at the ProxView host.

LAN-only by intent. On a public VPS, prefer the Cloudflare/Tailscale wizards, or set CADDY_BIND to a private/tunnel IP.

Reach nodes across networks (WireGuard)

WireGuard needs kernel-level networking, so it runs as a compose add-on rather than in-app. In Settings → Connectivity, generate a keypair, fill wireguard/wg0.conf (see wireguard/wg0.conf.example), add the public key as a peer on your WG server, then: docker compose -f docker-compose.yml -f docker-compose.wireguard.yml up -d

Advanced: run the tunnels as compose sidecars instead

If you'd rather not run the tunnels inside the app container, the classic sidecar files are still here: set CF_TUNNEL_TOKEN / TS_AUTHKEY in .env and use docker compose --profile cloudflare up -d or docker compose -f docker-compose.yml -f docker-compose.tailscale.yml up -d.

Architecture

  • backend/ — Fastify + TypeScript. Holds credentials (AES-256-GCM encrypted), polls each site (/cluster/resources, /status/datastore-usage, SSH sensors -j), keeps live snapshots, writes time-series to SQLite, streams updates over SSE, and serves the built frontend.
  • frontend/ — React + Vite + Zustand. Dark, dense monitoring UI (uPlot charts).
  • Ships as one Docker image / one core service. Data (SQLite + secret key) lives in the ./data volume.

Configuration

EnvDefaultPurpose
PORT8080Host port the dashboard is published on
BIND_ADDR127.0.0.1Host interface to publish on. On a VPS, set to your WireGuard/Tailscale IP (e.g. 10.0.0.7) — never 0.0.0.0 on a public box
DEMO01 serves synthetic data
PROXVIEW_SECRET_KEYauto32-byte hex key for credential encryption
PROXVIEW_ADMIN_USER / PROXVIEW_ADMIN_PASSWORDAuto-provision the admin on first boot (skips the setup token). Handy for scripted deploys
POLL_INTERVAL_MS10000PVE/PBS poll cadence — seeds the default only; edit live under Settings → Alert rules
TEMP_INTERVAL_MS45000SSH temperature poll cadence — seeds the default only; edit live under Settings → Alert rules
RETENTION_DAYS30Time-series retention
COOKIE_SECURE0Set 1 when always behind HTTPS

Security notes

  • Read-only by design. ProxView never mutates your clusters — give it audit tokens only: PVE PVEAuditor, PBS Audit. Never root@pam.
  • Back up data/secret.key (or set PROXVIEW_SECRET_KEY): it decrypts your stored site credentials.
  • Keep it on a private network or tailnet. Prefer Tailscale over public exposure; if you use the Cloudflare Tunnel wizard, put Cloudflare Access in front.

Contributing

Issues and PRs are welcome — see CONTRIBUTING.md for dev setup and the (short) ground rules. The most important one: ProxView stays read-only.

License

MIT © 2026 freewaretools


ProxView is an independent project and is not affiliated with, endorsed by, or sponsored by Proxmox Server Solutions GmbH. Proxmox® is a registered trademark of Proxmox Server Solutions GmbH.

About

Free, self-hosted, read-only monitoring dashboard for multiple Proxmox VE + PBS sites — a no-licence alternative to Proxmox Datacenter Manager.

Topics

Resources

Contributing

Stars

12 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ProxView

CILicense: MITDocker readyTypeScriptReact 19Fastify 5Read-only

A read-only pane of glass for every Proxmox VE cluster and Proxmox Backup Server you run.

ProxView is a free, self-hosted view-only monitoring dashboard for homelabbers running multiple Proxmox stations — a lightweight, no-licence alternative to Proxmox Datacenter Manager with a one-command deploy. It only ever reads: least-privilege audit API tokens for metrics and a read-only SSH key for temperatures. ProxView never starts, stops, migrates, or changes anything on your nodes — it's a dashboard, not a controller.

ProxView overview — multiple Proxmox VE nodes and a PBS server in one dark dashboard

  • 🖥️ Per-node CPU, memory, disk & temperatures across all your sites, live
  • 📦 VMs & CTs running on each node, with status and resource use
  • 📈 History charts (CPU / memory / temperature) with 1h · 24h · 7d ranges
  • 💾 PBS backup health — datastore fullness, backup freshness, GC & verify status
  • 🌡️ Temperatures via SSH (lm-sensors) — the one thing the Proxmox API can't give you
  • 🔔 Alerts that reach you — offline nodes, near-full datastores, stale backups, hot CPUs; on-screen and via Telegram, Slack, email or browser push (details)
  • 🔒 Secure by default — first-run admin setup, encrypted credentials, localhost-only core
  • 🌐 Optional remote access — guided in-app Cloudflare Tunnel & Tailscale wizards (no .env edits)

How it's meant to run

ProxView reaches each Proxmox VE / PBS station over its API (a read-only audit token) and, for temperatures, over SSH. That works best when ProxView and your stations can talk to each other privately:

  • All on one network? Point ProxView straight at each station's LAN IP.
  • Spread across sites? Put ProxView and your nodes on a Tailscale tailnet or a WireGuard tunnel and add each station by its private IP. Both are set up in one place — Settings → Connectivity.

Keep it off the public internet. ProxView is built for a private LAN or tailnet, not the WWW — it holds credentials for every cluster you run, so it shouldn't be world-facing. To reach it while you're away, prefer Tailscale (visible only to your own devices). For homelabbers who want a simple public URL anyway, a guided Cloudflare Tunnel wizard is included — if you use it, gate the hostname with Cloudflare Access so the dashboard is never left open to the world.

Running on a VPS reached over WireGuard/Tailscale? Publish the port on the tunnel interface, not loopback or 0.0.0.0. With compose, set BIND_ADDR to the host's tunnel IP (e.g. BIND_ADDR=10.0.0.7); with plain docker run, use -p 10.0.0.7:8080:8080. It's then reachable through the tunnel and refused on the public interface.

Quick start (Docker)

git clone https://github.com/freewaretools/proxview.git &&cd proxview
cp .env.example .env # optionally set PROXVIEW_SECRET_KEY (openssl rand -hex 32)
docker compose up -d --build

On first boot ProxView prints a one-time setup link to the logs — open it to create your admin account:

docker compose logs -f app # look for: Setup ProxView: http://localhost:8080/setup?token=...

Then open http://localhost:8080, sign in, and add your sites under Settings.

Try it with synthetic data first (no real cluster needed):

DEMO=1 docker compose up -d --build

Prefer not to build locally? A prebuilt multi-arch image is published to ghcr.io/freewaretools/proxview:latest on each tagged release — set that as the app service's image: in docker-compose.yml to pull instead of build.

Deploy as a Proxmox LXC (one command)

An optional convenience path, not the recommended one — Docker Compose / the image above is the primary way to run ProxView. This spins up a Debian 12 LXC and runs the Docker image inside it (nesting enabled), which some prefer to avoid on principle. It's simply the fastest way from zero to a running dashboard on a box you already have.

Run it on a Proxmox VE host as root — it creates the container, installs Docker, runs ProxView, provisions the admin, and prints a ready-to-use URL + login (no token dance):

bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

Defaults to an unprivileged CT — 2 vCPU / 1 GB RAM / 6 GB disk on vmbr0 (DHCP). Override anything with env vars:

CTID=131 STORAGE=local-zfs RAM_MB=2048 \
NET=192.168.1.50/24 GATEWAY=192.168.1.1 \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

By default it auto-generates a strong admin password and prints it. To choose your own, prepend it to the command (no file editing — this is not the compose path):

PROXVIEW_ADMIN_PASSWORD='choose-your-own' \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

The container is LAN-only — reach it across networks with the in-app Cloudflare/Tailscale wizards. (Tunables: CTID, CT_HOSTNAME, CORES, RAM_MB, DISK_GB, BRIDGE, NET, GATEWAY, STORAGE, PROXVIEW_PORT, PROXVIEW_IMAGE, PROXVIEW_ADMIN_USER, PROXVIEW_ADMIN_PASSWORD.)

Adding a Proxmox VE site

  1. In Proxmox: Datacenter → Permissions → API Tokens, create a token for a user with the PVEAuditor role at / (read-only). Copy the token ID (user@realm!name) and secret.
  2. In ProxView Settings → Add a site: name, https://<host>:8006, the token ID and secret. Leave Verify TLS off for the default self-signed cert.
  3. (Optional) Temperatures: expand Temperatures via SSH, add the node's host, an SSH user, and a read-only private key. Requires apt install lm-sensors on the node.

Proxmox Backup Server works the same way (https://<host>:8007, an Audit token — note PBS uses a colon before the secret, which ProxView handles for you).

Click any node to drill into per-metric history (CPU · memory · temperature · power):

Node detail — CPU, memory, temperature and power history charts

Notifications & alerts

ProxView doesn't just draw graphs — it watches your sites and tells you when something's wrong. Every alert shows on-screen as a banner, and you can add delivery channels so you hear about it even when the dashboard is closed:

  • ChannelsTelegram, Slack, email (SMTP), and browser (web) push. Add as many as you like under Settings → Notifications, each with its own minimum severity (e.g. critical-only Telegram + all-alerts email) and a one-click Send test.
  • Rules — 12 built-in conditions (node offline, memory/CPU/temp/power, datastore full, stale backups, GC/verify failed, lost quorum, …), each with an enable toggle, warning/ critical severity, and a threshold. Tune them under Settings → Alert rules.
  • Smart delivery — an alert must persist for a couple of polls before it fires (no paging on a single blip), optional reminders while it's still active, and a "resolved" note when it clears.

Channel credentials are stored AES-256-GCM encrypted at rest, just like your site tokens.

👉 Full setup guide, all rules and their defaults, and troubleshooting: docs/notifications.md.

Local development

npm install
npm run dev # backend (Fastify) on :8080, frontend (Vite) on :5173 with /api proxy

Remote access (optional, opt-in)

The core stack binds to 127.0.0.1 only. Expose it deliberately from Settings → Connectivity — each wizard links you to the provider to grab a token, then ProxView applies it in-app. No .env edits, no compose commands.

Settings → Remote access & connectivity — Cloudflare Tunnel, Tailscale and WireGuard wizards

  • Cloudflare Tunnel — public HTTPS, no open ports. Create a tunnel in Cloudflare Zero Trust (point the public hostname at http://localhost:8080, gate it with Cloudflare Access), paste the tunnel token, and connect. ProxView runs cloudflared for you.
  • Tailscale — tailnet-only HTTPS via Tailscale Serve. Paste a reusable auth key and connect; ProxView joins your tailnet and becomes reachable at https://proxview.<your-tailnet>.ts.net. Tick Funnel to also expose it publicly. Once ProxView is on the tailnet you can add sites by their 100.x IPs.

Both cloudflared and tailscaled ship inside the image and run in userspace — no extra container privileges. Tokens are stored AES-256-GCM encrypted alongside your site creds.

Serve on a friendly LAN URL, no port (Caddy)

Prefer http://proxview.home over http://192.168.1.50:8080? An optional Caddy reverse proxy serves ProxView on :80 / :443 with automatic HTTPS (Caddy's internal CA, so no public domain needed):

PROXVIEW_HOSTNAME=proxview.home \
docker compose -f docker-compose.yml -f docker-compose.caddy.yml up -d

Caddy handles the port and the cert; you still need name resolution (the app can't invent DNS):

  • .local names resolve automatically via mDNS on macOS/Windows — no setup.
  • Other names (.home, .lan, …) need an A record in your router / Pi-hole / AdGuard, or a hosts entry, pointing at the ProxView host.

LAN-only by intent. On a public VPS, prefer the Cloudflare/Tailscale wizards, or set CADDY_BIND to a private/tunnel IP.

Reach nodes across networks (WireGuard)

WireGuard needs kernel-level networking, so it runs as a compose add-on rather than in-app. In Settings → Connectivity, generate a keypair, fill wireguard/wg0.conf (see wireguard/wg0.conf.example), add the public key as a peer on your WG server, then: docker compose -f docker-compose.yml -f docker-compose.wireguard.yml up -d

Advanced: run the tunnels as compose sidecars instead

If you'd rather not run the tunnels inside the app container, the classic sidecar files are still here: set CF_TUNNEL_TOKEN / TS_AUTHKEY in .env and use docker compose --profile cloudflare up -d or docker compose -f docker-compose.yml -f docker-compose.tailscale.yml up -d.

Architecture

  • backend/ — Fastify + TypeScript. Holds credentials (AES-256-GCM encrypted), polls each site (/cluster/resources, /status/datastore-usage, SSH sensors -j), keeps live snapshots, writes time-series to SQLite, streams updates over SSE, and serves the built frontend.
  • frontend/ — React + Vite + Zustand. Dark, dense monitoring UI (uPlot charts).
  • Ships as one Docker image / one core service. Data (SQLite + secret key) lives in the ./data volume.

Configuration

EnvDefaultPurpose
PORT8080Host port the dashboard is published on
BIND_ADDR127.0.0.1Host interface to publish on. On a VPS, set to your WireGuard/Tailscale IP (e.g. 10.0.0.7) — never 0.0.0.0 on a public box
DEMO01 serves synthetic data
PROXVIEW_SECRET_KEYauto32-byte hex key for credential encryption
PROXVIEW_ADMIN_USER / PROXVIEW_ADMIN_PASSWORDAuto-provision the admin on first boot (skips the setup token). Handy for scripted deploys
POLL_INTERVAL_MS10000PVE/PBS poll cadence — seeds the default only; edit live under Settings → Alert rules
TEMP_INTERVAL_MS45000SSH temperature poll cadence — seeds the default only; edit live under Settings → Alert rules
RETENTION_DAYS30Time-series retention
COOKIE_SECURE0Set 1 when always behind HTTPS

Security notes

  • Read-only by design. ProxView never mutates your clusters — give it audit tokens only: PVE PVEAuditor, PBS Audit. Never root@pam.
  • Back up data/secret.key (or set PROXVIEW_SECRET_KEY): it decrypts your stored site credentials.
  • Keep it on a private network or tailnet. Prefer Tailscale over public exposure; if you use the Cloudflare Tunnel wizard, put Cloudflare Access in front.

Contributing

Issues and PRs are welcome — see CONTRIBUTING.md for dev setup and the (short) ground rules. The most important one: ProxView stays read-only.

License

MIT © 2026 freewaretools


ProxView is an independent project and is not affiliated with, endorsed by, or sponsored by Proxmox Server Solutions GmbH. Proxmox® is a registered trademark of Proxmox Server Solutions GmbH.

About

Free, self-hosted, read-only monitoring dashboard for multiple Proxmox VE + PBS sites — a no-licence alternative to Proxmox Datacenter Manager.

Topics

Resources

Contributing

Stars

12 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

ProxView

CILicense: MITDocker readyTypeScriptReact 19Fastify 5Read-only

A read-only pane of glass for every Proxmox VE cluster and Proxmox Backup Server you run.

ProxView is a free, self-hosted view-only monitoring dashboard for homelabbers running multiple Proxmox stations — a lightweight, no-licence alternative to Proxmox Datacenter Manager with a one-command deploy. It only ever reads: least-privilege audit API tokens for metrics and a read-only SSH key for temperatures. ProxView never starts, stops, migrates, or changes anything on your nodes — it's a dashboard, not a controller.

ProxView overview — multiple Proxmox VE nodes and a PBS server in one dark dashboard

  • 🖥️ Per-node CPU, memory, disk & temperatures across all your sites, live
  • 📦 VMs & CTs running on each node, with status and resource use
  • 📈 History charts (CPU / memory / temperature) with 1h · 24h · 7d ranges
  • 💾 PBS backup health — datastore fullness, backup freshness, GC & verify status
  • 🌡️ Temperatures via SSH (lm-sensors) — the one thing the Proxmox API can't give you
  • 🔔 Alerts that reach you — offline nodes, near-full datastores, stale backups, hot CPUs; on-screen and via Telegram, Slack, email or browser push (details)
  • 🔒 Secure by default — first-run admin setup, encrypted credentials, localhost-only core
  • 🌐 Optional remote access — guided in-app Cloudflare Tunnel & Tailscale wizards (no .env edits)

How it's meant to run

ProxView reaches each Proxmox VE / PBS station over its API (a read-only audit token) and, for temperatures, over SSH. That works best when ProxView and your stations can talk to each other privately:

  • All on one network? Point ProxView straight at each station's LAN IP.
  • Spread across sites? Put ProxView and your nodes on a Tailscale tailnet or a WireGuard tunnel and add each station by its private IP. Both are set up in one place — Settings → Connectivity.

Keep it off the public internet. ProxView is built for a private LAN or tailnet, not the WWW — it holds credentials for every cluster you run, so it shouldn't be world-facing. To reach it while you're away, prefer Tailscale (visible only to your own devices). For homelabbers who want a simple public URL anyway, a guided Cloudflare Tunnel wizard is included — if you use it, gate the hostname with Cloudflare Access so the dashboard is never left open to the world.

Running on a VPS reached over WireGuard/Tailscale? Publish the port on the tunnel interface, not loopback or 0.0.0.0. With compose, set BIND_ADDR to the host's tunnel IP (e.g. BIND_ADDR=10.0.0.7); with plain docker run, use -p 10.0.0.7:8080:8080. It's then reachable through the tunnel and refused on the public interface.

Quick start (Docker)

git clone https://github.com/freewaretools/proxview.git &&cd proxview
cp .env.example .env # optionally set PROXVIEW_SECRET_KEY (openssl rand -hex 32)
docker compose up -d --build

On first boot ProxView prints a one-time setup link to the logs — open it to create your admin account:

docker compose logs -f app # look for: Setup ProxView: http://localhost:8080/setup?token=...

Then open http://localhost:8080, sign in, and add your sites under Settings.

Try it with synthetic data first (no real cluster needed):

DEMO=1 docker compose up -d --build

Prefer not to build locally? A prebuilt multi-arch image is published to ghcr.io/freewaretools/proxview:latest on each tagged release — set that as the app service's image: in docker-compose.yml to pull instead of build.

Deploy as a Proxmox LXC (one command)

An optional convenience path, not the recommended one — Docker Compose / the image above is the primary way to run ProxView. This spins up a Debian 12 LXC and runs the Docker image inside it (nesting enabled), which some prefer to avoid on principle. It's simply the fastest way from zero to a running dashboard on a box you already have.

Run it on a Proxmox VE host as root — it creates the container, installs Docker, runs ProxView, provisions the admin, and prints a ready-to-use URL + login (no token dance):

bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

Defaults to an unprivileged CT — 2 vCPU / 1 GB RAM / 6 GB disk on vmbr0 (DHCP). Override anything with env vars:

CTID=131 STORAGE=local-zfs RAM_MB=2048 \
NET=192.168.1.50/24 GATEWAY=192.168.1.1 \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

By default it auto-generates a strong admin password and prints it. To choose your own, prepend it to the command (no file editing — this is not the compose path):

PROXVIEW_ADMIN_PASSWORD='choose-your-own' \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

The container is LAN-only — reach it across networks with the in-app Cloudflare/Tailscale wizards. (Tunables: CTID, CT_HOSTNAME, CORES, RAM_MB, DISK_GB, BRIDGE, NET, GATEWAY, STORAGE, PROXVIEW_PORT, PROXVIEW_IMAGE, PROXVIEW_ADMIN_USER, PROXVIEW_ADMIN_PASSWORD.)

Adding a Proxmox VE site

  1. In Proxmox: Datacenter → Permissions → API Tokens, create a token for a user with the PVEAuditor role at / (read-only). Copy the token ID (user@realm!name) and secret.
  2. In ProxView Settings → Add a site: name, https://<host>:8006, the token ID and secret. Leave Verify TLS off for the default self-signed cert.
  3. (Optional) Temperatures: expand Temperatures via SSH, add the node's host, an SSH user, and a read-only private key. Requires apt install lm-sensors on the node.

Proxmox Backup Server works the same way (https://<host>:8007, an Audit token — note PBS uses a colon before the secret, which ProxView handles for you).

Click any node to drill into per-metric history (CPU · memory · temperature · power):

Node detail — CPU, memory, temperature and power history charts

Notifications & alerts

ProxView doesn't just draw graphs — it watches your sites and tells you when something's wrong. Every alert shows on-screen as a banner, and you can add delivery channels so you hear about it even when the dashboard is closed:

  • ChannelsTelegram, Slack, email (SMTP), and browser (web) push. Add as many as you like under Settings → Notifications, each with its own minimum severity (e.g. critical-only Telegram + all-alerts email) and a one-click Send test.
  • Rules — 12 built-in conditions (node offline, memory/CPU/temp/power, datastore full, stale backups, GC/verify failed, lost quorum, …), each with an enable toggle, warning/ critical severity, and a threshold. Tune them under Settings → Alert rules.
  • Smart delivery — an alert must persist for a couple of polls before it fires (no paging on a single blip), optional reminders while it's still active, and a "resolved" note when it clears.

Channel credentials are stored AES-256-GCM encrypted at rest, just like your site tokens.

👉 Full setup guide, all rules and their defaults, and troubleshooting: docs/notifications.md.

Local development

npm install
npm run dev # backend (Fastify) on :8080, frontend (Vite) on :5173 with /api proxy

Remote access (optional, opt-in)

The core stack binds to 127.0.0.1 only. Expose it deliberately from Settings → Connectivity — each wizard links you to the provider to grab a token, then ProxView applies it in-app. No .env edits, no compose commands.

Settings → Remote access & connectivity — Cloudflare Tunnel, Tailscale and WireGuard wizards

  • Cloudflare Tunnel — public HTTPS, no open ports. Create a tunnel in Cloudflare Zero Trust (point the public hostname at http://localhost:8080, gate it with Cloudflare Access), paste the tunnel token, and connect. ProxView runs cloudflared for you.
  • Tailscale — tailnet-only HTTPS via Tailscale Serve. Paste a reusable auth key and connect; ProxView joins your tailnet and becomes reachable at https://proxview.<your-tailnet>.ts.net. Tick Funnel to also expose it publicly. Once ProxView is on the tailnet you can add sites by their 100.x IPs.

Both cloudflared and tailscaled ship inside the image and run in userspace — no extra container privileges. Tokens are stored AES-256-GCM encrypted alongside your site creds.

Serve on a friendly LAN URL, no port (Caddy)

Prefer http://proxview.home over http://192.168.1.50:8080? An optional Caddy reverse proxy serves ProxView on :80 / :443 with automatic HTTPS (Caddy's internal CA, so no public domain needed):

PROXVIEW_HOSTNAME=proxview.home \
docker compose -f docker-compose.yml -f docker-compose.caddy.yml up -d

Caddy handles the port and the cert; you still need name resolution (the app can't invent DNS):

  • .local names resolve automatically via mDNS on macOS/Windows — no setup.
  • Other names (.home, .lan, …) need an A record in your router / Pi-hole / AdGuard, or a hosts entry, pointing at the ProxView host.

LAN-only by intent. On a public VPS, prefer the Cloudflare/Tailscale wizards, or set CADDY_BIND to a private/tunnel IP.

Reach nodes across networks (WireGuard)

WireGuard needs kernel-level networking, so it runs as a compose add-on rather than in-app. In Settings → Connectivity, generate a keypair, fill wireguard/wg0.conf (see wireguard/wg0.conf.example), add the public key as a peer on your WG server, then: docker compose -f docker-compose.yml -f docker-compose.wireguard.yml up -d

Advanced: run the tunnels as compose sidecars instead

If you'd rather not run the tunnels inside the app container, the classic sidecar files are still here: set CF_TUNNEL_TOKEN / TS_AUTHKEY in .env and use docker compose --profile cloudflare up -d or docker compose -f docker-compose.yml -f docker-compose.tailscale.yml up -d.

Architecture

  • backend/ — Fastify + TypeScript. Holds credentials (AES-256-GCM encrypted), polls each site (/cluster/resources, /status/datastore-usage, SSH sensors -j), keeps live snapshots, writes time-series to SQLite, streams updates over SSE, and serves the built frontend.
  • frontend/ — React + Vite + Zustand. Dark, dense monitoring UI (uPlot charts).
  • Ships as one Docker image / one core service. Data (SQLite + secret key) lives in the ./data volume.

Configuration

EnvDefaultPurpose
PORT8080Host port the dashboard is published on
BIND_ADDR127.0.0.1Host interface to publish on. On a VPS, set to your WireGuard/Tailscale IP (e.g. 10.0.0.7) — never 0.0.0.0 on a public box
DEMO01 serves synthetic data
PROXVIEW_SECRET_KEYauto32-byte hex key for credential encryption
PROXVIEW_ADMIN_USER / PROXVIEW_ADMIN_PASSWORDAuto-provision the admin on first boot (skips the setup token). Handy for scripted deploys
POLL_INTERVAL_MS10000PVE/PBS poll cadence — seeds the default only; edit live under Settings → Alert rules
TEMP_INTERVAL_MS45000SSH temperature poll cadence — seeds the default only; edit live under Settings → Alert rules
RETENTION_DAYS30Time-series retention
COOKIE_SECURE0Set 1 when always behind HTTPS

Security notes

  • Read-only by design. ProxView never mutates your clusters — give it audit tokens only: PVE PVEAuditor, PBS Audit. Never root@pam.
  • Back up data/secret.key (or set PROXVIEW_SECRET_KEY): it decrypts your stored site credentials.
  • Keep it on a private network or tailnet. Prefer Tailscale over public exposure; if you use the Cloudflare Tunnel wizard, put Cloudflare Access in front.

Contributing

Issues and PRs are welcome — see CONTRIBUTING.md for dev setup and the (short) ground rules. The most important one: ProxView stays read-only.

License

MIT © 2026 freewaretools


ProxView is an independent project and is not affiliated with, endorsed by, or sponsored by Proxmox Server Solutions GmbH. Proxmox® is a registered trademark of Proxmox Server Solutions GmbH.

About

Free, self-hosted, read-only monitoring dashboard for multiple Proxmox VE + PBS sites — a no-licence alternative to Proxmox Datacenter Manager.

Topics

Resources

Contributing

Stars

12 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ProxView

CILicense: MITDocker readyTypeScriptReact 19Fastify 5Read-only

A read-only pane of glass for every Proxmox VE cluster and Proxmox Backup Server you run.

ProxView is a free, self-hosted view-only monitoring dashboard for homelabbers running multiple Proxmox stations — a lightweight, no-licence alternative to Proxmox Datacenter Manager with a one-command deploy. It only ever reads: least-privilege audit API tokens for metrics and a read-only SSH key for temperatures. ProxView never starts, stops, migrates, or changes anything on your nodes — it's a dashboard, not a controller.

ProxView overview — multiple Proxmox VE nodes and a PBS server in one dark dashboard

  • 🖥️ Per-node CPU, memory, disk & temperatures across all your sites, live
  • 📦 VMs & CTs running on each node, with status and resource use
  • 📈 History charts (CPU / memory / temperature) with 1h · 24h · 7d ranges
  • 💾 PBS backup health — datastore fullness, backup freshness, GC & verify status
  • 🌡️ Temperatures via SSH (lm-sensors) — the one thing the Proxmox API can't give you
  • 🔔 Alerts that reach you — offline nodes, near-full datastores, stale backups, hot CPUs; on-screen and via Telegram, Slack, email or browser push (details)
  • 🔒 Secure by default — first-run admin setup, encrypted credentials, localhost-only core
  • 🌐 Optional remote access — guided in-app Cloudflare Tunnel & Tailscale wizards (no .env edits)

How it's meant to run

ProxView reaches each Proxmox VE / PBS station over its API (a read-only audit token) and, for temperatures, over SSH. That works best when ProxView and your stations can talk to each other privately:

  • All on one network? Point ProxView straight at each station's LAN IP.
  • Spread across sites? Put ProxView and your nodes on a Tailscale tailnet or a WireGuard tunnel and add each station by its private IP. Both are set up in one place — Settings → Connectivity.

Keep it off the public internet. ProxView is built for a private LAN or tailnet, not the WWW — it holds credentials for every cluster you run, so it shouldn't be world-facing. To reach it while you're away, prefer Tailscale (visible only to your own devices). For homelabbers who want a simple public URL anyway, a guided Cloudflare Tunnel wizard is included — if you use it, gate the hostname with Cloudflare Access so the dashboard is never left open to the world.

Running on a VPS reached over WireGuard/Tailscale? Publish the port on the tunnel interface, not loopback or 0.0.0.0. With compose, set BIND_ADDR to the host's tunnel IP (e.g. BIND_ADDR=10.0.0.7); with plain docker run, use -p 10.0.0.7:8080:8080. It's then reachable through the tunnel and refused on the public interface.

Quick start (Docker)

git clone https://github.com/freewaretools/proxview.git &&cd proxview
cp .env.example .env # optionally set PROXVIEW_SECRET_KEY (openssl rand -hex 32)
docker compose up -d --build

On first boot ProxView prints a one-time setup link to the logs — open it to create your admin account:

docker compose logs -f app # look for: Setup ProxView: http://localhost:8080/setup?token=...

Then open http://localhost:8080, sign in, and add your sites under Settings.

Try it with synthetic data first (no real cluster needed):

DEMO=1 docker compose up -d --build

Prefer not to build locally? A prebuilt multi-arch image is published to ghcr.io/freewaretools/proxview:latest on each tagged release — set that as the app service's image: in docker-compose.yml to pull instead of build.

Deploy as a Proxmox LXC (one command)

An optional convenience path, not the recommended one — Docker Compose / the image above is the primary way to run ProxView. This spins up a Debian 12 LXC and runs the Docker image inside it (nesting enabled), which some prefer to avoid on principle. It's simply the fastest way from zero to a running dashboard on a box you already have.

Run it on a Proxmox VE host as root — it creates the container, installs Docker, runs ProxView, provisions the admin, and prints a ready-to-use URL + login (no token dance):

bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

Defaults to an unprivileged CT — 2 vCPU / 1 GB RAM / 6 GB disk on vmbr0 (DHCP). Override anything with env vars:

CTID=131 STORAGE=local-zfs RAM_MB=2048 \
NET=192.168.1.50/24 GATEWAY=192.168.1.1 \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

By default it auto-generates a strong admin password and prints it. To choose your own, prepend it to the command (no file editing — this is not the compose path):

PROXVIEW_ADMIN_PASSWORD='choose-your-own' \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

The container is LAN-only — reach it across networks with the in-app Cloudflare/Tailscale wizards. (Tunables: CTID, CT_HOSTNAME, CORES, RAM_MB, DISK_GB, BRIDGE, NET, GATEWAY, STORAGE, PROXVIEW_PORT, PROXVIEW_IMAGE, PROXVIEW_ADMIN_USER, PROXVIEW_ADMIN_PASSWORD.)

Adding a Proxmox VE site

  1. In Proxmox: Datacenter → Permissions → API Tokens, create a token for a user with the PVEAuditor role at / (read-only). Copy the token ID (user@realm!name) and secret.
  2. In ProxView Settings → Add a site: name, https://<host>:8006, the token ID and secret. Leave Verify TLS off for the default self-signed cert.
  3. (Optional) Temperatures: expand Temperatures via SSH, add the node's host, an SSH user, and a read-only private key. Requires apt install lm-sensors on the node.

Proxmox Backup Server works the same way (https://<host>:8007, an Audit token — note PBS uses a colon before the secret, which ProxView handles for you).

Click any node to drill into per-metric history (CPU · memory · temperature · power):

Node detail — CPU, memory, temperature and power history charts

Notifications & alerts

ProxView doesn't just draw graphs — it watches your sites and tells you when something's wrong. Every alert shows on-screen as a banner, and you can add delivery channels so you hear about it even when the dashboard is closed:

  • ChannelsTelegram, Slack, email (SMTP), and browser (web) push. Add as many as you like under Settings → Notifications, each with its own minimum severity (e.g. critical-only Telegram + all-alerts email) and a one-click Send test.
  • Rules — 12 built-in conditions (node offline, memory/CPU/temp/power, datastore full, stale backups, GC/verify failed, lost quorum, …), each with an enable toggle, warning/ critical severity, and a threshold. Tune them under Settings → Alert rules.
  • Smart delivery — an alert must persist for a couple of polls before it fires (no paging on a single blip), optional reminders while it's still active, and a "resolved" note when it clears.

Channel credentials are stored AES-256-GCM encrypted at rest, just like your site tokens.

👉 Full setup guide, all rules and their defaults, and troubleshooting: docs/notifications.md.

Local development

npm install
npm run dev # backend (Fastify) on :8080, frontend (Vite) on :5173 with /api proxy

Remote access (optional, opt-in)

The core stack binds to 127.0.0.1 only. Expose it deliberately from Settings → Connectivity — each wizard links you to the provider to grab a token, then ProxView applies it in-app. No .env edits, no compose commands.

Settings → Remote access & connectivity — Cloudflare Tunnel, Tailscale and WireGuard wizards

  • Cloudflare Tunnel — public HTTPS, no open ports. Create a tunnel in Cloudflare Zero Trust (point the public hostname at http://localhost:8080, gate it with Cloudflare Access), paste the tunnel token, and connect. ProxView runs cloudflared for you.
  • Tailscale — tailnet-only HTTPS via Tailscale Serve. Paste a reusable auth key and connect; ProxView joins your tailnet and becomes reachable at https://proxview.<your-tailnet>.ts.net. Tick Funnel to also expose it publicly. Once ProxView is on the tailnet you can add sites by their 100.x IPs.

Both cloudflared and tailscaled ship inside the image and run in userspace — no extra container privileges. Tokens are stored AES-256-GCM encrypted alongside your site creds.

Serve on a friendly LAN URL, no port (Caddy)

Prefer http://proxview.home over http://192.168.1.50:8080? An optional Caddy reverse proxy serves ProxView on :80 / :443 with automatic HTTPS (Caddy's internal CA, so no public domain needed):

PROXVIEW_HOSTNAME=proxview.home \
docker compose -f docker-compose.yml -f docker-compose.caddy.yml up -d

Caddy handles the port and the cert; you still need name resolution (the app can't invent DNS):

  • .local names resolve automatically via mDNS on macOS/Windows — no setup.
  • Other names (.home, .lan, …) need an A record in your router / Pi-hole / AdGuard, or a hosts entry, pointing at the ProxView host.

LAN-only by intent. On a public VPS, prefer the Cloudflare/Tailscale wizards, or set CADDY_BIND to a private/tunnel IP.

Reach nodes across networks (WireGuard)

WireGuard needs kernel-level networking, so it runs as a compose add-on rather than in-app. In Settings → Connectivity, generate a keypair, fill wireguard/wg0.conf (see wireguard/wg0.conf.example), add the public key as a peer on your WG server, then: docker compose -f docker-compose.yml -f docker-compose.wireguard.yml up -d

Advanced: run the tunnels as compose sidecars instead

If you'd rather not run the tunnels inside the app container, the classic sidecar files are still here: set CF_TUNNEL_TOKEN / TS_AUTHKEY in .env and use docker compose --profile cloudflare up -d or docker compose -f docker-compose.yml -f docker-compose.tailscale.yml up -d.

Architecture

  • backend/ — Fastify + TypeScript. Holds credentials (AES-256-GCM encrypted), polls each site (/cluster/resources, /status/datastore-usage, SSH sensors -j), keeps live snapshots, writes time-series to SQLite, streams updates over SSE, and serves the built frontend.
  • frontend/ — React + Vite + Zustand. Dark, dense monitoring UI (uPlot charts).
  • Ships as one Docker image / one core service. Data (SQLite + secret key) lives in the ./data volume.

Configuration

EnvDefaultPurpose
PORT8080Host port the dashboard is published on
BIND_ADDR127.0.0.1Host interface to publish on. On a VPS, set to your WireGuard/Tailscale IP (e.g. 10.0.0.7) — never 0.0.0.0 on a public box
DEMO01 serves synthetic data
PROXVIEW_SECRET_KEYauto32-byte hex key for credential encryption
PROXVIEW_ADMIN_USER / PROXVIEW_ADMIN_PASSWORDAuto-provision the admin on first boot (skips the setup token). Handy for scripted deploys
POLL_INTERVAL_MS10000PVE/PBS poll cadence — seeds the default only; edit live under Settings → Alert rules
TEMP_INTERVAL_MS45000SSH temperature poll cadence — seeds the default only; edit live under Settings → Alert rules
RETENTION_DAYS30Time-series retention
COOKIE_SECURE0Set 1 when always behind HTTPS

Security notes

  • Read-only by design. ProxView never mutates your clusters — give it audit tokens only: PVE PVEAuditor, PBS Audit. Never root@pam.
  • Back up data/secret.key (or set PROXVIEW_SECRET_KEY): it decrypts your stored site credentials.
  • Keep it on a private network or tailnet. Prefer Tailscale over public exposure; if you use the Cloudflare Tunnel wizard, put Cloudflare Access in front.

Contributing

Issues and PRs are welcome — see CONTRIBUTING.md for dev setup and the (short) ground rules. The most important one: ProxView stays read-only.

License

MIT © 2026 freewaretools


ProxView is an independent project and is not affiliated with, endorsed by, or sponsored by Proxmox Server Solutions GmbH. Proxmox® is a registered trademark of Proxmox Server Solutions GmbH.

About

Free, self-hosted, read-only monitoring dashboard for multiple Proxmox VE + PBS sites — a no-licence alternative to Proxmox Datacenter Manager.

Topics

Resources

Contributing

Stars

12 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ProxView

CILicense: MITDocker readyTypeScriptReact 19Fastify 5Read-only

A read-only pane of glass for every Proxmox VE cluster and Proxmox Backup Server you run.

ProxView is a free, self-hosted view-only monitoring dashboard for homelabbers running multiple Proxmox stations — a lightweight, no-licence alternative to Proxmox Datacenter Manager with a one-command deploy. It only ever reads: least-privilege audit API tokens for metrics and a read-only SSH key for temperatures. ProxView never starts, stops, migrates, or changes anything on your nodes — it's a dashboard, not a controller.

ProxView overview — multiple Proxmox VE nodes and a PBS server in one dark dashboard

  • 🖥️ Per-node CPU, memory, disk & temperatures across all your sites, live
  • 📦 VMs & CTs running on each node, with status and resource use
  • 📈 History charts (CPU / memory / temperature) with 1h · 24h · 7d ranges
  • 💾 PBS backup health — datastore fullness, backup freshness, GC & verify status
  • 🌡️ Temperatures via SSH (lm-sensors) — the one thing the Proxmox API can't give you
  • 🔔 Alerts that reach you — offline nodes, near-full datastores, stale backups, hot CPUs; on-screen and via Telegram, Slack, email or browser push (details)
  • 🔒 Secure by default — first-run admin setup, encrypted credentials, localhost-only core
  • 🌐 Optional remote access — guided in-app Cloudflare Tunnel & Tailscale wizards (no .env edits)

How it's meant to run

ProxView reaches each Proxmox VE / PBS station over its API (a read-only audit token) and, for temperatures, over SSH. That works best when ProxView and your stations can talk to each other privately:

  • All on one network? Point ProxView straight at each station's LAN IP.
  • Spread across sites? Put ProxView and your nodes on a Tailscale tailnet or a WireGuard tunnel and add each station by its private IP. Both are set up in one place — Settings → Connectivity.

Keep it off the public internet. ProxView is built for a private LAN or tailnet, not the WWW — it holds credentials for every cluster you run, so it shouldn't be world-facing. To reach it while you're away, prefer Tailscale (visible only to your own devices). For homelabbers who want a simple public URL anyway, a guided Cloudflare Tunnel wizard is included — if you use it, gate the hostname with Cloudflare Access so the dashboard is never left open to the world.

Running on a VPS reached over WireGuard/Tailscale? Publish the port on the tunnel interface, not loopback or 0.0.0.0. With compose, set BIND_ADDR to the host's tunnel IP (e.g. BIND_ADDR=10.0.0.7); with plain docker run, use -p 10.0.0.7:8080:8080. It's then reachable through the tunnel and refused on the public interface.

Quick start (Docker)

git clone https://github.com/freewaretools/proxview.git &&cd proxview
cp .env.example .env # optionally set PROXVIEW_SECRET_KEY (openssl rand -hex 32)
docker compose up -d --build

On first boot ProxView prints a one-time setup link to the logs — open it to create your admin account:

docker compose logs -f app # look for: Setup ProxView: http://localhost:8080/setup?token=...

Then open http://localhost:8080, sign in, and add your sites under Settings.

Try it with synthetic data first (no real cluster needed):

DEMO=1 docker compose up -d --build

Prefer not to build locally? A prebuilt multi-arch image is published to ghcr.io/freewaretools/proxview:latest on each tagged release — set that as the app service's image: in docker-compose.yml to pull instead of build.

Deploy as a Proxmox LXC (one command)

An optional convenience path, not the recommended one — Docker Compose / the image above is the primary way to run ProxView. This spins up a Debian 12 LXC and runs the Docker image inside it (nesting enabled), which some prefer to avoid on principle. It's simply the fastest way from zero to a running dashboard on a box you already have.

Run it on a Proxmox VE host as root — it creates the container, installs Docker, runs ProxView, provisions the admin, and prints a ready-to-use URL + login (no token dance):

bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

Defaults to an unprivileged CT — 2 vCPU / 1 GB RAM / 6 GB disk on vmbr0 (DHCP). Override anything with env vars:

CTID=131 STORAGE=local-zfs RAM_MB=2048 \
NET=192.168.1.50/24 GATEWAY=192.168.1.1 \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

By default it auto-generates a strong admin password and prints it. To choose your own, prepend it to the command (no file editing — this is not the compose path):

PROXVIEW_ADMIN_PASSWORD='choose-your-own' \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

The container is LAN-only — reach it across networks with the in-app Cloudflare/Tailscale wizards. (Tunables: CTID, CT_HOSTNAME, CORES, RAM_MB, DISK_GB, BRIDGE, NET, GATEWAY, STORAGE, PROXVIEW_PORT, PROXVIEW_IMAGE, PROXVIEW_ADMIN_USER, PROXVIEW_ADMIN_PASSWORD.)

Adding a Proxmox VE site

  1. In Proxmox: Datacenter → Permissions → API Tokens, create a token for a user with the PVEAuditor role at / (read-only). Copy the token ID (user@realm!name) and secret.
  2. In ProxView Settings → Add a site: name, https://<host>:8006, the token ID and secret. Leave Verify TLS off for the default self-signed cert.
  3. (Optional) Temperatures: expand Temperatures via SSH, add the node's host, an SSH user, and a read-only private key. Requires apt install lm-sensors on the node.

Proxmox Backup Server works the same way (https://<host>:8007, an Audit token — note PBS uses a colon before the secret, which ProxView handles for you).

Click any node to drill into per-metric history (CPU · memory · temperature · power):

Node detail — CPU, memory, temperature and power history charts

Notifications & alerts

ProxView doesn't just draw graphs — it watches your sites and tells you when something's wrong. Every alert shows on-screen as a banner, and you can add delivery channels so you hear about it even when the dashboard is closed:

  • ChannelsTelegram, Slack, email (SMTP), and browser (web) push. Add as many as you like under Settings → Notifications, each with its own minimum severity (e.g. critical-only Telegram + all-alerts email) and a one-click Send test.
  • Rules — 12 built-in conditions (node offline, memory/CPU/temp/power, datastore full, stale backups, GC/verify failed, lost quorum, …), each with an enable toggle, warning/ critical severity, and a threshold. Tune them under Settings → Alert rules.
  • Smart delivery — an alert must persist for a couple of polls before it fires (no paging on a single blip), optional reminders while it's still active, and a "resolved" note when it clears.

Channel credentials are stored AES-256-GCM encrypted at rest, just like your site tokens.

👉 Full setup guide, all rules and their defaults, and troubleshooting: docs/notifications.md.

Local development

npm install
npm run dev # backend (Fastify) on :8080, frontend (Vite) on :5173 with /api proxy

Remote access (optional, opt-in)

The core stack binds to 127.0.0.1 only. Expose it deliberately from Settings → Connectivity — each wizard links you to the provider to grab a token, then ProxView applies it in-app. No .env edits, no compose commands.

Settings → Remote access & connectivity — Cloudflare Tunnel, Tailscale and WireGuard wizards

  • Cloudflare Tunnel — public HTTPS, no open ports. Create a tunnel in Cloudflare Zero Trust (point the public hostname at http://localhost:8080, gate it with Cloudflare Access), paste the tunnel token, and connect. ProxView runs cloudflared for you.
  • Tailscale — tailnet-only HTTPS via Tailscale Serve. Paste a reusable auth key and connect; ProxView joins your tailnet and becomes reachable at https://proxview.<your-tailnet>.ts.net. Tick Funnel to also expose it publicly. Once ProxView is on the tailnet you can add sites by their 100.x IPs.

Both cloudflared and tailscaled ship inside the image and run in userspace — no extra container privileges. Tokens are stored AES-256-GCM encrypted alongside your site creds.

Serve on a friendly LAN URL, no port (Caddy)

Prefer http://proxview.home over http://192.168.1.50:8080? An optional Caddy reverse proxy serves ProxView on :80 / :443 with automatic HTTPS (Caddy's internal CA, so no public domain needed):

PROXVIEW_HOSTNAME=proxview.home \
docker compose -f docker-compose.yml -f docker-compose.caddy.yml up -d

Caddy handles the port and the cert; you still need name resolution (the app can't invent DNS):

  • .local names resolve automatically via mDNS on macOS/Windows — no setup.
  • Other names (.home, .lan, …) need an A record in your router / Pi-hole / AdGuard, or a hosts entry, pointing at the ProxView host.

LAN-only by intent. On a public VPS, prefer the Cloudflare/Tailscale wizards, or set CADDY_BIND to a private/tunnel IP.

Reach nodes across networks (WireGuard)

WireGuard needs kernel-level networking, so it runs as a compose add-on rather than in-app. In Settings → Connectivity, generate a keypair, fill wireguard/wg0.conf (see wireguard/wg0.conf.example), add the public key as a peer on your WG server, then: docker compose -f docker-compose.yml -f docker-compose.wireguard.yml up -d

Advanced: run the tunnels as compose sidecars instead

If you'd rather not run the tunnels inside the app container, the classic sidecar files are still here: set CF_TUNNEL_TOKEN / TS_AUTHKEY in .env and use docker compose --profile cloudflare up -d or docker compose -f docker-compose.yml -f docker-compose.tailscale.yml up -d.

Architecture

  • backend/ — Fastify + TypeScript. Holds credentials (AES-256-GCM encrypted), polls each site (/cluster/resources, /status/datastore-usage, SSH sensors -j), keeps live snapshots, writes time-series to SQLite, streams updates over SSE, and serves the built frontend.
  • frontend/ — React + Vite + Zustand. Dark, dense monitoring UI (uPlot charts).
  • Ships as one Docker image / one core service. Data (SQLite + secret key) lives in the ./data volume.

Configuration

EnvDefaultPurpose
PORT8080Host port the dashboard is published on
BIND_ADDR127.0.0.1Host interface to publish on. On a VPS, set to your WireGuard/Tailscale IP (e.g. 10.0.0.7) — never 0.0.0.0 on a public box
DEMO01 serves synthetic data
PROXVIEW_SECRET_KEYauto32-byte hex key for credential encryption
PROXVIEW_ADMIN_USER / PROXVIEW_ADMIN_PASSWORDAuto-provision the admin on first boot (skips the setup token). Handy for scripted deploys
POLL_INTERVAL_MS10000PVE/PBS poll cadence — seeds the default only; edit live under Settings → Alert rules
TEMP_INTERVAL_MS45000SSH temperature poll cadence — seeds the default only; edit live under Settings → Alert rules
RETENTION_DAYS30Time-series retention
COOKIE_SECURE0Set 1 when always behind HTTPS

Security notes

  • Read-only by design. ProxView never mutates your clusters — give it audit tokens only: PVE PVEAuditor, PBS Audit. Never root@pam.
  • Back up data/secret.key (or set PROXVIEW_SECRET_KEY): it decrypts your stored site credentials.
  • Keep it on a private network or tailnet. Prefer Tailscale over public exposure; if you use the Cloudflare Tunnel wizard, put Cloudflare Access in front.

Contributing

Issues and PRs are welcome — see CONTRIBUTING.md for dev setup and the (short) ground rules. The most important one: ProxView stays read-only.

License

MIT © 2026 freewaretools


ProxView is an independent project and is not affiliated with, endorsed by, or sponsored by Proxmox Server Solutions GmbH. Proxmox® is a registered trademark of Proxmox Server Solutions GmbH.

About

Free, self-hosted, read-only monitoring dashboard for multiple Proxmox VE + PBS sites — a no-licence alternative to Proxmox Datacenter Manager.

Topics

Resources

Contributing

Stars

12 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

ProxView

CILicense: MITDocker readyTypeScriptReact 19Fastify 5Read-only

A read-only pane of glass for every Proxmox VE cluster and Proxmox Backup Server you run.

ProxView is a free, self-hosted view-only monitoring dashboard for homelabbers running multiple Proxmox stations — a lightweight, no-licence alternative to Proxmox Datacenter Manager with a one-command deploy. It only ever reads: least-privilege audit API tokens for metrics and a read-only SSH key for temperatures. ProxView never starts, stops, migrates, or changes anything on your nodes — it's a dashboard, not a controller.

ProxView overview — multiple Proxmox VE nodes and a PBS server in one dark dashboard

  • 🖥️ Per-node CPU, memory, disk & temperatures across all your sites, live
  • 📦 VMs & CTs running on each node, with status and resource use
  • 📈 History charts (CPU / memory / temperature) with 1h · 24h · 7d ranges
  • 💾 PBS backup health — datastore fullness, backup freshness, GC & verify status
  • 🌡️ Temperatures via SSH (lm-sensors) — the one thing the Proxmox API can't give you
  • 🔔 Alerts that reach you — offline nodes, near-full datastores, stale backups, hot CPUs; on-screen and via Telegram, Slack, email or browser push (details)
  • 🔒 Secure by default — first-run admin setup, encrypted credentials, localhost-only core
  • 🌐 Optional remote access — guided in-app Cloudflare Tunnel & Tailscale wizards (no .env edits)

How it's meant to run

ProxView reaches each Proxmox VE / PBS station over its API (a read-only audit token) and, for temperatures, over SSH. That works best when ProxView and your stations can talk to each other privately:

  • All on one network? Point ProxView straight at each station's LAN IP.
  • Spread across sites? Put ProxView and your nodes on a Tailscale tailnet or a WireGuard tunnel and add each station by its private IP. Both are set up in one place — Settings → Connectivity.

Keep it off the public internet. ProxView is built for a private LAN or tailnet, not the WWW — it holds credentials for every cluster you run, so it shouldn't be world-facing. To reach it while you're away, prefer Tailscale (visible only to your own devices). For homelabbers who want a simple public URL anyway, a guided Cloudflare Tunnel wizard is included — if you use it, gate the hostname with Cloudflare Access so the dashboard is never left open to the world.

Running on a VPS reached over WireGuard/Tailscale? Publish the port on the tunnel interface, not loopback or 0.0.0.0. With compose, set BIND_ADDR to the host's tunnel IP (e.g. BIND_ADDR=10.0.0.7); with plain docker run, use -p 10.0.0.7:8080:8080. It's then reachable through the tunnel and refused on the public interface.

Quick start (Docker)

git clone https://github.com/freewaretools/proxview.git &&cd proxview
cp .env.example .env # optionally set PROXVIEW_SECRET_KEY (openssl rand -hex 32)
docker compose up -d --build

On first boot ProxView prints a one-time setup link to the logs — open it to create your admin account:

docker compose logs -f app # look for: Setup ProxView: http://localhost:8080/setup?token=...

Then open http://localhost:8080, sign in, and add your sites under Settings.

Try it with synthetic data first (no real cluster needed):

DEMO=1 docker compose up -d --build

Prefer not to build locally? A prebuilt multi-arch image is published to ghcr.io/freewaretools/proxview:latest on each tagged release — set that as the app service's image: in docker-compose.yml to pull instead of build.

Deploy as a Proxmox LXC (one command)

An optional convenience path, not the recommended one — Docker Compose / the image above is the primary way to run ProxView. This spins up a Debian 12 LXC and runs the Docker image inside it (nesting enabled), which some prefer to avoid on principle. It's simply the fastest way from zero to a running dashboard on a box you already have.

Run it on a Proxmox VE host as root — it creates the container, installs Docker, runs ProxView, provisions the admin, and prints a ready-to-use URL + login (no token dance):

bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

Defaults to an unprivileged CT — 2 vCPU / 1 GB RAM / 6 GB disk on vmbr0 (DHCP). Override anything with env vars:

CTID=131 STORAGE=local-zfs RAM_MB=2048 \
NET=192.168.1.50/24 GATEWAY=192.168.1.1 \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

By default it auto-generates a strong admin password and prints it. To choose your own, prepend it to the command (no file editing — this is not the compose path):

PROXVIEW_ADMIN_PASSWORD='choose-your-own' \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/freewaretools/proxview/main/proxmox/proxview-lxc.sh)"

The container is LAN-only — reach it across networks with the in-app Cloudflare/Tailscale wizards. (Tunables: CTID, CT_HOSTNAME, CORES, RAM_MB, DISK_GB, BRIDGE, NET, GATEWAY, STORAGE, PROXVIEW_PORT, PROXVIEW_IMAGE, PROXVIEW_ADMIN_USER, PROXVIEW_ADMIN_PASSWORD.)

Adding a Proxmox VE site

  1. In Proxmox: Datacenter → Permissions → API Tokens, create a token for a user with the PVEAuditor role at / (read-only). Copy the token ID (user@realm!name) and secret.
  2. In ProxView Settings → Add a site: name, https://<host>:8006, the token ID and secret. Leave Verify TLS off for the default self-signed cert.
  3. (Optional) Temperatures: expand Temperatures via SSH, add the node's host, an SSH user, and a read-only private key. Requires apt install lm-sensors on the node.

Proxmox Backup Server works the same way (https://<host>:8007, an Audit token — note PBS uses a colon before the secret, which ProxView handles for you).

Click any node to drill into per-metric history (CPU · memory · temperature · power):

Node detail — CPU, memory, temperature and power history charts

Notifications & alerts

ProxView doesn't just draw graphs — it watches your sites and tells you when something's wrong. Every alert shows on-screen as a banner, and you can add delivery channels so you hear about it even when the dashboard is closed:

  • ChannelsTelegram, Slack, email (SMTP), and browser (web) push. Add as many as you like under Settings → Notifications, each with its own minimum severity (e.g. critical-only Telegram + all-alerts email) and a one-click Send test.
  • Rules — 12 built-in conditions (node offline, memory/CPU/temp/power, datastore full, stale backups, GC/verify failed, lost quorum, …), each with an enable toggle, warning/ critical severity, and a threshold. Tune them under Settings → Alert rules.
  • Smart delivery — an alert must persist for a couple of polls before it fires (no paging on a single blip), optional reminders while it's still active, and a "resolved" note when it clears.

Channel credentials are stored AES-256-GCM encrypted at rest, just like your site tokens.

👉 Full setup guide, all rules and their defaults, and troubleshooting: docs/notifications.md.

Local development

npm install
npm run dev # backend (Fastify) on :8080, frontend (Vite) on :5173 with /api proxy

Remote access (optional, opt-in)

The core stack binds to 127.0.0.1 only. Expose it deliberately from Settings → Connectivity — each wizard links you to the provider to grab a token, then ProxView applies it in-app. No .env edits, no compose commands.

Settings → Remote access & connectivity — Cloudflare Tunnel, Tailscale and WireGuard wizards

  • Cloudflare Tunnel — public HTTPS, no open ports. Create a tunnel in Cloudflare Zero Trust (point the public hostname at http://localhost:8080, gate it with Cloudflare Access), paste the tunnel token, and connect. ProxView runs cloudflared for you.
  • Tailscale — tailnet-only HTTPS via Tailscale Serve. Paste a reusable auth key and connect; ProxView joins your tailnet and becomes reachable at https://proxview.<your-tailnet>.ts.net. Tick Funnel to also expose it publicly. Once ProxView is on the tailnet you can add sites by their 100.x IPs.

Both cloudflared and tailscaled ship inside the image and run in userspace — no extra container privileges. Tokens are stored AES-256-GCM encrypted alongside your site creds.

Serve on a friendly LAN URL, no port (Caddy)

Prefer http://proxview.home over http://192.168.1.50:8080? An optional Caddy reverse proxy serves ProxView on :80 / :443 with automatic HTTPS (Caddy's internal CA, so no public domain needed):

PROXVIEW_HOSTNAME=proxview.home \
docker compose -f docker-compose.yml -f docker-compose.caddy.yml up -d

Caddy handles the port and the cert; you still need name resolution (the app can't invent DNS):

  • .local names resolve automatically via mDNS on macOS/Windows — no setup.
  • Other names (.home, .lan, …) need an A record in your router / Pi-hole / AdGuard, or a hosts entry, pointing at the ProxView host.

LAN-only by intent. On a public VPS, prefer the Cloudflare/Tailscale wizards, or set CADDY_BIND to a private/tunnel IP.

Reach nodes across networks (WireGuard)

WireGuard needs kernel-level networking, so it runs as a compose add-on rather than in-app. In Settings → Connectivity, generate a keypair, fill wireguard/wg0.conf (see wireguard/wg0.conf.example), add the public key as a peer on your WG server, then: docker compose -f docker-compose.yml -f docker-compose.wireguard.yml up -d

Advanced: run the tunnels as compose sidecars instead

If you'd rather not run the tunnels inside the app container, the classic sidecar files are still here: set CF_TUNNEL_TOKEN / TS_AUTHKEY in .env and use docker compose --profile cloudflare up -d or docker compose -f docker-compose.yml -f docker-compose.tailscale.yml up -d.

Architecture

  • backend/ — Fastify + TypeScript. Holds credentials (AES-256-GCM encrypted), polls each site (/cluster/resources, /status/datastore-usage, SSH sensors -j), keeps live snapshots, writes time-series to SQLite, streams updates over SSE, and serves the built frontend.
  • frontend/ — React + Vite + Zustand. Dark, dense monitoring UI (uPlot charts).
  • Ships as one Docker image / one core service. Data (SQLite + secret key) lives in the ./data volume.

Configuration

EnvDefaultPurpose
PORT8080Host port the dashboard is published on
BIND_ADDR127.0.0.1Host interface to publish on. On a VPS, set to your WireGuard/Tailscale IP (e.g. 10.0.0.7) — never 0.0.0.0 on a public box
DEMO01 serves synthetic data
PROXVIEW_SECRET_KEYauto32-byte hex key for credential encryption
PROXVIEW_ADMIN_USER / PROXVIEW_ADMIN_PASSWORDAuto-provision the admin on first boot (skips the setup token). Handy for scripted deploys
POLL_INTERVAL_MS10000PVE/PBS poll cadence — seeds the default only; edit live under Settings → Alert rules
TEMP_INTERVAL_MS45000SSH temperature poll cadence — seeds the default only; edit live under Settings → Alert rules
RETENTION_DAYS30Time-series retention
COOKIE_SECURE0Set 1 when always behind HTTPS

Security notes

  • Read-only by design. ProxView never mutates your clusters — give it audit tokens only: PVE PVEAuditor, PBS Audit. Never root@pam.
  • Back up data/secret.key (or set PROXVIEW_SECRET_KEY): it decrypts your stored site credentials.
  • Keep it on a private network or tailnet. Prefer Tailscale over public exposure; if you use the Cloudflare Tunnel wizard, put Cloudflare Access in front.

Contributing

Issues and PRs are welcome — see CONTRIBUTING.md for dev setup and the (short) ground rules. The most important one: ProxView stays read-only.

License

MIT © 2026 freewaretools


ProxView is an independent project and is not affiliated with, endorsed by, or sponsored by Proxmox Server Solutions GmbH. Proxmox® is a registered trademark of Proxmox Server Solutions GmbH.

About

Free, self-hosted, read-only monitoring dashboard for multiple Proxmox VE + PBS sites — a no-licence alternative to Proxmox Datacenter Manager.

Topics

Resources

Contributing

Stars

12 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages