All posts

Backup and Snapshot Management on Proxmox: GUI vs CLI

A technical guide to scheduling automatic snapshots on Proxmox VE: comparing full backups via GUI against atomic snapshots via CLI.

The Problem: Disaster Recovery Strategies on Proxmox

In a production environment or an advanced homelab, data persistence is critical. Proxmox VE offers several methodologies to ensure the operational continuity of LXC containers. However, full backups and snapshots are often confused, leading to inefficient use of storage resources.

How can we schedule automatic saves that are fast and storage-efficient?


Standard Approach: The Proxmox GUI

The Proxmox web interface provides a native tool under Datacenter -> Backup. This allows you to create scheduled jobs for entire VMs or LXC containers.

Pros

  • Simplicity: Visual configuration with no need to write scripts.
  • Granular Restore: Ability to restore an entire container to a new ID or a different cluster node.
  • External Destinations: Native support for NFS, SMB, or Proxmox Backup Server storage.

Cons

  • Heavy I/O: The standard backup tool (vzdump) creates a compressed disk archive. Even with incremental backups (when using PBS), the I/O load is higher than a snapshot.
  • Execution Time: The compression and transfer process takes time proportional to the disk size.

The CLI Way: Filesystem-Level Snapshots

For those seeking maximum efficiency, the command line allows you to leverage the atomic capabilities of modern filesystems (such as ZFS or Thin-LVM) to create instantaneous snapshots. A snapshot does not copy data — it “freezes” the state of blocks at a specific point in time.

Pros

  • Speed: Creation is nearly instantaneous (milliseconds).
  • Storage Efficiency: Only the differences (deltas) generated after the snapshot consume additional space.
  • No Downtime: There is no need to suspend the container for extended periods.

Cons

  • Hardware Dependent: Requires filesystems that support snapshots (ZFS, BTRFS, LVM-Thin).
  • Not a True Backup: If the physical disk fails, you lose both the container and the snapshot. Snapshots are meant for quick rollbacks, not long-term disaster recovery.

Implementation: Automated Snapshots via CLI

To automate snapshots via CLI, we can use the native pct snapshot command. Below is a Bash script example that can be used in a cron job or a systemd timer unit.

The Script

Save the script to /usr/local/bin/lxc-snap.sh and make it executable with chmod +x /usr/local/bin/lxc-snap.sh.

#!/bin/bash

CONTAINER_ID=105
SNAPSHOT_NAME="Auto_$(date +%Y%m%d_%H%M%S)"
LOG_FILE="/var/log/proxmox_snapshots.log"

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

log "Starting snapshot creation for LXC $CONTAINER_ID (name: $SNAPSHOT_NAME)..."

pct snapshot "$CONTAINER_ID" "$SNAPSHOT_NAME" --description "Scheduled automatic snapshot"

if [ $? -eq 0 ]; then
    log "SUCCESS: snapshot $SNAPSHOT_NAME created successfully."
else
    log "ERROR: snapshot $SNAPSHOT_NAME creation failed for LXC $CONTAINER_ID."
    exit 1
fi

The log() function prepends a timestamp to every line and writes to both the log file and stdout — useful for both manual log inspection and systemd capture, as we will see shortly.


Automation via Cron

From the Proxmox shell, run crontab -e and add the following line to schedule the script every night at 03:00:

0 3 * * * root /usr/local/bin/lxc-snap.sh >> /var/log/proxmox_snapshots.log 2>&1

Automation via Systemd Timer

As an alternative to cron, systemd offers a more robust and integrated mechanism based on two INI-format files (not YAML): a service unit, which describes the process to run, and a timer unit, which defines its schedule. Both files go in /etc/systemd/system/.

Service unit: lxc-snapshot.service

[Unit]
Description=Automatic LXC Snapshot via pct
# If the service fails (exit code != 0), trigger the failure handler unit
OnFailure=lxc-snapshot-failure@%n.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/lxc-snap.sh
# stdout and stderr are captured by journald and also written to file
StandardOutput=append:/var/log/proxmox_snapshots.log
StandardError=append:/var/log/proxmox_snapshots.log

[Install]
WantedBy=multi-user.target

Timer unit: lxc-snapshot.timer

[Unit]
Description=Run LXC Snapshot every night at 03:00

[Timer]
OnCalendar=*-*-* 03:00:00
# If the system was off at the scheduled time, run on next boot
Persistent=true
Unit=lxc-snapshot.service

[Install]
WantedBy=timers.target

Failure handler: lxc-snapshot-failure@.service

If lxc-snap.sh exits with a non-zero exit code, systemd automatically triggers this unit. In this example the failure is recorded in a dedicated log, but the same structure can be extended to send notifications via email or webhook.

[Unit]
Description=LXC Snapshot Failure Notification (%i)

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'echo "[$(date \"+%%Y-%%m-%%d %%H:%%M:%%S\")] FAILURE: service %i exited with an error." >> /var/log/proxmox_snapshots.log'

Activation

After saving the three files, run:

systemctl daemon-reload
systemctl enable --now lxc-snapshot.timer

To verify the timer is active and see the next scheduled execution:

systemctl list-timers lxc-snapshot.timer

To inspect logs from previous runs via journald:

journalctl -u lxc-snapshot.service

Note: Snapshots are not a replacement for an offsite backup. For a complete disaster recovery strategy, pair this setup with a vzdump job scheduled to an external storage target (NFS, PBS, etc.).