# PVE Cloud Backup Self-hosted Proxmox VE backup manager for uploads to an existing rclone remote such as OneDrive. The application is intentionally small: - FastAPI backend and worker - Vue 3 + TypeScript + Tailwind frontend, compiled once into `static/` - SQLite for all runtime configuration and state - `pvesh` for Proxmox API access - `rclone copyto`, `rclone lsjson`, and `rclone deletefile` for exact remote objects - systemd services, no Docker ## Layout All application files live under: ```text /opt/pve-cloud-backup/ backend/ frontend/ static/ data/ app.db logs/ scripts/ ``` The install script copies the two systemd service files to `/etc/systemd/system/`. ## Prerequisites Install these on the Proxmox host: - Python 3 with `venv` - Node.js and npm for the one-time frontend build - `rclone` - a preconfigured rclone remote, for example OneDrive or a crypt remote backed by OneDrive - working `pvesh` access as the service user The app does not configure rclone. If no remote exists, setup fails until you configure rclone yourself. ## Install From the installation directory: ```bash cd /opt/pve-cloud-backup ./scripts/install.sh ``` The installer: 1. creates required subdirectories, 2. creates a Python virtual environment, 3. installs Python dependencies, 4. builds the Vue frontend into `/opt/pve-cloud-backup/static`, 5. initializes SQLite migrations, 6. installs and starts systemd services. Open: ```text http://:8080 ``` ## Setup On first launch, complete the setup wizard: - Proxmox node - Proxmox backup storage - local backup directory - rclone executable path - rclone remote name - remote backup path/folder within that remote - Discord webhook URL - allowed CORS origins - default compression - default backup mode - default retention policy - max concurrent backups All settings are stored in SQLite at `/opt/pve-cloud-backup/data/app.db`. ## Recovery behavior On worker startup, unfinished records in these states are reconciled: - `pve_running` - `local_ready` - `uploading` - `remote_ready` - `local_deleting` - `deleting` The worker does not delete unknown local files or remote objects. Local archives are deleted only after upload finishes and the remote object is verified. ## Retention cleanup Retention cleanup runs in two places: - immediately after a backup completes for that job; - periodically from the worker service, once per hour, so changed rules and day-based expiry are enforced even if no new backup runs. Remote deletion uses exact-object `rclone deletefile` calls for backup records already known in SQLite. ## Testing Run backend tests: ```bash cd /opt/pve-cloud-backup/backend ./.venv/bin/pytest ``` Run frontend type check and build: ```bash cd /opt/pve-cloud-backup/frontend npm run build ``` Manual integration test for the provided Proxmox test target: ```bash API_URL=http://127.0.0.1:8080 /opt/pve-cloud-backup/scripts/integration-test-adguard.sh ``` This queues a backup for guest `adguard` / VMID `110` using storage `hitachi` and dump path `/mnt/pve/hitachi/dump`. Expected archive size is approximately 250 MB. The script is explicitly for manual integration testing and does not hardcode these values into normal app behavior. ## Uninstall ```bash /opt/pve-cloud-backup/scripts/uninstall.sh ``` The uninstall script removes and disables systemd services. It leaves `/opt/pve-cloud-backup` intact so `app.db`, logs, and any remaining data are not destroyed accidentally.