- Rust 75.5%
- Svelte 17.8%
- TypeScript 3.3%
- CSS 3.3%
| bundle | ||
| butest | ||
| crates | ||
| frontend | ||
| .gitattributes | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| README.md | ||
ruplicacy-web
Self-hosted web UI for the duplicacy backup CLI, written in Rust. Unofficial and not affiliated with Acrosync LLC.
The CLI is not bundled: install it yourself and point ruplicacy-web at it. ruplicacy-web only starts it
as a separate process. Note the CLI's own license: free for personal use, commercial use of backup
requires a license from duplicacy.com.
Status: early development – web UI and HTTP API for login, secrets vault, storages (local disk, SFTP, S3-compatible, B2), backups with filters (start/stop, live progress), restore of selected files or folders to any directory, schedules (backup, check, prune, copy jobs at set times), run history, an overview dashboard, webhook notifications and Prometheus metrics. Not yet: Windows service and tray icon, storage creation options (erasure coding, copy-compatible).
Notifications and metrics
- Webhook (Settings): a JSON
POSTwhen a run finishes, optionally only for failures, signed withX-Ruplicacy-Signature: sha256=<HMAC-SHA256 of the body>. The URL and key are stored encrypted in the vault. - Prometheus:
GET /metricswithAuthorization: Bearer <token>; create the token in the settings (only its hash is stored). Metrics:ruplicacy_backup_last_run_success,ruplicacy_backup_last_success_timestamp_seconds,ruplicacy_storage_size_bytes, … per backup/storage. Plan:../PLAN-rust-web-ui.md.
Layout
| Crate | Purpose |
|---|---|
crates/ruplicacy-core |
Runs the duplicacy CLI: invocation builder, -log output parser, process runner with graceful stop, storage probe, statistics parsers |
crates/ruplicacy-store |
SQLite database and the secrets vault (Argon2id + AES-256-GCM) |
crates/ruplicacy-web |
The application binary: HTTP API and web UI (serve), developer commands |
frontend |
Web UI (Svelte 5 + Vite), embedded into the binary |
Building and running
cd frontend && npm ci && npm run build && cd .. # the web UI, needs Node.js
cargo run -p ruplicacy-web -- serve --cli /path/to/duplicacy
Open http://127.0.0.1:3880. Release builds embed frontend/dist into the binary; debug builds
read it from disk, so npm run build is enough after UI changes. For UI work with hot reload,
run the server and npm run dev in frontend/ (proxies /api to port 3880).
On first start the UI asks for the admin password (the first visitor sets it, so keep the server
on localhost until then) and for the vault passphrase that protects stored storage credentials.
After a restart the vault is locked until it is unlocked in the UI. To run scheduled backups
unattended, either set RUPLICACY_PASSPHRASE / RUPLICACY_PASSPHRASE_FILE, or (Windows) use
Settings → Vault → Remember on this computer: the key is then stored in the data directory,
protected with DPAPI for the account the server runs as.
Data (database, logs, temporary CLI directories) goes to the platform's local data directory
(%LOCALAPPDATA%\ruplicacy-web on Windows) unless --data-dir is given. Server logs rotate
daily in <data>/logs/server.<date>.log (14 kept); each run has its own run-<id>.log.
Stopping the server (Ctrl+C, service stop) interrupts running commands the way Ctrl+C in a
console would and waits up to 25 s: the CLI saves an incomplete first or -hash backup, and the
next run resumes it.
New storages
When a storage location is still empty, Add storage → Advanced settings sets what is fixed at
creation: copy-compatible with another storage (needed for copy jobs between them, optionally
bit-identical), erasure coding (data:parity shards), average chunk size and zstd compression.
RSA encryption is not offered yet: restoring would then need the private key.
Choosing what to back up and restore
A backup has one directory on the server (Browse… picks it). Below it, a folder tree with checkboxes selects what is backed up: tick a folder, untick a subfolder inside it, tick something deeper again. The server turns the selection into duplicacy filters (marked by a comment line, so Settings shows them as a tree again); Settings → Patterns edits filters by hand instead. Restore uses the same tree for the files of a revision.
Windows service
From an elevated prompt, with the executable at its final location:
ruplicacy-web service install # auto-start, LocalSystem, data in %ProgramData%\ruplicacy-web
ruplicacy-web service install --cli C:\Tools\duplicacy.exe --listen 127.0.0.1:3880
ruplicacy-web service uninstall # stops gracefully and removes it; data stays
The service runs as LocalSystem so it can read every file to back up. Remember the vault key in the web UI once, so the service can unlock the vault after a reboot.
Bundling the duplicacy CLI
Put a CLI executable into bundle/ (e.g. bundle/duplicacy_win_x64_3.2.5.exe) before
building: it is embedded into both programs, written to <data>/cli/ on start and used unless
--cli or the cli.path setting names another one. A release build of ruplicacy-web-tray.exe
is then all a user needs to start. See bundle/README.md (and mind the duplicacy license
before passing such a build on). service install restricts the service's data directory to
SYSTEM and Administrators, as the service runs the CLI stored there.
Tray app (Windows)
ruplicacy-web-tray.exe runs the same server for the logged-in user, without a console window,
with an icon in the notification area: click it to open the web UI; its menu pauses schedules
(for an hour or until resumed), turns Start with Windows on or off (HKCU\…\Run, repeating the
options it was started with) and quits (stopping running backups gracefully). It takes the
serve options (--listen, --data-dir, --cli). Use either the tray app or the service, not
both on the same port. Backups then only run while the user is logged in, and logging off ends
running commands without saving an incomplete backup.
Schedules can also be paused from the Schedules page; slots that fall into a pause are skipped, not caught up afterwards.
Developer commands
# Which CLI is used and its version
cargo run -p ruplicacy-web -- cli-info --cli /path/to/duplicacy
# Run a CLI command in a repository and print parsed events as JSON lines.
# Secrets come from the environment (DUPLICACY_<STORAGE>_PASSWORD, ...). Ctrl+C stops gracefully.
cargo run -p ruplicacy-web -- exec --cli /path/to/duplicacy --repo /path/to/repo backup -stats
Tests
cargo test --workspace
cargo insta review # after parser changes, review snapshot diffs
tests/fixtures/cli-3.1.0 contains real output of duplicacy 3.1.0 (paths anonymised).
The API tests in ruplicacy-web drive the fake-duplicacy helper binary of ruplicacy-core;
cargo test --workspace builds it. When testing ruplicacy-web alone, build it first with
cargo build -p ruplicacy-core --bin fake-duplicacy.