Scheduled Backups with Clockwork and Backup Gem

Today I am here to demonstrate a solution I have used to backup a Rails application to Amazon S3.

A popular library to perform backups in Ruby world, is Backup, it has a lot of options (for storage, compression, notification..) and seemed great to me.

Having our backup gem chosen, it's time to pick a gem to deal with scheduled jobs in order we can schedule automatic backups. As Clockwork already was in project's Gemfile, I used it.

Setting up Environment

It isn't recommended include Backup gem in project's main Gemfile, a solution is to create an isolated environment to this gem.

Firstly, let's install the gem:

gem install backup -v '~> 4.0.1'

Now, you will need to create the below structure:


Inside vendor/backup/Gemfile you drop:

source ''
gem 'backup', '~> 4.0.1'

This Gemfile is just to Bundler recognize the folder as an isolated env.

Generating Backup Model

In my case, I generated a simple backup model in order to backup a PostgreSQL database, compress the dump and send to Amazon S3:

bundle exec backup generate:model --trigger my_bkp_name --databases="postgresql" --storages="s3" --compressor="gzip" --config-file="./config.rb"

Fill in your credentials (taken from your .yml files) in the recently created file inside models folder:, 'Description for my_bkp_name') do
  # PostgreSQL [Database]
  database PostgreSQL do |db|
    DB = YAML.load_file("#{DIR}/config/database.yml")
    # try to get RAILS_ENV variable, 
    # if it is not set, use 'production'
    RAILS_ENV = ENV.fetch('RAILS_ENV'){'production'}

    # To dump all databases,
    # set ` = :all` (or leave blank)               = DB[RAILS_ENV]['database']
    db.username           = DB[RAILS_ENV]['username']
    db.password           = DB[RAILS_ENV]['password']               = DB[RAILS_ENV]['host']
    db.additional_options = ["-xc", "-E=utf8"]

  # Amazon Simple Storage Service [Storage]
  store_with S3 do |s3|
    S3 = YAML.load_file("#{DIR}/config/s3.yml")

    # AWS Credentials
    s3.access_key_id     = S3['access_key_id']
    s3.secret_access_key = S3['secret_access_key']

    s3.region            = "us-east-1"
    s3.bucket            = "bucket-name"
    s3.path              = "path/to/backups"
    # max 7 files
    s3.keep              = 7

  # Gzip [Compressor]
  compress_with Gzip

We will need set our DIR variable in config.rb file also:

DIR = File.expand_path('../../../', __FILE__)

And after, run it:

bundle exec backup perform --trigger my_bkp_name --config-file="./config.rb"

It should works, access your bucket and check out your dump..

Scheduling Backups

Finally, I scheduled backups in app/clock.rb file:

if Rails.env.production?
  every(, 'database_backup', at: '03:30') do
    dir = File.expand_path('../../', __FILE__)
    Bundler.with_clean_env do
      system "cd #{dir}/vendor/backup/; bundle exec backup perform --trigger my_bkp_name --config-file ./config.rb"

Here, we run the perform command inside our isolated env using with_clean_env, that ensure we are not in application's env.

You can also create a rake task like this in lib/tasks/db.rake:

task :backup do
  dir = File.expand_path('../../../', __FILE__)
  Bundler.with_clean_env do
    system "cd #{dir}/vendor/backup/; bundle exec backup perform --trigger my_bkp_name --config-file ./config.rb"

However, you will have to create a method inside app/clock.rb to invoke the rake:

def execute_rake(file,task)
  require 'rake'
  rake =
  Rake.application = rake
  load "#{Rails.root}/lib/tasks/#{file}"

if Rails.env.production?
  every(, 'database_backup', at: '03:30') { execute_rake "db.rake", 'db:backup' }

After all, you must have your automatic backup scheduled successfully.

See you.

Written on February 11, 2014