UPS and Graceful Shutdown
Why a dirty power loss is a much bigger deal once ZFS and multiple VMs are in the picture, and how NUT gets everything shut down cleanly before the battery runs out.
A single Docker box losing power is annoying - most containers restart cleanly once power's back. Once you're running ZFS pools and several VMs on Proxmox, a dirty power loss is a bigger deal: ZFS is designed to survive it without corruption (that's part of its value proposition - see Storage and ZFS), but VMs mid-write and databases without proper journaling can still end up in a bad state. A UPS with automated graceful shutdown closes that gap.
Sizing a UPS honestly
Ignore the manufacturer's advertised runtime figure - it's typically measured at a fraction of the UPS's rated capacity, not against your actual load. What matters:
- VA/W rating vs. your actual total load (check the power draw numbers from Power, Noise, and Thermals, now summed across everything on the UPS - the Proxmox host, any networking gear you also want protected).
- You don't need enough runtime to ride out a long outage. The goal is a clean, automated shutdown within a couple of minutes of losing power, not staying online through a multi-hour blackout. A UPS sized for 5-10 minutes of runtime at your actual load is enough for this purpose.
- Buy more capacity than your current load, not exactly enough - UPS batteries degrade over 3-5 years, and headroom now means you're not immediately undersized once that happens.
NUT (Network UPS Tools): the piece that makes shutdown automatic
A UPS with just a USB cable only protects the one machine it's plugged into, and only if something's watching for the "on battery" signal. NUT solves both problems: one machine (the one physically connected to the UPS via USB) runs as the NUT server, and every other machine that needs to shut down gracefully - other Proxmox nodes, if you have more than one - runs as a NUT client, receiving the shutdown signal over the network when the server reports the battery is critically low.
On a Proxmox host you're logged in as root, so no sudo:
# On the machine physically connected to the UPS
apt install nut
/etc/nut/nut.conf - this machine serves UPS status to the network:
MODE=netserver
/etc/nut/ups.conf - the UPS itself:
[myups]
driver = usbhid-ups
port = auto
desc = "Main UPS"
/etc/nut/upsd.conf (set LISTEN to this machine's LAN address so
clients can connect) and /etc/nut/upsd.users (a monitoring user and
password) control who's allowed to query status. Then
/etc/nut/upsmon.conf tells the local monitor what to watch and what
to run:
MONITOR myups@localhost 1 upsmon your-upsd-password primary
SHUTDOWNCMD "/sbin/shutdown -h +0"
On each other machine that should shut down (a second Proxmox node, a
separate NAS), install nut too, set MODE=netclient in nut.conf,
and point its upsmon.conf at the server instead:
MONITOR [email protected] 1 upsmon your-upsd-password secondary
SHUTDOWNCMD "/sbin/shutdown -h +0"
By default upsmon starts the shutdown when the UPS reports low
battery. Secondaries shut down first; the primary waits for them,
then shuts itself down. If your UPS's low-battery point leaves too
little runtime for everything to stop cleanly (see below), NUT's
upssched can trigger the shutdown earlier instead - for example,
after being on battery for two minutes.
Shutdown ordering with Proxmox
You don't need a custom shutdown script for Proxmox. A normal host
shutdown (which is all SHUTDOWNCMD does) already shuts guests down
cleanly before the host powers off: Proxmox sends each running VM and
container a shutdown request and waits for it. What you do need to
get right is how that happens:
- Make sure every VM actually responds to a shutdown request. For
Linux VMs, install
qemu-guest-agentinside the guest and enable QEMU Guest Agent in the VM's Options. A VM that ignores the request just sits there until its timeout, then gets force-stopped. - Set the order. Proxmox shuts guests down in the reverse of their startup order (Guest > Options > Start/Shutdown order). Give anything other guests depend on - a NAS VM serving NFS shares, your DNS server - a low order number. It then starts first and shuts down last, after the services that mount its shares are already stopped.
- Set realistic timeouts. The same dialog has a shutdown timeout
per guest; after it runs out, that guest is force-stopped. Add up
the worst-case shutdown time of everything on the host and check
the UPS can supply that much runtime after the low-battery
signal - otherwise trigger earlier with
upssched.
⚠️ Risk: don't "help" by replacing
SHUTDOWNCMDwith a script that sleeps a fixed number of seconds and then powers off. It works until a guest is slower than usual (a VM mid-backup, for instance) and gets killed mid-write anyway - exactly what the UPS was meant to prevent. Test the whole sequence once by pulling the UPS's wall plug while you watch, rather than finding out during a real outage.
A note for clusters
If you're running a multi-node Proxmox cluster (see Proxmox Clustering and HA in Advanced), coordinated shutdown gets more involved - losing nodes in the wrong order can affect quorum before the remaining nodes have finished shutting down cleanly themselves. Worth revisiting this page's approach once you're at that stage rather than assuming the single-host script above scales as-is.
Next: Proxmox Backups.