Proxmox backup

Summary

This flow schedules and runs Proxmox VM backups sequentially, enforcing a fixed gap between each backup to control load and avoid concurrent jobs. The pipeline is triggered weekly by a cron scheduler in the Europe/Rome timezone and processes a list of VMIDs one by one with a rate-limiting delay in between.

Scheduler

A cron node is configured with the expression 10 22 * * 5 to fire every Friday at 22:10 local time (Europe/Rome). When it triggers, it emits a message that starts the backup sequence for the defined set of virtual machines.

VM enumeration

A function node “make list” sets msg.payload to an array of VMIDs. This array represents the VMs that will be backed up during the scheduled run. The list can be adapted to include different or dynamic VMIDs.

Message splitting

A split node converts the array into individual messages, one per VMID. This enables strict per-VM processing downstream, ensuring each VM’s backup is handled independently and in sequence.

Inter-backup spacing

A delay node is configured in rate-limit mode to release only one message per defined interval (e.g., 1 msg every N minutes). By placing this node after split, the flow guarantees a “sleep between backups,” preventing back-to-back API calls and reducing storage and API contention.

Payload construction

A function node “make payload” transforms each VMID into a vzdump request: mode: "snapshot", compress: "zstd", storage: "", remove: 1. This sets snapshot-based backups, uses efficient compression, targets the bcknas storage, and cleans up according to the remove flag.

Proxmox API call

A Proxmox API node posts the vzdump request to /nodes/pve/vzdump, executing the backup on the pve node. Each backup is triggered only after the previous one has been spaced out by the delay, ensuring serialized execution.

Observability

A debug node displays responses in the sidebar, aiding verification and troubleshooting during scheduled runs and manual tests.

Module

  node-red-contrib-proxmox
  node-red-contrib-cron-plus
[{"id":"4395e9cb29cc63d8","type":"tab","label":"bck","disabled":false,"info":"","env":[]},{"id":"51175775a54fa64a","type":"debug","z":"4395e9cb29cc63d8","name":"debug 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"jsonata","statusVal":"","statusType":"auto","x":880,"y":160,"wires":[]},{"id":"9fb7e65e79ab415f","type":"proxmox-api","z":"4395e9cb29cc63d8","name":"bckvm","path":"/nodes/pve/vzdump","method":"POST","payload":"msg.payload","server":"ad2b30f4130d3ff1","x":730,"y":160,"wires":[["51175775a54fa64a"]]},{"id":"630ef77e0740f0d1","type":"function","z":"4395e9cb29cc63d8","name":"make list","func":"msg.payload = [101, 102, 103, 104, 105, 106];\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":400,"y":60,"wires":[["20082cea657b8f6a"]]},{"id":"20082cea657b8f6a","type":"split","z":"4395e9cb29cc63d8","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","property":"payload","x":650,"y":60,"wires":[["e08fdfbb6153ad27"]]},{"id":"40afa852ea5c783f","type":"function","z":"4395e9cb29cc63d8","name":"make payload","func":"const vmid = msg.payload;\n\nmsg.payload = {\n    vmid: vmid,\n    mode: \"snapshot\",       // o \"stop\" o \"suspend\"\n    compress: \"zstd\",\n    storage: \"bcknas\",       // qui puoi mettere dinamico se vuoi scegliere storage diverso\n    remove: 1\n\n};\n\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":560,"y":160,"wires":[["9fb7e65e79ab415f"]]},{"id":"e08fdfbb6153ad27","type":"delay","z":"4395e9cb29cc63d8","name":"","pauseType":"rate","timeout":"3","timeoutUnits":"minutes","rate":"1","nbRateUnits":"5","rateUnits":"minute","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":360,"y":160,"wires":[["40afa852ea5c783f"]]},{"id":"edcbe1eae6915e5b","type":"cronplus","z":"4395e9cb29cc63d8","name":"","outputField":"payload","timeZone":"Europe/Rome","storeName":"","commandResponseMsgOutput":"output1","defaultLocation":"","defaultLocationType":"default","outputs":1,"options":[{"name":"schedule1","topic":"topic1","payloadType":"default","payload":"","expressionType":"cron","expression":"10 22 * * 5","location":"","offset":"0","solarType":"all","solarEvents":"sunrise,sunset"}],"x":120,"y":60,"wires":[["630ef77e0740f0d1"]]},{"id":"ad2b30f4130d3ff1","type":"proxmox-server","host":"10.10.10.10","port":8006},{"id":"3171cdfd7e4d846b","type":"global-config","env":[],"modules":{"node-red-contrib-proxmox":"0.0.2","node-red-contrib-cron-plus":"2.2.1"}}]

Flow Info

Created 5 days ago
Rating: 5 1

Owner

Actions

Rate:

Node Types

Core
  • debug (x1)
  • delay (x1)
  • function (x2)
  • split (x1)
Other

Tags

  • proxmox
  • backup
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option