We all know how important database backups are. Even if functionalities like Multi AZ support, multiple replicas, it's importance can't be more emphasised.
Ruby has a handy wrapper to automate this.
Setup Requirements:
- A linux server (proper disk space should be there, atleast the size of your database)
- Ruby installation. (rvm/rbenv can be used)
- Slack/Flock/Mattermost/SMTP (*not required, but good to have)
- Place where to store the backup. I personally prefer S3. It can be local, FTP or anything of that sort.
Process:
- Install
backup
gem. As I write this post,4.3.0
is the latest release out there. You can install the same withgem install backup
However, there are certain problems on some systems with the installation. If you face any error, try installing the nextrc
candidategem install backup -v5.0.0.beta.1
- Backup gem provides a
cli
utility for ease. Generate the config file by running this task:backup generate:model --trigger producion_backup --archives --storages='s3' --databases='postgresql' --compressor='gzip'
. The flags are self explanatory IMO. - Open up the generated file:
vim ~/Backup/models/production_backup.rb
- Replace, and tweak the needed items:
# encoding: utf-8
Model.new(:producion_backup, 'Description for producion_backup') do
archive :configs do |archive|
archive.add "/home/ubuntu/projects/api/shared/config/"
archive.add '/etc/nginx/'
end
database PostgreSQL do |db|
db.name = "db_name"
db.username = "db_username"
db.password = "db_password"
db.host = "db_url.ap-south-1.rds.amazonaws.com" # or localhost, or anyother hosted service url
db.port = 5432 # or any other port that you might have
end
# Keep 4 monthly backups
# 6 weekly
# 7 daily
# and 23 daily backups
time = Time.now
if time.hour == 0
if time.day == 1 # first day of the month
storage_id = :monthly
keep = 4
elsif time.sunday?
storage_id = :weekly
keep = 7
else
storage_id = :daily
keep = 6
end
else
storage_id = :hourly
keep = 23
end
store_with S3 do |s3|
# AWS Credentials
s3.access_key_id = "AWS_access_key_id"
s3.secret_access_key = "AWS_secret_access_key"
s3.region = "ap-south-1"
s3.bucket = "db-backups"
s3.path = "/backups/#{storage_id}"
s3.keep = keep
end
# can use mattermost/Flock or anyother servicee that takes in webhooks.
notify_by Slack do |slack|
slack.on_success = true
slack.on_failure = true
slack.webhook_url = 'Webhook URL'
slack.username = 'Backup bot'
slack.channel = 'db-backup-alerts'
slack.icon_emoji = ':ice:'
end
compress_with Gzip
end
5. Create a bucket in S3 before running the trigger.
6. Trigger the backup with backup perform --trigger production_backup
7. Verify the backup after it's done and uploaded over to S3.
8. Put up a cron
job for automating this, 0 * * * * /bin/bash -l -c 'rvm use 2.6.3 && backup perform --triggert producion_backup'
. The job will run every hour.
9. Why the server hard disk needs to be large? Because this gem creates an archive of the tables and other items in local first, and then uploads it.
I hope the article was helpful for you!
Documentation and more tweaking options for Backup gem can be found here.