Borg
The Borg destination writes host backups to a Borg repository. Three repository types are supported: local filesystem path, mounted external disk, or remote server via SSH. Chunk-level deduplication across all archives in the repository and optional repokey encryption.
What Borg is
Borg (also spelled BorgBackup) is an open-source deduplicating backup tool maintained by the Borg Backup community. It stores every archive as a set of variable-length chunks inside a repository; chunks are shared across archives so re-backing up unchanged data has near-zero storage cost. Borg is not tied to Proxmox — it is a general-purpose backup tool used across many environments. ProxMenux uses it as one of the three destinations for host backups; every Borg-specific mechanism described on this page (repository types, borg-serve over SSH, repokey encryption, prune) is standard Borg behaviour.
Chunk-based deduplication with local or SSH-served repositories
borg create against a repository at backup time and borg extract at restore time. The repository can live on the same filesystem as the source, on a mounted external disk, or on a remote host accessed over SSH.The borg binary
Borg is not a base dependency of the ProxMenux installer. When a backup runs, hb_ensure_borg resolves the binary from four sources in order and returns the first that works:
| # | Source | Detail |
|---|---|---|
| 1 | System borg | If the host already has borg installed via APT (which borg resolves), that binary is used. |
| 2 | State-dir cache | /usr/local/share/proxmenux/borg — kept from a prior GitHub download on this host. |
| 3 | Monitor AppImage bundle | /usr/local/share/proxmenux/monitor-app/usr/bin/borg — the AppImage bundles a signed borg-linux64. This is the offline-safe path: a host with no internet still has a working borg. |
| 4 | GitHub download | wget against the pinned borg-linux64 URL under github.com/borgbackup/borg/releases/, verified against a constant SHA-256 in lib_host_backup_common.sh (HB_BORG_LINUX64_SHA256). On checksum mismatch the binary is discarded and the backup aborts. The downloaded file is cached in the state dir so subsequent backups use path 2. |
Repository types
The repository type is chosen when a target is added. Each type resolves to a different repository URL that Borg understands.
| Type | Repository URL | Detail |
|---|---|---|
| remote | ssh://USER@HOST/RPATH | Repository lives on a remote server that runs borg serve. Requires an SSH connection to that server. |
| usb | /mnt/MOUNTPOINT/borgbackup | Repository lives on a mounted external disk (typically USB). The mount is resolved via hb_prompt_mounted_path, which detects, mounts or formats USB partitions as needed. |
| local | /backup/borgbackup (any absolute path) | Repository lives on a local directory. Meaningful only when the target directory is on a separate physical disk — a repository on the same disk as the source protects against operator error but not against disk failure. |
Preparing the Borg server (server side)
The remote repository type expects a working Borg server accessible over SSH. ProxMenux does not bootstrap the server itself — it only authorises a key against an existing account on it. This section documents what the server needs before ProxMenux can connect.
Where the server can live
Any Linux host with SSH access qualifies. Common setups:
- •A dedicated NAS or backup box (Debian, Ubuntu, TrueNAS SCALE with a shell).
- •An LXC container inside a Proxmox node. Small footprint, isolated from the host running the backups.
- •Another Proxmox host on the same LAN, or a VM anywhere reachable over SSH.
LXC as Borg server
Requirements on the server
| Requirement | Detail |
|---|---|
borg binary at /usr/bin/borg | The command="/usr/bin/borg serve ..." line ProxMenux writes into authorized_keys hard-codes that path. Installing via APT (apt install borgbackup) puts it there. A standalone binary must be symlinked to /usr/bin/borg. |
A dedicated user account (typically borg) | Owns the repository directory and receives incoming SSH connections. Does not need sudo or shell access — the authorized_keys line disables interactive shells anyway. |
| A writable repository directory | The path the operator gives ProxMenux (for example /backup/borgbackup) must exist on the server and be owned by the borg user. |
| SSH daemon accepting the borg user | PubkeyAuthentication yes (default). Password authentication is only needed for the one-shot generate-auto flow — after the key is installed, the server can disable password auth entirely. |
Minimal server setup
On a Debian or Ubuntu Borg server, a working baseline is four commands as root:
apt install borgbackup
useradd -m -d /home/borg -s /bin/bash borg
mkdir -p /backup/borgbackup
chown borg:borg /backup/borgbackupAfter this, ProxMenux's generate-auto mode can connect using the borg user's password once, install its own SSH key, and every subsequent backup uses that key. No further server-side configuration is needed — the key restricts itself to borg serve on that path.
SSH authentication (client side)
Remote Borg repositories are accessed over SSH. The connection runs from the ProxMenux host to a user account on the Borg server that runs borg serve. This user is typically named borg, NOT the admin/root user of the server — the borg-serve command line locks the connection to that specific repository path (see the key strategies below).
The four key strategies
When a remote target is added, ProxMenux prompts for the SSH user, host and remote path, then asks how to authenticate. Four modes:
| Mode | Best for | What it does |
|---|---|---|
| generate-auto | Recommended | ProxMenux generates a new ed25519 keypair at ~/.ssh/borg_proxmenux_HOST_ed25519, then uses sshpass to log in ONCE to the server with the admin password and append the public key to ~borg/.ssh/authorized_keys. The admin password is only used for this one call — it is never stored. |
| generate-manual | No admin password on this host | ProxMenux generates the keypair as above but displays the full authorized_keys line for the operator to paste manually into the server. The admin password never leaves the ProxMenux host because it is never asked for. |
| generate-pct | Borg server is a PVE LXC | The Borg server runs inside an LXC on a PVE node. ProxMenux authorises the key via pct exec from the PVE host — root on the PVE host writes into the LXC's ~borg/.ssh/authorized_keys without needing SSH into the LXC itself. |
| existing | Use an existing key | ProxMenux scans /root/.ssh/ and $HOME/.ssh/ for parseable ed25519/RSA private keys and lists them. The operator picks one or browses manually to a non-standard path. |
| none | Default SSH config | No custom key — Borg relies on the host's default SSH configuration (typically ~/.ssh/id_rsa or an SSH agent). |
The authorized_keys line
For every generated key, the authorized_keys line ProxMenux writes on the server locks the key to a single borg-serve invocation against the configured repository path:
command="/usr/bin/borg serve --restrict-to-path RPATH",restrict PUBKEYThe command= forces every SSH session using this key to run only that borg-serve command; restrict disables port forwarding, agent forwarding, X11 forwarding and PTY allocation. The key cannot be used to open an interactive shell on the server or to access any other repository path, even if the account has broader privileges.
Saved targets
A saved target persists the repository configuration under a friendly name so the details do not have to be re-entered. Storage layout in the ProxMenux state directory:
| File | Content |
|---|---|
| borg-targets.txt | One line per target: NAME|REPO|SSH_KEY_PATH|ENCRYPT_MODE. Read by hb_collect_borg_configs to populate the target-selection menu. |
| borg-pass-NAME.txt | Passphrase for the target NAMEd above (chmod 600). Only present when the operator chose repokey encryption. |
Saving is optional — the operator can decline the save prompt for a one-shot backup that leaves no credentials on the host.
Encryption
Repositories are initialised with an encryption mode via hb_borg_init_if_needed: the modern borg repo-create -e MODE when available, or the legacy borg init --encryption=MODE. ProxMenux exposes two modes: repokey (default) and none. In repokey mode Borg stores the encryption key inside the repository itself; access requires a passphrase, which ProxMenux prompts for twice with match validation and stores at borg-pass-NAME.txt. A mandatory acknowledgement dialog is shown after the passphrase is saved: the passphrase is the only way to access the encrypted archives, and losing it makes every archive in the repository unrecoverable.
Runtime environment
ProxMenux exports the following environment variables before invoking borg. They configure the connection and unlock the repository without embedding secrets in the command line.
| Variable | Value | Purpose |
|---|---|---|
| BORG_RSH | ssh -i SSH_KEY_PATH -o StrictHostKeyChecking=accept-new | The remote-shell command Borg uses for SSH-served repositories. Set only when a custom key was selected; otherwise unset so Borg uses the default SSH configuration. |
| BORG_PASSPHRASE | (passphrase from borg-pass-NAME.txt) | Unlocks the repokey. Set only when the target uses repokey encryption. Never appears in the process argument list. |
| BORG_ENCRYPT_MODE | repokey | none | Used by hb_borg_init_if_needed when initialising a repository that does not yet exist. Ignored by borg create on existing repositories. |
| BORG_RELOCATED_REPO_ACCESS_IS_OK | yes | Suppresses the interactive prompt Borg raises when the repository URL differs from the URL it was originally reached from (common after a mount-point rename or SSH-host reachable via new address). |
| BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK | yes | Suppresses the interactive prompt Borg raises the first time an unencrypted repository is accessed from a new client. |
Archive naming and retention
Every backup creates a new archive inside the repository.
hostcfg-HOSTNAME-YYYYMMDD_HHMMSSFor scheduled jobs, run_scheduled_backup.sh runs borg prune against the repository after each successful backup with the retention values configured on the job (--keep-last, --keep-daily, --keep-weekly). Interactive backups do not prune.
Retrieval on the restore side
The restore flow lists archives with borg list REPO and extracts the selected one with borg extract REPO::ARCHIVE-NAME into a staging directory that _rs_check_layout feeds to the standard restore pipeline. For manual retrieval outside ProxMenux the same commands work; the extracted tree is the standard three-payload layout described in How it works.
References
Official Borg documentation for the components ProxMenux relies on.
- Borg documentation — main entry point covering concepts, deployment, quickstart and every command.
- borg create — the command ProxMenux invokes on every backup, with all supported flags.
- Repository encryption — the encryption modes Borg supports, including repokey which ProxMenux uses by default.
- borg serve and SSH deployment — how to set up a central Borg server accessed over SSH, including the borg-serve command and the restrict-to-path flag ProxMenux writes into authorized_keys.
- borg prune — the retention model behind --keep-last / --keep-daily / --keep-weekly that ProxMenux applies per scheduled job.