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