ProxSave is a project created by enthusiasts, with the aim of simplifying recovery in critical moments.
Restoring a PVE or PBS server after a disaster (or even just a migration) is always a process that requires skill, time, and patience, ProxSave allows you to save your entire environment and restore it at any time, allowing you to prepare the new installation to accommodate your personal data with as few manual changes as possible.
ProxSave allows you to save and restore, integrating advanced features: automatic backups, multi-path saves, intelligent retention, encryption of backups, integrated Telegram and email notifications (cloud relay or Proxmox Notifications), and compatibility with webhooks, Gotify, and Prometheus.
For more information, take a look at our landing page at proxsave.dev.
bash -c "$(curl -fsSL https://raw.githubusercontent.com/tis24dev/proxsave/main/install.sh)"or: if you need a fully clean reinstall use: (preserves build/, env/, and identity/)
bash -c "$(curl -fsSL https://raw.githubusercontent.com/tis24dev/proxsave/main/install.sh)" _ --new-installYou can find the installation script source here.
The installer ends in the interactive setup, which writes your configs/backup.env. Everything after that is done from the dashboard: run proxsave on the host and it opens.
π The installer and proxsave --upgrade verify each release's signature before installing, for releases that publish SHA256SUMS.sig, so only authentic, untampered builds ever run (details).
Note
Please refer to the docs for more information about the installation.
proxsave, run with no arguments on a terminal, opens the interactive dashboard. This is the normal way to use ProxSave: backing up, restoring, editing the configuration, upgrading, running the diagnostic checks and managing the daemon are all reachable there, and every entry that has a matching command-line flag runs that flag's code. The three Diagnostic Checks entries and Daemon > Restart have no flag and exist only in the dashboard.
proxsave| Group | Entry | What it does |
|---|---|---|
| Backup | Backup |
starts a backup with the current configuration, streamed inside the dashboard |
| Tools | Restore |
restores a backup onto this system |
| Tools | Decrypt |
converts an encrypted backup into a plaintext bundle |
| Maintenance | New key |
creates a new AGE encryption key |
| Maintenance | Install |
Edit install re-runs the interactive setup (this is how you change the configuration); Wipe install resets the install directory first, keeping build/, env/ and identity/ |
| Maintenance | Upgrade |
Check upgrade updates the binary to a newer release, merging new template variables into backup.env as part of the same run; Check config runs that merge on its own |
| Diagnostic Checks | Telegram, Healthchecks, Post-install |
verify the Telegram relay pairing, show the monitoring portal details, re-run the post-install audit |
| Daemon | Install, Disable, Restart, Status |
switch the scheduler to the resident daemon or back to cron, restart it, show its state. The group is context aware: Install appears on a cron install, Disable and Restart when the daemon is the active scheduler, Status always |
| Recovery | Cleanup guards |
removes leftover restore mount guards |
| Recovery | Support |
runs a support backup and emails the debug log to the maintainer |
The dashboard opens only when proxsave is invoked completely bare (any flag, even --config, skips it) and stdin and stdout are both real terminals with TERM set to something other than dumb. Everything else, cron included, runs the backup directly, and a dashboard that is abandoned or that fails to render exits without doing anything instead of falling through into a backup.
Screen by screen: DASHBOARD.md.
The setup offers two scheduler engines and a fresh installation defaults to the resident daemon (proxsave-daemon.service): it runs the backup itself at SCHEDULER_TIME, supervises it under the MAX_RUN_DURATION hang watchdog, and reports liveness and outcome to healthchecks monitoring. Monitoring only transmits under the daemon, which is the sole pinger; choosing cron turns it off.
System cron is the legacy engine and stays fully supported: SCHEDULER_MODE=cron keeps the crontab entry instead. Once the variable is recorded in backup.env, an upgrade leaves the engine as it stands and never switches it.
Switch between the two from the dashboard's Daemon group, or with --daemon-setup / --daemon-remove on a headless host.
Details: DAEMON.md and HEALTHCHECKS.md.
From the dashboard: Upgrade > Check upgrade downloads and installs a newer release, and the backup.env merge is part of that run. Check config runs that merge on its own, for when the binary is already current.
Headless, the same upgrade is proxsave --upgrade (append y to auto-confirm).
An in-place proxsave --upgrade is started by the binary already installed, so the release check, the download, the signature and checksum verification and the install itself are all executed by the OLD code. From 0.36.0 on, the installed binary hands the post-install finalize (the configuration merge, the docs and symlink refresh, the daemon migration and restart) to the freshly installed release, so that half runs the new code; a binary older than that finalizes with its own code, and a fix shipped in the new release cannot help that upgrade.
To run the whole upgrade with the new code, fetch the installer instead:
bash -c "$(curl -fsSL https://raw.githubusercontent.com/tis24dev/proxsave/main/install.sh)" -- --upgradeIt downloads, verifies and installs the release itself, then calls the new binary with --upgrade --localfile to finalize.
The flags stay fully supported, for headless hosts, cron jobs, scripts and recovery when the dashboard cannot run. They are the automation route, not the everyday one.
| Flag | What it does |
|---|---|
--backup |
runs the backup now, skipping the dashboard. A non-interactive invocation does this anyway |
--restore |
runs the restore workflow (select bundle, optionally decrypt, apply to system) |
--decrypt |
converts encrypted bundles into plaintext bundles |
--newkey, --age-newkey |
resets the AGE recipients and runs the interactive key setup |
--support |
forces debug logging and emails the log to the maintainer. Available for a standard backup run and for --restore |
--install |
runs the interactive installer (generate or edit backup.env) |
--new-install |
resets the installation directory, preserving build/, env/ and identity/, then runs the installer |
--upgrade [y] |
downloads and installs the latest release, then upgrades backup.env. y auto-confirms |
--localfile |
with --upgrade: skip the release check and download and finalize against the binary already on disk |
--upgrade-config |
adds missing variables to backup.env from the embedded template, preserving existing and custom ones |
--upgrade-config-dry-run |
plans that merge without writing, reporting missing and custom variables |
--daemon |
runs as the resident daemon. This is what proxsave-daemon.service starts |
--daemon-setup |
switches this install to daemon mode: installs and enables the service, removes the cron entry |
--daemon-remove |
reverts to cron and prevents future upgrades from reinstalling the daemon |
--daemon-status |
prints scheduler mode, service state, running version and binary alignment |
--cleanup-guards |
removes leftover guard bind mounts and directories. Combine with --dry-run to preview |
--show-whatsnew |
shows the release notes screen once and exits |
-c, --config <path> |
configuration file to use (default configs/backup.env under the install directory) |
-l, --log-level <level> |
debug, info, warning, error or critical |
-n, --dry-run |
runs without making actual changes |
--cli |
uses plain CLI prompts instead of the TUI, for --install, --new-install, --newkey, --decrypt and --restore |
-v, --version |
shows version and build information |
-h, --help |
shows the help message |
A few more flags exist (--upgrade-config-json, --upgrade-finalize and its companions) purely as internal plumbing for --upgrade; they are not meant to be run by hand.
Full reference: CLI_REFERENCE.md.
You can find the guide files for the various functions here.
Every report or issue is important to us. There are various channels you can use to report a problem.
The fastest report is the dashboard's Support entry, under Recovery: it runs a backup with debug logging and emails that log to the maintainer. On a headless host, proxsave --support does the same.
It is important that you provide as much information as possible with each report. You will often find these details listed. They are important, so please do not forget to include them:
example
===========================================
Version: 0.11.2
Build Signature: 60d0d998f* (2025-12-02T14:46:14+01:00) hash=eeb72ef6b8b6ad89
===========================================Every run prints that block in its header. The dashboard shows the version in its own header and the build signature in its footer; proxsave --version prints the version with the build commit and date.
To stay completely free and open-source, with no feature behind the paywall and evolve the project, we need your help. If you like ProxSave, please consider donating to help us fund the project's future development.
Thank you so much!
A special thanks to the community members who help by testing releases and reporting issues. π
@NukeThemTillTheyGlow release testing |
@marc6901 release testing |