How I Handle Backups
The normal rule is 3-2-1 - 3 backups, 2 onsite, 1 offsite. However I do 2 offsite only. I may do a third offsite, but not sure just yet.
I use Scaleway's C14 Cold Storage. I used OVH Archive, but the upload speeds were super slow.
In proxmox I edited the /etc/vzdump.conf
and added script: /path/to/my/perl/script.pl
at the bottom. When I run vzdump from the ui or proxmox kicks off a backup cron the script will get ran.
Originally I was using a simple python script to backup vms to the cloud, but since I changed to this perl script.
#!/usr/bin/perl -w
from https://gitlab.com/mikeramsey/proxmox-vzdump-hook-script.pl/-/blob/master/vzdump-hook-script.pl
example hook script for vzdump (–script option)
use strict;
print “HOOK: " . join (’ ‘, @ARGV) . “\n”;
my $phase = shift;
my $GPGKey = “REDACTED”;
if ($phase eq ‘job-start’ ||
$phase eq ‘job-end’ ||
$phase eq ‘job-abort’) {
my $dumpdir = $ENV{DUMPDIR};
my $storeid = $ENV{STOREID};
print "HOOK-ENV: dumpdir=$dumpdir;storeid=$storeid\n";
} elsif ($phase eq ‘backup-start’ ||
$phase eq ‘backup-end’ ||
$phase eq ‘backup-abort’ ||
$phase eq ’log-end’ ||
$phase eq ‘pre-stop’ ||
$phase eq ‘pre-restart’ ||
$phase eq ‘post-restart’) {
my $mode = shift; # stop/suspend/snapshot
my $vmid = shift;
my $vmtype = $ENV{VMTYPE}; # lxc/qemu
my $dumpdir = $ENV{DUMPDIR};
my $storeid = $ENV{STOREID};
my $hostname = $ENV{HOSTNAME};
my $target = $ENV{TARGET};
my $logfile = $ENV{LOGFILE};
print "HOOK-ENV: vmtype=$vmtype;dumpdir=$dumpdir;storeid=$storeid;hostname=$hostname;target=$target;logfile=$logfile\n";
if ($phase eq 'backup-end') {
# encrypt the backup using gpg
print "encrypting $target";
system ("gpg -r $GPGKey -e $target") == 0 ||
die "encrypting $target failed";
# upload to c14 cold
print "Uploading ${target}.gpg to c14-cold-fr";
system ("rclone copy --config /root/.config/rclone/rclone.conf -P ${target}.gpg c14-cold-fr:/REDACTED/MYDIR") == 0 ||
die "uploading $target to c14-cold-fr failed";
# upload to c14 cold
print "Uploading ${target}.gpg to c14-cold-nl";
system ("rclone copy --config /root/.config/rclone/rclone.conf -P ${target}.gpg c14-cold-nl:/REDACTED --transfers 16 --buffer-size 512") == 0 ||
die "uploading $target to c14-cold-nl failed";
print "Deleting ${target}.gpg";
system ("rm ${target}.gpg") == 0 ||
die "deleting ${target}.gpg failed";
# print "Deleting $target and ${target}.gpg";
# system ("rm $target ${target}.gpg") == 0 ||
# die "deleting $target ${target}.gpg failed";
}
} else {
die “got unknown phase ‘$phase’”;
}
exit (0);
Here's the rclone config that I use.
[c14-cold-fr]
type = s3
provider = Other
env_auth = false
access_key_id = REDACTED
secret_access_key = REDACTED
region = fr-par
endpoint = https://s3.fr-par.scw.cloud
location_constraint = fr-par
acl = private
bucket_acl = private
chunk_size = 25M
upload_concurrency = 100
storage_class = GLACIER
[c14-cold-nl]
type = s3
provider = Other
env_auth = false
access_key_id = REDACTED
secret_access_key = REDACTED
region = nl-ams
endpoint = https://s3.nl-ams.scw.cloud
location_constraint = nl-ams
acl = private
bucket_acl = private
chunk_size = 25M
upload_concurrency = 100
storage_class = GLACIER
Instead of letting rclone handle the encryption (tbh I'm not familiar with it) I just run a gpg command to encrypt the backup.
until next time