← Back to Wiki
Proxmox / Backups

Set Up Proxmox Backup Server with NFS Storage on a NAS

Proxmox Backup Server (PBS) gives your Proxmox VE fleet real deduplicated, incremental backups. The NFS storage setup has a permissions gotcha that trips up almost everyone the first time.

Share on X

The setup

PBS runs happily as its own VM. Point it at NFS-backed storage from a NAS for the actual backup datastore:

mkdir -p /mnt/pbs-backups
mount -t nfs <nas-ip>:/volume1/pbs-backups /mnt/pbs-backups
echo "<nas-ip>:/volume1/pbs-backups /mnt/pbs-backups nfs defaults,_netdev,vers=4.1 0 0" >> /etc/fstab
BE WARNED: PBS refuses to initialize a datastore in a non-empty directory. Many NAS vendors create a hidden recycle-bin folder at the share root. Point the datastore at a clean subdirectory instead of the share root:
mkdir -p /mnt/pbs-backups/datastore

The NFS permission gotcha (the one that gets everyone)

BE WARNED: PBS writes to the datastore as root to build its internal structure. Most NAS NFS export rules default to "root squash", which maps the remote root user down to an unprivileged account. That silently blocks exactly this. Set the NFS permission rule for PBS's IP explicitly to Read/Write, squash: No mapping. Even with that rule right, the first backup run can still fail with a permission error if the directory permissions on the share are restrictive. Fix those on the NAS itself, not through the NFS client:
ssh <nas>
sudo chmod -R 777 /volume1/pbs-backups

Connecting PBS to your hypervisor

This needs a token/ACL setup on both sides:

  1. On PBS: create an API token (Configuration → Access Control → API Tokens) and grant it the datastore admin role:
    proxmox-backup-manager acl update /datastore/<name> DatastoreAdmin --auth-id 'root@pam!<token-name>'
  2. On your hypervisor: add PBS as a storage target, using the user@realm!tokenname format for the username field and the token secret (not the token name) as the password.
If storage registration fails with 401 Unauthorized, check the username field includes the !tokenname suffix. If it then fails with "cannot find datastore", run proxmox-backup-manager acl list on PBS. A token can authenticate successfully while holding zero permissions on anything, and that produces exactly this error.
Proxmox VE Add Storage dialog for a Proxmox Backup Server target, with ID, Server, Username, Password, and Datastore fields
Proxmox VE → Datacenter → Storage → Add → Proxmox Backup Server. The Username field takes the full user@realm!tokenname format described above.

Backup job configuration

A reasonable starting retention policy is keep-last 3, keep-daily 7, keep-weekly 4, keep-monthly 2, keep-yearly 1. Many backup jobs use an explicit VM or container ID list, not "all". Every new guest has to be added to the job by hand. That is easy to forget while spinning up new infrastructure. Audit the list periodically to catch anything that slipped through.

Proxmox backup job edit dialog showing schedule, storage target, and an explicit checklist of VM/container IDs included in the job
Proxmox VE → Datacenter → Backup → Edit job. The VM and container selection is an explicit checklist, not an "all guests" toggle. Anything unchecked here silently gets no backup.

Sizing your NAS storage realistically

Don't trust df on a shared NFS mount to estimate datastore size. df reports usage for the entire underlying volume, which may be shared by many unrelated exports on the same NAS. Run du -sh on the exported path instead. The difference can be enormous. In one real case df showed 23TB and the datastore was 185GB.

Migrating the datastore to new storage later

To move the backing storage to a different NAS, the safe sequence is short. Mount the new share alongside the old one. rsync the datastore across. Verify file counts and sizes match on both sides. Then cut over. Stop the PBS services before the cutover. The daemon holds a lock file open on the datastore, so unmounting fails with "device busy" while it runs. Update the mount config to point at the new location, remount at the same path, and restart the services. If the datastore name and mount path do not change, nothing on the hypervisor side needs updating. It only talks to PBS's API, never the NAS directly.

BE WARNED: if a migration script puts a command that can fail, like an unmount, in the same set -e block as a config-file edit, a failure in the first one skips the edit entirely. The script just exits. Do not rely on strict-mode ordering when you chain a command that might fail with one that must run regardless. Check exit codes explicitly instead.

Don't forget to actually retire the old copy

It is tempting to leave the old storage location as a permanent safety net after a migration. "Temporary rollback copy" has a way of quietly becoming permanent clutter. Wait until the new storage has a real track record. Several days of successful backups and verification and garbage-collection jobs, not just a cutover that did not immediately explode. Then retire the old copy on purpose:

BE WARNED: a "dedicated direct link" network is often unreachable from anywhere except the two ends of that link. A 10G point-to-point connection between your hypervisor and NAS, for example. Reach for it from a third machine, like your workstation, and it times out. That looks like a transient network hiccup. It is the design working. If a host has two addresses, a fast dedicated link and a normal LAN address, use the LAN address for anything that is not the hypervisor itself.

Backing up a physical Windows PC (not just VMs)

PBS is not limited to VMs and containers. A real, physical Windows machine can back up to the same datastore. Here is the catch. Proxmox ships no official Windows client. The real option is a third-party, alpha-quality community reimplementation of the backup protocol. It comes as two small executables, one for folder-level backups and one for whole-disk image backups. Both are unsigned, so expect Windows Defender to flag or slow them down. Treat "alpha quality" as a literal warning, not a disclaimer.

BE WARNED: a PowerShell script launched by double-clicking closes itself the instant the process exits or crashes. It takes any error output with it. A folder-level backup run crashed silently partway through and looked like a normal, boring exit. Only checking the datastore afterward revealed it, in the form of a corrupted, incomplete snapshot. Two fixes. Launch from an already-open terminal instead of double-clicking. And have the script pause for input at the very end, on success or failure, so a double-click launch cannot hide a crash behind a closing window.

Where "don't lose a single file" matters more than "back up efficiently", take the full-disk image. It captures the whole drive via a live snapshot, and it is the safer default over picking specific folders. It does not depend on you remembering every folder that matters, and it survives the folder-level tool's rougher edges.

The permission bug that looks exactly like a config error

BE WARNED: an API token's real permissions can be the *intersection* of two separate grants, not just its own. Some backup and virtualization platforms let you grant a role directly to a token and separately to its parent user account. The token's effective access is whatever both of them agree on. Grant a role only to the token, while its parent user has none, and you get a token that authenticates fine and can do nothing. Every request gets rejected. A "list this token's granted roles" check looks completely correct the whole time, because it shows what was granted, not what is effective. If a freshly permissioned token still gets rejected and the ACL looks right, check whether the platform has this two-sided model before you blame the credential. Grant the same role to both the token and its parent account.

Scaling this to a whole household

Once more than one physical machine needs this, a few small pieces of infrastructure make it repeatable instead of a manual one-off every time: