Pulse — Proxmox Monitoring Dashboard
Project: rcourtman/pulse
Version: 5.1.24
Host: pulse / pulse.home.lab
IP: 10.69.20.60
VLAN: 20 (SERVERS)
VMID: 260
Web UI: http://10.69.20.60:7655
Overview
Pulse is a real-time monitoring dashboard for Proxmox VE and Proxmox Backup Server. It connects to the Proxmox API and provides a live view of nodes, VMs, containers, and backups.
Infrastructure
LXC Container
| Setting | Value |
|---|---|
| Node | pve02 |
| VMID | 260 |
| IP | 10.69.20.60/24 |
| Gateway | 10.69.20.1 |
| CPU | 2 cores |
| RAM | 1024 MB |
| Swap | 256 MB |
| Disk | 8 GB (SSD-Storage) |
| Template | debian-13-standard_13.1-2 |
| Unprivileged | yes |
Ansible
Provisioned and managed via Ansible:
- Playbook:
playbooks/pulse.yml - Role:
roles/pulse/ - Host vars:
inventory/host_vars/pulse/ - Runtime: Podman Quadlet (systemd-managed container)
- Data dir:
/srv/pulse(mounted as/datainside container)
Podman Quadlet
The container is managed as a systemd service via Podman Quadlet:
systemctl status pulse
systemctl restart pulse
podman logs pulse
Monitored Nodes
| Node | Type | Host URL | Token |
|---|---|---|---|
| pve02 | Proxmox VE | https://10.69.10.20:8006 | root@pam!pulse |
| pve01 | Proxmox VE | https://10.69.10.5:8006 | root@pam!pulse |
| pbs01 | Proxmox Backup Server | https://10.69.10.25:8007 | root@pam!pulse |
SSL verification is disabled (self-signed Proxmox certificates).
Firewall
VyOS SERVERS-MGMT policy allows Pulse (PULSE address group) to reach Proxmox APIs:
| Rule | Source | Destination | Port |
|---|---|---|---|
| 130 | PULSE | 10.69.10.20 (pve02) | 8006/TCP |
| 140 | PULSE | 10.69.10.25 (pbs01) | 8007/TCP |
| 150 | PULSE | 10.69.10.5 (pve01) | 8006/TCP |
API Tokens
Proxmox API tokens are created per-node with the following permissions:
VM.AuditSys.AuditDatastore.Audit
Token format: root@pam!pulse
Token secrets are stored in inventory/host_vars/pulse/vault.yml (Ansible Vault).
Alerting — Matrix / Element
Pulse can send alerts to a Matrix room via the hookshot webhook bridge.
Setup
- Follow the hookshot setup docs to create a webhook room and get a secret URL
- In Pulse → Settings → Notifications → Webhooks → Add Webhook:
| Field | Value |
|---|---|
| Name | hookshot - Element |
| HTTP Method | POST |
| Webhook URL | http://10.69.70.40:9000/webhook/<uuid> |
| Content-Type header | application/json |
- Add
10.69.70.40to the private IP allowlist in Pulse → System Settings
Payload Template
{
"text": "🚨 **{{.Level}} Alert** — {{.Message}}\n\n🖥️ **Node:** `{{.Node}}`\n📊 **Resource:** `{{.ResourceName}}`\n📈 **Value:** {{.Value}} *(threshold: {{.Threshold}})*\n⏱️ **Duration:** {{.Duration}}\n🕐 **Time:** {{.Timestamp}}"
}
See hookshot documentation for full details.
Known Issues / Workarounds
Netavark DNAT port forwarding
After container restarts, the netavark nft DNAT chain can have stale rules that prevent port 7655 from being reachable. The Quadlet service file includes a pre-start flush:
ExecStartPre=-/usr/sbin/nft flush chain inet netavark nv_2f259bab_10_88_0_0_nm16_dnat
If the port becomes unreachable after a restart, flush manually:
nft flush chain inet netavark nv_2f259bab_10_88_0_0_nm16_dnat
systemctl restart pulse
Bootstrap token
On first start (or if /srv/pulse is wiped), Pulse generates a bootstrap token required to unlock the UI. Retrieve it from the logs:
podman logs pulse | grep "Token:"