βοΈ Proxmox Backup Server - Cold backup
Abstract
A secondary Proxmox Backup Server operating as a pull-based, time-air-gapped replica of the primary PBS, powered on only during scheduled synchronization windows.
Prerequisites
- Proxmox Backup Server installed
Explanation
My goal is to have secondary local backup of my data that time-air-gapped. This offers: - an additional copy of my data (always useful) - an additional layer of security - some power saving as the server mostly powered off - longer retention on backups as this server has a bunch of spinning disks
I have PBS installed on a dedicated server, that will only power on at a specified time and after completing the sync of my backup, powers down automatically.
The cold storage PBS with only sync in a PULL motion. Meaning that it will pull the backups from the primary PBS. If the primary is compromised (malware, ransomware, credential theft), it cannot reach or overwrite the secondary backups.
1. Dedicated backup user
Create a dedicated backup user on your primary PBS

Give that user the necessary permissions: - Path: The path to the datastore that wish to sync - User: Your created backup user - Role: DatastoreReader (our user only need read permissions)

2. Namespaces (optional)
On the secondary PBS (cold PBS), I have created the same namespaces as on my primary PBS but with "cold" added in the name.

3. Add the primary PBS
On your secondary PBS, add the primary PBS. For this I refer to my guide: Proxmox Backup Server
and setup a sync job. Be sure to disable the option 'Remove Vanished'!! Otherwise, when a snapshot is deleted from the primary PBS, it will also be deleted on your secondary PBS.

I will run mine daily at 2pm.
4. Automatically start PBS
The next step is to determine on how to start your PBS. There are a couple of different ways depending on your BIOS options and preferences: - Some BIOS options allow you to start the system at a predefined time. - Wake on LAN (a separate server wakes up the PBS server) - Turn on after power loss (using a smart plug to turn on at a predefined time)
I will be choosing the last option using a Zigbee plug in Home Assistant. Using this method I will be turning on my PBS server daily. When PBS has completed all its tasks, it will shut down (more on this in the next part). Afterwards, when Home Assistant measures that the wattage on the smart plug is below than 10W, it will cut the power until the next backup period.
5. Stop PBS after all jobs are finished
With the help of a bash script, we can check if PBS has any active tasks running. If there are no tasks running, we will assume that the sync/backup is complete and the server can shut down.
Credit for the script goes to Apalrd https://www.apalrd.net/posts/2024/pbs_hibernate/
Strategy: - 12h55 - Start PBS - 13h00 - Prune job - 13h10 - Garbage collection job - 13h30 - Sync job - 14h00 - Start bash script to check if there are any jobs running. If not, shutdown. - (I will run verify jobs once a week at separate time)
To create the bash script to check if there are any jobs running:
#!/bin/bash
#Count of times we have queried and there are tasks running
count=0
#Number of no-task intervals before we shutdown
max=10
#Interval in seconds
interval=5
#Continue until we shutdown
while true; do
#Check if we should shutdown until we see not
if [[ $(proxmox-backup-manager task list) ]]; then
#Continue to wait
count=0
else
#There are no tasks running, so increment counter
count=$((count + 1))
echo "No tasks running, time until shutdown is $(((max - count) * interval)) seconds"
#If we reached the max count, then shutdown
if ((count >= max)); then
echo "Time to shutdown!"
shutdown now
fi
fi
#Delay by interval to next check
sleep "$interval"
done
echo "Exiting"
Make it executable:
[Unit]
Description=Shutdown when there are no tasks left
[Service]
ExecStart=/usr/local/sbin/autoshutdown.sh
[Install]
WantedBy=default.target
Create a timer to start the bash script at 14h00
[Unit]
Description=Shutdown
RefuseManualStart=no
RefuseManualStop=no
[Timer]
#Run at 14:00 local time
OnCalendar=*-*-* 14:00:00
Unit=autoshutdown.service
[Install]
WantedBy=timers.target
6. PBS verify job
I will run a verify job once a week. For this I will create: - a separate timer - the smart plug will start the PBS a litte before that time
Create a timer to start the bash script at 14h00