Joulenap runs beside Proxmox — not on a PVE host itself — as a tiny always-on container or service on the same LAN as the backup servers it wakes. Pick the path that fits you.
Every step from scratch: create the container, install Docker, one command.
DOCKERAlready have Docker, or want to pre-edit config.
ADVANCEDRun it directly as a Python service under systemd.
Before you start: enable Wake-on-LAN on each backup server (a BIOS/UEFI setting, sometimes also ethtool -s <iface> wol g) and put Joulenap on the same LAN/subnet as those servers — Wake-on-LAN can't cross routers. Keep the UI on your LAN/VPN.
The simplest reliable path: a small Debian LXC on your Proxmox host, Docker inside it, then one command. No files to download and no config to edit by hand — the container creates its own config and you finish in the browser.
In the Proxmox web UI, Create CT from a Debian 12 template: 1 core, 512 MB RAM, 4 GB disk. Bridge its network onto the same VLAN/subnet as your backup servers — this is the setting that matters most.
Select the container → Options → Features → nesting, then start it. (Docker needs this inside an LXC.)
Open the container's Console (log in as root), then install Docker's official build:
# inside the LXC
apt update && apt install -y curl
curl -fsSL https://get.docker.com | sh
Seeing perl: warning: Setting locale failed? Fresh Debian LXCs ship without a generated locale — it's harmless and the install still succeeds. Silence it with update-locale LANG=C.UTF-8 (permanent, from the next login) and export LANG=C.UTF-8 LC_ALL=C.UTF-8 (takes effect in the current shell).
One command. Docker pulls the image from Docker Hub and the container seeds its own config on first boot:
mkdir -p /opt/joulenap/data docker run -d --name joulenap \ --restart unless-stopped \ --network host \ -e TZ=Etc/UTC \ -v /opt/joulenap/data:/app/data \ catubba/joulenap:latest
--network host lets it send the Wake-on-LAN broadcast; the single data folder holds config, history, logs and the SSH key. You'll pick your timezone on the first-run screen (pre-detected from your browser), so leave TZ as-is.
Browse to http://<container-ip>:8080 and continue at First run.
Use this if you already run Docker, or want to pre-edit config.yaml. There's no separate config file to create — it's seeded into ./data on first run.
mkdir -p joulenap && cd joulenap # grab just the compose file curl -fsSL -o docker-compose.yml \ https://raw.githubusercontent.com/Joulenap/joulenap/main/docker-compose.example.yml docker compose up -d # then open http://<host-ip>:8080
The example uses host networking and mounts one writable ./data directory. To pre-fill config, start it once so it seeds ./data/config.yaml, stop it, edit, and bring it back up.
For those who'd rather not use Docker — run Joulenap directly as a Python service. You need Python 3.12+, git, and Node.js 24 (once, to build the web UI — 24 is what CI and the container image build with).
# 1. get the source mkdir -p /opt/joulenap && cd /opt/joulenap git clone https://github.com/Joulenap/joulenap.git cd joulenap # 2. build the web UI cd frontend && npm ci && npm run build && cd .. # 3. install the backend (editable — resolves the packaged README) python3 -m venv .venv .venv/bin/pip install -e ./backend mkdir -p /opt/joulenap/data
Then run it under systemd so it starts on boot — a unit file, the full walkthrough, and the update steps are in the repo's install guide.
Full native + systemd instructions, plus updating each method, live in docs/INSTALL.md.
Once the UI is up at http://<host>:8080 — the same for every install path:
A one-time registration. The timezone dropdown is pre-filled from your browser, so usually you just leave it — it sets the timezone your backup schedule runs in.
Under Settings → Devices → + Add. One wizard adds a Proxmox VE host and discovers the backup servers behind it from its storage config; the other adds a backup server and sets up its Wake-on-LAN and power-off, including a test that sends a real magic packet. Both default to API-token mode (you paste scoped tokens; nothing leaves your server), and both can instead provision everything from a root login used once and never stored.
From the homepage: pick the source host(s) and the target backup server, a time and the days, which CTs/VMs to include, and the retention — that's what gets scheduled. Add more routes for more hosts, or a PBS → PBS sync for an off-site second copy. Use the route's Run now to test the full wake → backup → power-off cycle while you're watching. Backup mode, bandwidth limit and the guardrails live in the route's Advanced section; ports and session settings in Settings → Advanced, which also embeds a full config.yaml editor in the browser.
Your config.yaml and data live in the mounted data/ directory, so they carry over across updates.