Instantly share code, notes, and snippets.

Embed
What would you like to do?
Automatic snapshots using Vultr API

Automated Snapshots / Backups via Vultr API

A more customizable alternative to Vultr's backup feature using Vultr API v1. Tested on Ubuntu 16.04. Run this php script on a Vultr instance to create a snapshot of itself and rotate out the oldest snapshot(s). Use the $backup_tag field to uniquely id a set of snapshots.

  1. Set $api_key to your Vultr API key.
  2. Set $num_of_backups to specify how many snapshots to keep.
  3. Set chmod +x vultr-snapshot.php.
  4. Add vultr-snapshot.php to your cron tab.
  5. Epic winning at life.

For example, add the crob jobs below in order to create 3 daily, weekly, and monthly snapshots. The oldest snapshots will be automatically rotated out.

0 0 * * * /home/user/scripts/vultr-snapshot.php
#!/usr/bin/php
<?php
// input parameters
$api_key = "YOUR_API_KEY";
// default arguments
$backup_tag = "daily";
$num_of_backups = 3;
// sunday = weekly, 1st day of month = monthly
if(intval(date('w')) == 0) $backup_tag = "weekly";
if(intval( date('d')) == 1) $backup_tag = "monthly";
$api_addr = "https://api.vultr.com/v1/";
$curl = "curl -s -H 'API-Key: " . $api_key . "' " . $api_addr;
$host = trim(shell_exec("hostname"));
$ip = trim(shell_exec("hostname -I"));
// find a subid that matches the current ip
$json = shell_exec( $curl . "server/list" );
$obj = json_decode($json,true);
$subid = 0;
foreach ($obj as $k => $v) {
if( $v['main_ip'] == $ip ){
$subid = $k;
break;
}
}
if($subid == 0){
echo "Couldn't find a Vultr instance with ip " . $ip;
exit(1);
}
// find old snapshot(s) to remove
$json = shell_exec( $curl . "snapshot/list" );
$obj = json_decode($json,true);
// filter non-backup snapshots
$obj = array_filter($obj, function ($x){
return strpos($x['description'], $GLOBALS['ip'] . "-" . $GLOBALS['backup_tag']) !== false;
});
// reverse sort by creation time
usort($obj, function($x, $y){
return $y['date_created'] <=> $x['date_created'];
});
// delete oldest snapshot(s)
for($i=0;$i<count($obj);$i++){
if($i >= $num_of_backups-1){
$id = $obj[$i]['SNAPSHOTID'];
$cmd = $curl . "snapshot/destroy";
shell_exec( $cmd . " --data 'SNAPSHOTID=" . $id . "'" );
}
}
// create new snapshot
$cmd = $curl . "snapshot/create";
$cmd .= " --data 'SUBID=" . $subid . "'";
$cmd .= " --data 'description=" . $host . "-" . $ip . "-" . $backup_tag . "'";
shell_exec( $cmd );
?>
@jlchandler

This comment has been minimized.

jlchandler commented Nov 11, 2017

This is great! However, I'm receiving the message "Couldn't find a Vultr instance with ip xx.xx.xx.xxx". (IP replaced with x's) Any idea what the issue could be? Thanks!

@jlchandler

This comment has been minimized.

jlchandler commented Nov 11, 2017

UPDATE: On line 25 I manually changed “0” to my instance subid and it seemed to work as expected. Thanks again for creating this!

@mcknco

This comment has been minimized.

Owner

mcknco commented Nov 30, 2017

Hey @jlchandler, just noticed your comment! The idea is that I get the IP from the VPS instance directly (using hostname -I on line 19) and then compare it to the list of Vultr instances reported from the API (line 22) in order to figure out what the subid is. A bit strange they wouldn't match! Glad you like it, the first php I ever wrote!

@jlchandler

This comment has been minimized.

jlchandler commented Dec 3, 2017

Hey, @mcknco! Thanks for commenting back! I think I figured out what the issue is.

If your instance has an IPV6 address associated to it, the script throws the "Couldn't find a Vultr instance with ip xx.xx.xx.xxx." error. However, if your instance doesn't (IPV4 only), it works perfectly without manually entering your instance's subid into the script. Nice job on your first php script!

Side note: I'm looking for a php script that iterates over all domains in your Vultr account, searches for an IP and then replaces it with another. Really handy if you have a lot of domains (like me) and change where your instance is hosted at geographically on the Vultr network. How difficult would this be do you think? Thanks!

Edit: Like this, but for Vultr. https://www.aetherweb.co.uk/batch-editing-cloudflare-dns-ip-with-cloudflare-api-in-php/

@mcknco

This comment has been minimized.

Owner

mcknco commented Dec 4, 2017

Gotcha. If running hostname -I on your VPS terminal doesn't give back the IPv4 — thats a problem, but easily fixable. Depends on which OS, etc.

domains in your Vultr account

You mean domains using Vultr DNS? If you want to bulk replace A records (or whatever) using a script, that's definitely possible — the API commands are ready and waiting: https://www.vultr.com/api/#dns

Very annoying there's no comment notifications on GitHub gists!

@lucasltavares

This comment has been minimized.

lucasltavares commented Nov 5, 2018

Hello. First of all congratulations for the script, it is helping me a lot ! Sorry for my question, but how can i do only 1 daily backup ? i have 4 servers on vultr and i want to keep only 1 daily snapshot of each one, but this cron script makes weekly and monthly snapshots unnecessarily.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment