Advice on using Restic with VM backups

Tonight I restored the 50GB PBS datastore via Restic from Borgbase (cloud), I was able successfully run a PBS verification on a VM and then restore in PVE after adding the restored datastore.

VM started up straight away with zero issues.

Code:
sudo resticprofile restore latest --target /tank/restic-restore/ --include /tank/pbs
2025/05/23 19:17:32 using configuration file: /etc/resticprofile/profiles.yaml
2025/05/23 19:17:32 profile 'default': initializing repository (if not existing)
2025/05/23 19:17:33 profile 'default': starting 'restore'
repository 5abbb250 opened (version 2, compression level auto)
[0:00] 100.00%  49 / 49 index files loaded
restoring snapshot 446e16a3 of [/home /root /etc /tank/pbs] at 2025-05-23 18:25:09.850230369 +1000 AEST by root@datto01.sapling to /tank/restic-restore/
Summary: Restored 88196 / 88195 files/dirs (49.257 GiB / 49.257 GiB) in 3:17:43
2025/05/23 22:35:22 profile 'default': finished 'restore'

Restored PBS datastore and added to PBS alongside the actual / real datastore and ran a ‘verify’ on the coredns01 VM. Restored the coredns01 and successfully started:

Screenshot 2025-05-23 at 23.00.20.png


Screenshot 2025-05-23 at 22.51.24.png



Screenshot 2025-05-23 at 22.52.39.png

I will continue to stick with this method of datastore backup with Restic / resticprofile as it is proven to work for me and provides an incredible easy / fast method of daily backup and simple restore. All for $6/month for 1TB of storage.
 
Last edited:
Just to close this one off from my POV. I am running Restic backups via the resticprofile wrapper tool deployed locally on the PBS instance. I use the schedule feature built in to resticprofile that handles the systemd service/timer for daily backups/forgets/prunes.

I run a stop-proxmox-backup.sh script before a backup that shuts down PBS if it's not in 'running' state, this ensures a clean backup of the datastore:

Bash:
#!/bin/bash

# Configurable parameters
MAX_ATTEMPTS=12         # Total number of checks before giving up
SLEEP_SECONDS=300       # Wait time between checks in seconds

# Function to check if any tasks are running
has_running_tasks() {
    proxmox-backup-manager task list | grep -q "│ running │"
}

attempt=1
while [ $attempt -le $MAX_ATTEMPTS ]; do
    echo "Attempt $attempt of $MAX_ATTEMPTS: Checking for running tasks..."

    if has_running_tasks; then
        echo "Active tasks detected. Waiting $SLEEP_SECONDS seconds before retrying..."
        sleep $SLEEP_SECONDS
        ((attempt++))
    else
        echo "No running tasks detected. Stopping proxmox-backup service..."
        systemctl stop proxmox-backup.service
        sleep 30
        exit 0
    fi
done

echo "Failed to stop service: Tasks are still running after $MAX_ATTEMPTS attempts."
exit 1


This is called from my resticprofile config file, /etc/resticprofile/profiles.yaml:


Code:
version: "1"

global:
  # ionice is available on Linux only
  # ionice: false
  # ionice-class: 2
  # ionice-level: 6
  # priority is using priority class on windows, and "nice" on unixes
  priority: "low"
  # run 'snapshots' when no command is specified when invoking resticprofile
  default-command: "snapshots"
  # initialize a repository if none exist at location
  initialize: true
  # resticprofile won't start a profile if there's less than 100MB of RAM available
  min-memory: 100
  scheduler: "systemd"
  #log: '{{ tempFile "backup.log" }}'

default:
  repository: "rest:https://user:password@xxx.repo.borgbase.com"
  password-file: "/etc/resticprofile/xxx.key"
  lock: "/tmp/resticprofile.lock"
  run-before:
    - "mkdir -p /var/tmp/restic"
    - "chmod 750 /var/tmp/restic"

  env:
    TMPDIR: "/var/tmp/restic"
    GOGC: 20

  backup:
    run-before: "/usr/local/bin/stop-proxmox-backup.sh"
    run-after:
      - "systemctl start proxmox-backup"
    run-after-fail:
      - "systemctl start proxmox-backup"

    #run-after-fail: 'cp {{ tempFile "backup.log" }} /var/log/resticprofile-fail-{{ .Now.Format "2006-01-02T15-04-05" }}.log'
    #run-finally: 'cp {{ tempFile "backup.log" }} /var/log/resticprofile-{{ .Now.Format "2006-01-02T15-04-05" }}.log'

    send-after:
      URL: "https://hc-ping.com/xxx"
    send-after-fail:
      URL: "https://hc-ping.com/xxx/fail"

    host: "xxx"

    verbose: true
    source:
      - "/home"
      - "/root"
      - "/etc"
      - "/tank/pbs"

    exclude-caches: true
    exclude:
      - "/**/.git"
      - "/**/*.iso"
      - "/**/.cache/restic"
      - "/**/.cache"
      - "/**/#snapshot"
      - "/**/.vscode-server"
      - "/**/tmp"
    tag:
      - "resticprofile"

    schedule: "02:30"
    schedule-permission: "system"
    schedule-lock-wait: "2h"
    #schedule-log: '{{ tempFile "backup.log" }}'

  forget:
    before-backup: false
    after-backup: true
    #keep-hourly: 1
    keep-daily: 6
    keep-weekly: 3
    keep-monthly: 5
    #keep-within: "3h"
    keep-tag:
      - "protected"
    prune: true

  check:
    read-data: true
    # if scheduled, will check the repository the first day of each month at 6am
    schedule: "*-*-01 09:00"
    schedule-permission: "system"
    schedule-lock-wait: "2h"

This has been running for me for a few years now and I have had to recover from it twice. I'd love a native Proxmox cloud backup feature but in the meantime this has been solid for me.