
Redonkulously easy, that is.
Your rails app has been humming along nicely for several months, then suddenly it hits you, wait, are we backing up our database / uploaded files yet?
Well, of course you are. But for those who prefer to live on the edge, launching an app without a well-articulated backup strategy, I give you backup_fu.
It’s a rails plugin, invoked via rake tasks. After installing the plugin and modifying a few lines in a config file, you can have your application backing up both its database and static files to Amazon S3 within minutes.
Update: backup fu does now support PostgresSQL. See this post for the 411.
Installation
Grab the only dependency, the aws-s3 gem (if not installed already):
sudo gem install aws-s3
And the plugin:
ruby script/plugin install http://backup-fu.googlecode.com/svn/backup_fu/
Configuration
Generate the default config/backup_fu.yml file with:
rake backup_fu:setup
You’ll need to modify at least these four lines in config/backup_fu.yml:
# The app_name is used as the backup filename prefix app_name: replace_me # Note: please create this bucket (whatever yours may be) externally first: s3_bucket: some-s3-bucket aws_access_key_id: --replace me with your AWS access key id-- aws_secret_access_key: --replace me with your AWS secret access key--
If you’re on OS X, the excellent S3 Browser will have you creating S3 buckets, browsing them, and uploading/downloading to them within minutes.
Jets3t is a Java-based S3 browser and should do the trick on win32/etc systems.
Basic Usage
To dump your database (to RAILS_ROOT/tmp/backup):
rake backup_fu:dump
In production environments, of course, you may have to do something like:
RAILS_ENV=production rake backup_fu:dump
To dump your database, then send the tar/gzipped copy to Amazon S3, it’s as simple as:
rake backup
This will place a file named something like ‘foo_app_2008-02-07_db.tar.gz’ into your Amazon S3 bucket (as specified by s3_bucket from your config file).
Configuration Options
If you bump into any snafus, the first thing you should do is enable verbosity via the config file:
verbose: true
See vendor/plugins/backup_fu/config/backup_fu.yml.advanced_example for the list of advanced configuration options. ( view online )
The most common issue that one might run into is ‘mysqldump’ not being in the user path.
To solve this do a ‘locate mysqldump’ or otherwise find its absolute path, and specify it explicitly in config/backup_fu.yml:
mysqldump_path: /usr/local/mysql/bin/mysqldump
Also see the README for more on debugging snafus and advanced configuration options.
Static File Backups
Backing up your database is great and all, but what if users upload files too?
Let’s say you’ve got a directory RAILS_ROOT/public/static where all of these files reside.
In our fictional example, this directory is really a symlink to /apps/foo/static. So we specify this as the ‘static_paths’ key (again in config/backup_fu.yml):
static_paths: "/apps/foo/static"
Let’s say we also wanted to backup ”/apps/foo/user_images”.
Multiple target static directories can be delimited via whitespace:
static_paths: "/apps/foo/static /apps/foo/user_images"
First let’s try dumping these static directories (with full contents) into a tar/gzipped archive in RAILS_ROOT/tmp/backup:
rake backup_fu:static:dump
If that worked, let’s go for the full enchilada (dumping + uploading to S3) with:
rake backup_fu:static:backup
And for backing up both your database + static files (they will get uploaded as separate, distinct archives) in one rake command:
rake backup_fu:all
Phew.

Notes
While I had trouble with aws-s3 in its early days, I’ve since used aws-s3 (and backup_fu) to send a 4GB file to Amazon S3. VPSes or systems with much less memory might have issues backing up such huge files, though.
See the README for cronjob examples.
Pluginizing this code (which existed for a while in my apps, though not as a plugin) was inspired by Scott Patten who has written a similar kind of plugin.
Backup_fu does not erase old backup archives for you. This is left as an exercise for the reader. :) But seriously, it’s probably a good idea to check on your backups every month or so and do some pruning then, by hand if necessary.








This is great fu!
I’d like to stress the point that mysqldump is one of the most demanding things you can do to your DB. This should only be done either A) From a replicated mirror (like a reporting server or fail-over slave), or B) Be done during low utilization times. Of course backups tend to be cron’ed for early morning. But, even while you are running you first tests, know that this can send your query response times through the roof. This can result in your connection pool filling up and connections being denied/aborted.
I’m a DBA and I’ve had one of my developers decide to load his local DB via mysqldump. He didn’t know the name of the slave server so he pulled the master’s name from his app. The DB server was denying 300 connections per minute for the 8 minutes that the mysqldump ran. That’s bad!
if you are using innodb tables providing the—single-transaction argument to mysqldump will cut down the exclusive locking
I made a simple change to allow you to set mysqldump parameters.
In your backup_fu.yml (add the parameters you like:
mysql_options:—single-transaction—flush-logs—add-drop-table—add-locks—create-options—disable-keys—extended-insert—quick
Change Line 32 of backup_fu.rb:
cmd = niceify ”#{mysqldump_path} #{@fu_conf[:mysql_options]} #{host} #{port}—user=#{@db_conf[:username]} #{password} #{@db_conf[:database]} > #{full_dump_path}”
Toby Hede http://FiniteStateMachine.com: Software Development for Social Netowkrs
Thank you so much for this! I’ve been waiting for a no-brainer backup solution for a long time now.
If you don’t mind, I had one quick fix feature request:
If the config yml doesn’t define aws_access_key_id and/or aws_secret_access_key, check the environment—attachment_fu uses this, and it saves one more config step.
line 116: :access_key_id => (@fu_conf[:aws_access_key_id] || ENV[‘AMAZON_ACCESS_KEY_ID’]), :secret_access_key => (@fu_conf[:aws_secret_access_key] || ENV[‘AMAZON_SECRET_ACCESS_KEY’])
THANKS!!
Awesome plugin.
Been playing around with it this morning and I’ve gotta say it does exactly what I need.
Keep up the good work.
Worked like a charm! I’ve been looking to do something just like this for a while not. Note that I was originally getting “Access denied… ...when using LOCK TABLES” but a quick permissions fix in mysql did the trick. Thanks for releasing this.
Hey guys – thanks for all of the kind words.
I’ve applied many of the suggestions from above with the latest release. See:
http://shanti.railsblog.com/a-few-updates-to-backup_fu
If the Database Backup tag.gz file gets beyond 5 gigs it won’t be able to go into S3 right? Can backup_fu automatically chop backups into 5 gig pieces before sending?
this rocks. thanks Shanti
Hi
http://fglgokff.com nrljg pftav http://ddelyaov.com nvixe dlsas
Hi webmaster!