Install

Get Joulenap running

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.

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.

Option A — Proxmox LXC + Docker

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.

  1. Create the LXC

    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.

  2. Enable nesting

    Select the container → Options → Features → nesting, then start it. (Docker needs this inside an LXC.)

  3. Open a shell & install Docker

    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).

  4. Run Joulenap

    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.

  5. Open the UI

    Browse to http://<container-ip>:8080 and continue at First run.

Option B — Docker Compose

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.

Option C — Native install, no Docker

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.

First run

Once the UI is up at http://<host>:8080 — the same for every install path:

  1. Create the admin account & confirm your timezone

    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.

  2. Add your devices

    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.

  3. Create a route

    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.