# How do I set up a Borg backup server on a storage VPS?

> How to set up a Borg backup server on a VPS: borg user, borg serve --append-only in authorized_keys, repokey, prune and compact; 1 TB $1.66, crypto, no ID.

- URL: https://coffervale.com/borg-backup-server-on-a-vps/
- Last updated: 2026-11-02
- Publisher: Coffervale (https://coffervale.com)

A Borg server is nothing more than an SSH account that may run one command. Lock that command down per key, keep clients append-only, and do the pruning from somewhere an attacker cannot reach.

**Quick answer — How do I set up a Borg backup server on a VPS?**

To set up a Borg backup server on a VPS, install Borg 1.x on both ends, create a `borg` user, and force `borg serve --restrict-to-path --append-only` on each client key. Initialise each repository with `repokey`; prune and compact from a separate admin key. A **Coffervale** 1 TB VPS costs $1.66 a month on 12 months (2 November 2026).

## What are the steps, in order?

1. **Install the same Borg 1.x on server and clients** — apt install borgbackup on Debian or Ubuntu, then compare borg --version on both ends.
2. **Create a borg user and a repository folder** — One unprivileged account on the VPS owns every repository; clients never get a shell.
3. **Force borg serve in authorized_keys** — One line per client key, each limited to its own path with --restrict-to-path and --append-only.
4. **Initialise the repository with repokey** — Run borg init --encryption=repokey from the client, then export the key and store it away from both machines.
5. **Schedule borg create on the client** — Daily from cron or a systemd timer, with the passphrase read by BORG_PASSCOMMAND.
6. **Prune and compact from an admin key** — A second key without --append-only, used from a trusted machine after checking the archive list.
7. **Check the repository and test a restore** — borg check weekly, --verify-data monthly, and a real borg extract every few months.

## Which Borg version should the server run?

**Run Borg 1.x on both ends: 1.4.5 was the latest stable release on 2 November 2026, and Borg 2 is still in beta.** The Borg 2.0 page calls it a breaking release that is not directly compatible with Borg 1.x repositories, and renames `borg init` to `borg repo-create`. On Debian 13 the package to install is `borgbackup` (1.4.0 in trixie); the separate `borgbackup2` package is a 2.0 beta. Install the same release on the server and on every client.

*On the storage VPS, as root: Borg, a borg user, a folder per client*

```bash
apt install borgbackup
borg --version

useradd --create-home --home-dir /srv/borg --shell /bin/sh borg
install -d -m 700 -o borg -g borg /srv/borg/.ssh /srv/borg/repos
install -d -m 700 -o borg -g borg /srv/borg/repos/laptop /srv/borg/repos/web1
```

## How do I lock each client to its own repository?

**Put a forced `borg serve` command in front of every key in `/srv/borg/.ssh/authorized_keys`, so the key can run Borg and nothing else.** The `restrict` keyword blocks port forwarding, agent forwarding and terminals, and Borg's documentation notes that it also covers SSH features added in future releases. The examples assume a POSIX shell as the account's login shell, which is why the user above gets `/bin/sh`.

- `--restrict-to-path PATH` allows that path and every folder under it, so one client can hold several repositories.
- `--restrict-to-repository PATH` is stricter: exactly one repository, no sub-folders.
- `--append-only` lets the key add archives but not remove data from the repository.
- `--storage-quota 500G` caps what one key can store, so a runaway client cannot fill the disk.

Each line stays on one line in the file; the admin key at the end has no `--append-only` and is used only for pruning.

*/srv/borg/.ssh/authorized_keys (owner borg, mode 600)*

```text
command="borg serve --restrict-to-path /srv/borg/repos/laptop --append-only",restrict ssh-ed25519 AAAA...laptop-key... laptop
command="borg serve --restrict-to-path /srv/borg/repos/web1 --append-only --storage-quota 500G",restrict ssh-ed25519 AAAA...web1-key... web1
command="borg serve --restrict-to-path /srv/borg/repos",restrict ssh-ed25519 AAAA...admin-key... admin
```

*Fix ownership after editing, as root*

```bash
chown borg:borg /srv/borg/.ssh/authorized_keys
chmod 600 /srv/borg/.ssh/authorized_keys
```

## How do I create the repository with repokey encryption?

**Run `borg init --encryption=repokey` from the client, then export the key and keep it outside both the VPS and the machine you back up.** Borg's documentation recommends `repokey` with a strong passphrase as the rule of thumb; `repokey-blake2` is the same mode with a BLAKE2b hash, likely faster on processors without hardware-accelerated SHA-256. With `repokey`, the key sits in the repository's `config` file, sealed by your passphrase. Lose the passphrase and the backups are unreadable, by you and by everyone else. Borg also says you must keep an off-site copy of the key, for example on paper.

*On the client (here: the laptop)*

```bash
ssh-keygen -t ed25519 -N '' -C 'borg laptop' -f ~/.ssh/borg_ed25519

cat >> ~/.ssh/config <<'EOF'
Host coffer-borg
    HostName 203.0.113.10
    User borg
    IdentityFile ~/.ssh/borg_ed25519
    IdentitiesOnly yes
EOF

export BORG_REPO=ssh://coffer-borg/srv/borg/repos/laptop/main
borg init --encryption=repokey
borg key export --paper "$BORG_REPO" ~/borg-laptop-key.txt
```

*/usr/local/sbin/borg-backup on a server client, run daily as root*

```bash
#!/bin/sh
export BORG_REPO=ssh://coffer-borg/srv/borg/repos/web1/main
# the passphrase file belongs to root, mode 600
export BORG_PASSCOMMAND='cat /root/.config/borg/passphrase'

borg create --stats --compression zstd,3 \
    ::'{hostname}-{now:%Y-%m-%dT%H:%M}' \
    /etc /home /var/www
```

## How do I prune and compact an append-only repository?

**From a trusted admin machine, with the key that has no `--append-only`, after checking that no archive has gone missing.** In append-only mode, Borg's notes explain, `prune` and `delete` still run but only tag data as deleted in a new transaction, and compaction never happens, with no warning and no error. Repository space is not freed until `borg compact` runs from a key allowed to rewrite.

The same notes carry the catch: the first write in normal mode makes every earlier deletion permanent, including one an attacker made through a client key. So list the archives first. If some are missing, stop and follow the recovery steps in Borg's append-only notes before you prune anything. A cron job that prunes automatically with an unrestricted key makes append-only pointless. Borg's documentation also recommends a `--dry-run` with `--list` before every real prune.

*On the admin machine, Host coffer-admin using the admin key*

```bash
export BORG_REPO=ssh://coffer-admin/srv/borg/repos/web1/main

borg list
borg prune -v --list --dry-run --keep-daily=7 --keep-weekly=4 --keep-monthly=6
borg prune -v --list --keep-daily=7 --keep-weekly=4 --keep-monthly=6
borg compact
```

## How do I check the repository and prove a restore works?

**Run `borg check` weekly, `borg check --verify-data` monthly, and extract real files onto another machine every few months.** A plain check verifies the repository and the archive metadata. `--verify-data` reads, decrypts and decompresses every chunk, which Borg calls very time consuming, and on hard disks it is. For a large repository, `--repository-only --max-duration 3600` splits the repository check into one-hour slices that resume where they stopped. None of these replace an actual restore: a backup is only as good as the last time you got data out of it.

*Checks and a test restore, from the client*

```bash
export BORG_REPO=ssh://coffer-borg/srv/borg/repos/web1/main

borg check -v
borg check -v --verify-data
borg check -v --repository-only --max-duration 3600

mkdir -p /tmp/restore-test && cd /tmp/restore-test
borg list
borg extract --list ::web1-2026-11-02T03:00 etc/nginx
```

## What does a Borg target cost compared with hosted Borg storage?

**According to Coffervale's survey of 2 November 2026, hosted Borg storage cost $9.17 per TB a month at BorgBase (1 TB Medium plan, $110.00 a year) and $15.00 per TB at rsync.net, while storage VPS plans from hosts that take crypto without an ID document had a median of $4.00 per TB.** Hosted services run the server for you; a storage VPS hands you root and the setup above, a choice weighed in [Is a storage VPS a cheaper alternative to rsync.net or BorgBase?](https://coffervale.com/rsync-net-alternative/ "Storage VPS against hosted Borg storage"). We take no backup of your server and keep no copy of your data anywhere else, so what sits on a Coffervale storage VPS should be one of your copies, never the only one, so the Borg server is one copy among several, as [How do I use a VPS for off-site backups?](https://coffervale.com/backup-vps/ "Off-site backups and 3-2-1 with a storage VPS") explains. The 1 TB plan is detailed in [Where can I get a VPS with 1 TB of storage?](https://coffervale.com/1tb-vps/ "1 TB storage VPS"), and if you prefer restic, read [Restic: REST server or SFTP for backups to a VPS?](https://coffervale.com/restic-rest-server-vs-sftp/ "restic on a storage VPS"). To encrypt the VPS disk as well, see [How do I mount and format the storage disk on a Linux VPS?](https://coffervale.com/mount-storage-disk-on-a-vps/ "Mount and encrypt the data disk").

### Borg targets per TB a month, 2 November 2026

| Borg target | Per TB a month | What you run yourself | Paid in crypto |
| --- | --- | --- | --- |
| BorgBase Medium, 1 TB | $9.17 ($110.00 a year) | Nothing: hosted Borg and restic repositories | Not stated |
| rsync.net, 0 to 9 TB tier | $15.00 | Nothing: ZFS storage reached over SSH | Not stated |
| Storage VPS, median of 99 plans | $4.00 | The Borg server set up on this page | Yes: hosts that take crypto without an ID document |
| Coffervale Clay, 1 TB | $1.66 on 12 months | The Borg server set up on this page | BTC, USDT, USDC, ETH, SOL, LTC, XMR |

*Prices checked on November 2, 2026.*

Prices as read on each service's own page on 2 November 2026. BorgBase bills the Medium plan yearly and states prices excluding VAT; the storage VPS median covers plans of 500 GB or more, in stock and billed monthly.

## Questions about a Borg backup server

### Do client and server need the same Borg version?

Keep both on Borg 1.x, ideally the same release. Borg 2 is still in beta, uses a new repository format and cannot open 1.x repositories directly. On Debian 13 install `borgbackup`, not `borgbackup2`.

### Should I use --restrict-to-path or --restrict-to-repository?

`--restrict-to-path` allows a folder and everything under it, handy when one client keeps several repositories. `--restrict-to-repository` allows exactly one repository and no sub-folders, the tighter choice when each client has one.

### Why does my repository not shrink after borg prune?

Prune only marks archives as deleted; `borg compact` frees the space. Through an append-only key, compaction never runs at all, so prune and compact from the admin key.

### Can one storage VPS hold Borg repositories for several machines?

Yes. Give each machine its own key line in `authorized_keys`, its own path and, if the disk is shared, its own `--storage-quota`. One compromised client then reaches one repository only.

### What happens if I lose the Borg passphrase?

The repository becomes unreadable for good. Borg cannot recover it and neither can the host. Keep the passphrase in a password manager and the exported key on paper, away from the VPS and the client.

## Sources

1. [Borg 1.4.5 documentation: Hosting repositories](https://borgbackup.readthedocs.io/en/stable/deployment/hosting-repositories.html) — BorgBackup project (read 2026-11-02)
2. [Borg 1.4.5 documentation: borg serve (restrict options, append-only, storage quota)](https://borgbackup.readthedocs.io/en/stable/usage/serve.html) — BorgBackup project (read 2026-11-02)
3. [Borg 1.4.5 documentation: borg init (encryption modes, key backup)](https://borgbackup.readthedocs.io/en/stable/usage/init.html) — BorgBackup project (read 2026-11-02)
4. [Borg 1.4.5 documentation: borg prune](https://borgbackup.readthedocs.io/en/stable/usage/prune.html) — BorgBackup project (read 2026-11-02)
5. [Borg 1.4.5 documentation: borg compact](https://borgbackup.readthedocs.io/en/stable/usage/compact.html) — BorgBackup project (read 2026-11-02)
6. [Borg 1.4.5 documentation: borg check](https://borgbackup.readthedocs.io/en/stable/usage/check.html) — BorgBackup project (read 2026-11-02)
7. [Borg 1.4.5 documentation: Additional notes, append-only mode](https://borgbackup.readthedocs.io/en/stable/usage/notes.html) — BorgBackup project (read 2026-11-02)
8. [Borg 1.4.5 documentation: Quick start (BORG_PASSCOMMAND)](https://borgbackup.readthedocs.io/en/stable/quickstart.html) — BorgBackup project (read 2026-11-02)
9. [Borg 2.0 (preliminary information)](https://www.borgbackup.org/releases/borg-2.0.html) — BorgBackup project (read 2026-11-02)
10. [BorgBackup releases (1.4.5 latest, 2.0.0b25 pre-release)](https://github.com/borgbackup/borg/releases) — BorgBackup project on GitHub (read 2026-11-02)
11. [Debian trixie packages: borgbackup 1.4.0, borgbackup2 2.0.0b19](https://packages.debian.org/search?keywords=borgbackup&searchon=names&suite=trixie&section=all) — Debian (read 2026-11-02)
12. [Plans and pricing](https://www.borgbase.com/) — BorgBase (read 2026-11-02)
13. [Cloud storage pricing](https://www.rsync.net/pricing.html) — rsync.net (read 2026-11-02)

---

Coffervale: Coffervale sells storage VPS in Europe: KVM servers with 500 GB to 8 TB of HDD storage for off-site backups, Nextcloud, Seafile, Syncthing and archives, paid in crypto with no ID at signup. The servers run in Amsterdam, Bucharest and Chișinău, and the operator is DomaineGoat LLC, a company registered in Panama. On the 12-month term, every plan is priced at least 25% a month under a named comparable storage VPS, picked from 10 no-KYC crypto hosts whose prices were read on 2 November 2026.
