EZ drop in backup rake task for your rails projects - works well - 5 - 10 min set up, one rake file and one config file
backs up db and any directory's to any number of servers with rsync
BSD License or whatever, but it would be cool if you told me your using it
2007 ISS http://industrialstrengthinc.com
this is a sample config file and a rake task you can drop into any rails project to do backups, easy to automate.
Backs up your specified environment db to activerecord yml files (one per table) and zips them up in a human readable timestamped file
syncs that and any other set of arbitrary directory's to any number of arbitrary servers with rsync
be sure to set ssh key based logins
to run: rake backup
also: rake backup:db, rake backup:restoredb (promts for a file created by backup:db), rake backup:push (to push out what u got)
note: this uses something like 30 lines of code from some blog site I got it from that I cant recall, yay for that guy, thanks
1
2
3
4 3 * * * * cd /rails_deployment_dir/current && nice rake backup RAILS_ENV=production >> /rails_deployment_dir/production_backup_system.log
5
6
7
8 production:
9 dirs:
10 - db/backups
11 - public/uploaded_images
12 servers:
13 - name: backup server number 1
14 host: gridserver.com
15 port: 22
16 user: blah@whatever.com
17 dir: /home/blah/backups
18 - name: backup server two
19 host: kradradio.com
20 port: 22
21 user: kraduser
22 dir: /home/kraduser/backups_from_my_rails_proj
23
24
25 development:
26 dirs:
27 - db/backups
28 - public/uploaded_images
29 servers:
30 - name: local self
31 host: localhost
32 port: 5222
33 user: oneman
34 dir: /home/oneman/Documents/development_backup
35
36
37
38
39 desc "Backup Everything Specified in config/backup.yml"
40 task :backup => [ "backup:db", "backup:push"]
41
42 namespace :backup do
43
44 RAILS_APPDIR = RAILS_ROOT.sub("/config/..","")
45
46 def interesting_tables
47 ActiveRecord::Base.connection.tables.sort.reject! do |tbl|
48 ['schema_info', 'sessions', 'public_exceptions'].include?(tbl)
49 end
50 end
51
52 desc "Push backup to remote server"
53 task :push => [:environment] do
54 FileUtils.chdir(RAILS_APPDIR)
55 backup_config = YAML::load( File.open( 'config/backup.yml' ) )[RAILS_ENV]
56 for server in backup_config["servers"]
57 puts "Backing up #{RAILS_ENV} directorys #{backup_config['dirs'].join(', ')} to #{server['name']}"
58 puts "Time is " + Time.now.rfc2822 + "\n\n"
59 for dir in backup_config["dirs"]
60 local_dir = RAILS_APPDIR + "/" + dir + "/"
61 remote_dir = server['dir'] + "/" + dir.split("/").last + "/"
62 puts "Syncing #{local_dir} to #{server['host']}#{remote_dir}"
63 sh "/usr/bin/rsync -avz -e 'ssh -p#{server['port']} ' #{local_dir} #{server['user']}@#{server['host']}:#{remote_dir}"
64 end
65 puts "Completed backup to #{server['name']}\n\n"
66 end
67 end
68
69 task :storedb => :environment do
70
71 backupdir = RAILS_APPDIR + '/db/backup'
72 FileUtils.mkdir_p(backupdir)
73 FileUtils.chdir(backupdir)
74 puts "Dumping database to activerecord yaml files in #{backupdir}"
75 interesting_tables.each do |tbl|
76
77 klass = tbl.classify.constantize
78 puts "Writing #{tbl}..."
79 File.open("#{tbl}.yml", 'w+') { |f| YAML.dump klass.find(:all).collect(&:attributes), f }
80 end
81 puts "Database Dumped.\n\n"
82 end
83
84 desc "Dump Current Environment Db to file"
85 task :db => [:environment, :storedb ] do
86 backupdir = RAILS_APPDIR + '/db/backup'
87 archivedir = RAILS_APPDIR + '/db/backups'
88 backup_filename = "#{RAILS_ENV}_db_backup_#{Time.now.strftime("%B.%d.%Y_at_%I.%M.%S%p_%Z")}.tar.bz2"
89 FileUtils.mkdir_p(archivedir)
90 puts "Archiving #{backupdir} yaml files to #{backup_filename}\n\n"
91 `tar -C #{backupdir} -cjf #{backup_filename} *`
92 `mv #{backup_filename} #{archivedir}`
93 end
94
95 desc "Restore Current Environment Db from a file"
96 task :restoredb => [:environment] do
97 backupdir = RAILS_APPDIR + '/db/backup'
98 archivedir = RAILS_APPDIR + '/db/backups'
99 print "Input a file to load into the db: #{archivedir}/"
100 backup_filename = STDIN.gets.chomp
101 puts "Loading backup file: #{backup_filename}"
102 FileUtils.chdir(archivedir)
103 `tar -xjf #{backup_filename}`
104 `mv *.yml #{backupdir}`
105 FileUtils.mkdir_p(backupdir)
106 FileUtils.chdir(backupdir)
107
108 interesting_tables.each do |tbl|
109 puts "Clearing #{tbl} table.."
110 ActiveRecord::Base.connection.execute "TRUNCATE #{tbl}"
111 puts "Loading #{tbl} backup file..."
112 table = YAML.load_file("#{tbl}.yml")
113
114 if table.length > 0 && table.first.key?("id")
115 highestid = 0
116 table.each do |fixture|
117 if fixture["id"] > highestid
118 highestid = fixture["id"]
119 end
120 end
121
122 ActiveRecord::Base.connection.execute "SELECT setval('#{tbl}_id_seq',#{highestid})"
123 puts "Setting #{tbl}_id sequence to #{highestid}"
124 end
125
126
127 ActiveRecord::Base.transaction do
128
129 puts "Inserting #{table.length} values into #{tbl}"
130 table.each do |fixture|
131 ActiveRecord::Base.connection.execute "INSERT INTO #{tbl} (#{fixture.keys.join(",")}) VALUES (#{fixture.values.collect { |value| ActiveRecord::Base.connection.quote(value) }.join(",")})", 'Fixture Insert'
132 end
133 puts "#{tbl} table restored.\n\n"
134 end
135 end
136 end
137
138
139 end