Introduction

Get started with Joulenap

Joulenap is a self-hosted web UI + scheduler that runs your Proxmox VE backups to Proxmox Backup Servers that stay powered off — waking each one only when it's time, then putting it back to sleep.

What it is

A dedicated Proxmox Backup Server (PBS) is the right way to keep backups on separate hardware — the 3-2-1 rule. But a backup job runs for a few minutes a night, and leaving a second machine powered on 24/7 wastes energy. Proxmox's built-in scheduled backups assume the target is always reachable, so they can't drive a “wake, back up, sleep” cycle — and they certainly can't drive one for a second backup server that only comes up once a week to take an off-site copy.

Joulenap is the missing piece: a small always-on service on your LAN that owns its own schedule, wakes each backup server over Wake-on-LAN when it's needed, runs the job, applies retention and garbage collection, powers the box back down, and notifies you. Every run is logged step by step, can be stopped mid-flight, and can feed your homelab dashboard or Grafana. The name says it — a joule saved, while your backup servers take a nap. 💤

How it works with Proxmox

It talks to every Proxmox VE and PBS through their APIs (using scoped tokens, one per machine) and uses a single SSH command only for the power-off, which has no API. Crucially, it modifies nothing on your Proxmox hosts — no cron, no systemd timers, no scripts on the node. Everything lives in one small container or LXC you run beside Proxmox.

Routes

You list each Proxmox host and each backup server once, then connect them with routes. A route is one scheduled flow of backup data between them: which machines, at what time, on which days, with what retention. Two routes onto the same backup server share its credentials, its wake-up settings and its power lease, so the box is woken once and slept once no matter how many routes need it.

There are four kinds, and Joulenap infers which one you mean from the machines you pick:

A backup server you keep powered on all the time is supported too: turn its managed power setting off and Joulenap treats it as always available instead of trying to wake it.

How a route runs

At the scheduled time, Joulenap runs the whole cycle end to end and logs every step:

  1. Wake

    Sends a Wake-on-LAN magic packet to every backup server the route touches, then polls each until it answers, with retries and a timeout — if one never comes up, the run aborts and notifies you.

  2. Run

    Whatever the route is: vzdump on each source host in turn, a server-to-server sync, a verification, or simply watching the jobs Proxmox starts on its own. Then your retention policy, and garbage collection if you enabled it. Every remote task is followed to completion, with its output streaming into the run.

  3. Power off

    A clean shutdown over SSH — but only once nothing else still needs the box. If another queued route is about to use the same server, it stays awake instead of being woken twice. On failure it stays on so you can inspect it.

  4. Notify

    Sends the result — success or failure, with durations and sizes, naming the route — on your chosen channels. If a route's window passed while Joulenap was down, or a run was interrupted, you're told at the next startup, and no server is ever silently left powered on.

What you'll need

You don't need to prepare API tokens or SSH keys by hand — the guided Add a Proxmox VE and Add a backup server wizards can create the scoped tokens and install the poweroff key for you. The PVE wizard also reads that host's storage configuration to find the backup servers behind it.

A note on security

Joulenap can trigger backups and power machines on and off, so treat it as privileged. It's designed to run on a trusted LAN/VPN, behind its login — not on the public internet. It prefers scoped API tokens over root passwords; if root credentials are supplied during setup, they're used once to provision a scoped token and then discarded. Secrets live only in the container's data directory, never in the repo.