Automatic Server Snapshots

Tech Website Ryan DIY

So, after accidentally messing up previous attempts at this website, I wanted to be sure we had a way to easily revert the entire server back. Just in case we... you know... screw something up. Again.

As I've written about before, I have set this website up on a digital ocean droplet. One thing I love about Digital ocean is that they provide the ability to easily take snapshots of droplets. Additionally, they provide an amazing API, that allows me to script all of this functionality.

I could occasionally run snapshots manually, but I knew they likely wouldn't be done consistently then. So, I decided to write a script using the API that can safely shutdown the server, run and name a snapshot, and restart the server, on a nightly basis.

I have never written Ruby code before, so I quickly taught myself the basics required to write this script. It's not the prettiest code, but hey, it works. Especially considering I wrote it in less than an hour with no Ruby or the digital ocean API experience.

require 'droplet_kit'

# Token and droplet ID
token = "DigitalOcean TOKEN CODE HERE"  

# Make snapshot name
time =  
snapshotName = "wedding-snapshot_%d%d%d" % [time.year, time.month,]  
puts snapshotName

# Droplet
client = token)  
droplets = client.droplets.all.each

# Shutdown Droplet if active
if client.droplets.find(id: dropletID).status == "active"  
  puts "active -- attempting shutdown"
  client.droplet_actions.shutdown(droplet_id: dropletID)
  if client.droplets.find(id: dropletID).status == "active"
    puts "Still active, force power off"
    client.droplet_actions.power_off(droplet_id: dropletID)
  puts "not active"

# Take snapshot
client.droplet_actions.snapshot(droplet_id: dropletID, name: snapshotName)

puts "Snapshot Complete"  

I have setup a cron job to automatically run this script nightly. This means that we have daily snapshots of the wedding server and can revert back to another time if we mess something up. Additionally, I can manually run the script with a single command, if I wish to force an additional snapshot.

This seems to be working really well. Based on this experience, I try to use the Digital Ocean API more often.