heroku-mongo-backup 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/README.md +55 -0
- data/Rakefile +7 -0
- data/heroku-mongo-backup.gemspec +20 -0
- data/lib/heroku-mongo-backup.rb +29 -4
- data/lib/s3_helpers.rb +92 -34
- data/lib/tasks/heroku_mongo_backup.rake +1 -1
- metadata +23 -3
data/.gitignore
ADDED
data/README.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
## heroku-mongo-backup *— backup mongodb on Heroku and push it to S3 or FTP storage*
|
2
|
+
|
3
|
+
**heroku-mongo-backup** does:
|
4
|
+
|
5
|
+
1. Backup mongodb collections to one file;
|
6
|
+
2. Compress backup file with gzip;
|
7
|
+
3. Push backup to the specified S3 bucket or FTP server;
|
8
|
+
|
9
|
+
> Why not mongodump command?
|
10
|
+
|
11
|
+
*mongodump* command is not available on Heroku side. If you don't want to setup third party backup service for every project *heroku-mongo-backup* may be helpful.
|
12
|
+
|
13
|
+
|
14
|
+
## Configuration
|
15
|
+
|
16
|
+
Add gem to the ```Gemfile```: ```gem "heroku-mongo-backup"``` - if everything's okay ```rake -T``` command should show ```rake mongo:backup``` rake tasks.
|
17
|
+
|
18
|
+
For S3 support **heroku-mongo-backup** requires ```s3``` or ```aws-s3``` or ```fog``` library. One of those should be in ```Gemfile```, if you don't care add ```fog``` it's seems to be the most advanced.
|
19
|
+
|
20
|
+
Configure heroku scheduler to run ```mongo:backup``` rake task. Or if cron is used add backup task to ```/lib/tasks/cron.rake``` file:
|
21
|
+
|
22
|
+
```
|
23
|
+
desc "This task is called by the Heroku cron add-on"
|
24
|
+
task :cron => :environment do
|
25
|
+
Rake::Task['mongo:backup'].invoke
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
29
|
+
Set Heroku environment variables:
|
30
|
+
|
31
|
+
```heroku config:add S3_BACKUPS_BUCKET=_value_ S3_KEY_ID=_value_ S3_SECRET_KEY=_value_ MONGO_URL=_value_```
|
32
|
+
|
33
|
+
On MONGO_URL place anyone of these is assaptable: *MONGOHQ_URI* or *MONGOLAB_URI*.
|
34
|
+
|
35
|
+
For FTP set these variables:
|
36
|
+
|
37
|
+
```heroku config:add UPLOAD_TYPE=ftp FTP_HOST=_host_ FTP_PASSWORD=_pass_ FTP_USERNAME=_user_```
|
38
|
+
|
39
|
+
|
40
|
+
## Rake Commands
|
41
|
+
|
42
|
+
* ```heroku run rake mongo:backup```
|
43
|
+
* ```heroku run rake mongo:restore FILE=backup-file-name.gz```
|
44
|
+
|
45
|
+
For Rails 2 add this to your Rakefile to import rake tasks:
|
46
|
+
|
47
|
+
```import File.expand_path(File.join(Gem.datadir('heroku-mongo-backup'), '..', '..', 'lib', 'tasks', 'heroku_mongo_backup.rake'))```
|
48
|
+
|
49
|
+
## Gem Contributors
|
50
|
+
|
51
|
+
1. [alexkravets - slatestudio.com](http://slatestudio.com "Slate Studio") - gem itself with S3 support
|
52
|
+
2. [matyi](https://github.com/matyi "Matyi - GitHub Profile") - FTP support
|
53
|
+
3. [stefl - stef.io](http://stef.io "Stef Lewandowski") - Rails is not required for production
|
54
|
+
4. [moonhouse - moonhouse.se](http://www.moonhouse.se/ "David Hall") - default config improvement
|
55
|
+
5. [wolfpakz](https://github.com/wolfpakz "Dan Porter") - Rails2 support
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'heroku-mongo-backup'
|
3
|
+
s.version = '0.4.1'
|
4
|
+
s.summary = 'Rake task backups mongo database on Heroku and push gzipped file to Amazon S3 or FTP.'
|
5
|
+
s.description = 'Rake task for backing up mongo database on heroku and push it to S3 or FTP. Library can be used as rake task or be easily integrated into daily cron job.'
|
6
|
+
|
7
|
+
s.authors = ['Alex Kravets', 'matyi', 'Stef Lewandowski', 'David Hall', 'Dan Porter']
|
8
|
+
s.email = 'santyor@gmail.com'
|
9
|
+
s.homepage = 'https://github.com/alexkravets/heroku-mongo-backup'
|
10
|
+
|
11
|
+
s.require_paths = ["lib"]
|
12
|
+
s.files = `git ls-files`.split($\)
|
13
|
+
s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
14
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
15
|
+
|
16
|
+
# Supress the warning about no rubyforge project
|
17
|
+
s.rubyforge_project = 'nowarning'
|
18
|
+
|
19
|
+
s.add_runtime_dependency 'mongo'
|
20
|
+
end
|
data/lib/heroku-mongo-backup.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
3
|
require 'mongo'
|
4
|
-
require 'bson'
|
5
4
|
require 'json'
|
6
5
|
require 'zlib'
|
7
6
|
require 'uri'
|
@@ -109,6 +108,12 @@ module HerokuMongoBackup
|
|
109
108
|
|
110
109
|
def s3_connect
|
111
110
|
bucket = ENV['S3_BACKUPS_BUCKET']
|
111
|
+
if bucket.nil?
|
112
|
+
bucket = ENV['S3_BACKUP_BUCKET']
|
113
|
+
end
|
114
|
+
if bucket.nil?
|
115
|
+
bucket = ENV['S3_BACKUP']
|
116
|
+
end
|
112
117
|
if bucket.nil?
|
113
118
|
bucket = ENV['S3_BUCKET']
|
114
119
|
end
|
@@ -117,11 +122,17 @@ module HerokuMongoBackup
|
|
117
122
|
if access_key_id.nil?
|
118
123
|
access_key_id = ENV['S3_KEY']
|
119
124
|
end
|
125
|
+
if access_key_id.nil?
|
126
|
+
access_key_id = ENV['AWS_ACCESS_KEY_ID']
|
127
|
+
end
|
120
128
|
|
121
129
|
secret_access_key = ENV['S3_SECRET_KEY']
|
122
130
|
if secret_access_key.nil?
|
123
131
|
secret_access_key = ENV['S3_SECRET']
|
124
132
|
end
|
133
|
+
if secret_access_key.nil?
|
134
|
+
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY']
|
135
|
+
end
|
125
136
|
|
126
137
|
@bucket = HerokuMongoBackup::s3_connect(bucket, access_key_id, secret_access_key)
|
127
138
|
end
|
@@ -145,10 +156,17 @@ module HerokuMongoBackup
|
|
145
156
|
#config_template = ERB.new(IO.read("config/mongoid.yml"))
|
146
157
|
#uri = YAML.load(config_template.result)['production']['uri']
|
147
158
|
uri = ENV['MONGO_URL']
|
159
|
+
|
160
|
+
if uri.nil?
|
161
|
+
uri = ENV['MONGOHQ_URL']
|
162
|
+
end
|
163
|
+
if uri.nil?
|
164
|
+
uri = ENV['MONGOLAB_URI']
|
165
|
+
end
|
148
166
|
else
|
149
167
|
mongoid_config = YAML.load_file("config/mongoid.yml")
|
150
168
|
config = {}
|
151
|
-
defaults
|
169
|
+
defaults = mongoid_config['defaults']
|
152
170
|
dev_config = mongoid_config['development']
|
153
171
|
|
154
172
|
config.merge!(defaults) unless defaults.nil?
|
@@ -158,11 +176,19 @@ module HerokuMongoBackup
|
|
158
176
|
port = config['port']
|
159
177
|
database = config['database']
|
160
178
|
uri = "mongodb://#{host}:#{port}/#{database}"
|
179
|
+
|
180
|
+
if uri == 'mongodb://:/' # new mongoid version 3.x
|
181
|
+
mongoid_config = YAML.load_file("config/mongoid.yml")
|
182
|
+
dev_config = mongoid_config['development']['sessions']['default']
|
183
|
+
host_port = dev_config['hosts'].first
|
184
|
+
database = dev_config['database']
|
185
|
+
uri = "mongodb://#{host_port}/#{database}"
|
186
|
+
end
|
161
187
|
end
|
162
188
|
|
163
189
|
@url = uri
|
164
190
|
|
165
|
-
puts "Using
|
191
|
+
puts "Using database: #{@url}"
|
166
192
|
|
167
193
|
self.db_connect
|
168
194
|
|
@@ -200,4 +226,3 @@ module HerokuMongoBackup
|
|
200
226
|
end
|
201
227
|
end
|
202
228
|
end
|
203
|
-
|
data/lib/s3_helpers.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
begin
|
2
2
|
require 's3'
|
3
|
+
|
3
4
|
rescue LoadError
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
#
|
6
|
+
# There is no 's3' gem in Gmefile
|
7
|
+
#
|
8
|
+
#puts "There is no 's3' gem in Gemfile."
|
8
9
|
end
|
9
10
|
|
10
11
|
if defined?(S3)
|
@@ -18,11 +19,13 @@ if defined?(S3)
|
|
18
19
|
bucket = service.buckets.find(bucket)
|
19
20
|
return bucket
|
20
21
|
end
|
22
|
+
|
21
23
|
def HerokuMongoBackup::s3_upload(bucket, filename)
|
22
24
|
object = bucket.objects.build("backups/#{filename}")
|
23
25
|
object.content = open(filename)
|
24
26
|
object.save
|
25
27
|
end
|
28
|
+
|
26
29
|
def HerokuMongoBackup::s3_download(bucket, filename)
|
27
30
|
object = bucket.objects.find("backups/#{filename}")
|
28
31
|
content = object.content(reload=true)
|
@@ -35,36 +38,91 @@ if defined?(S3)
|
|
35
38
|
|
36
39
|
return content
|
37
40
|
end
|
38
|
-
|
39
|
-
begin
|
40
|
-
require 'aws/s3'
|
41
|
-
rescue LoadError
|
42
|
-
#
|
43
|
-
# There is no 'aws/s3' in Gemfile
|
44
|
-
#
|
45
|
-
#puts "There is no 'aws/s3' gem in Gemfile."
|
46
|
-
end
|
41
|
+
end
|
47
42
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
58
|
-
def HerokuMongoBackup::s3_upload(bucket, filename)
|
59
|
-
AWS::S3::S3Object.store("backups/#{filename}", open(filename), bucket)
|
60
|
-
end
|
61
|
-
def HerokuMongoBackup::s3_download(bucket, filename)
|
62
|
-
content = AWS::S3::S3Object.value("backups/#{filename}", bucket)
|
63
|
-
return content
|
64
|
-
end
|
65
|
-
else
|
66
|
-
logging = Logger.new(STDOUT)
|
67
|
-
logging.error "heroku-mongo-backup: Please include 's3' or 'aws/s3' gem in applications Gemfile."
|
68
|
-
end
|
43
|
+
|
44
|
+
|
45
|
+
begin
|
46
|
+
require 'aws/s3'
|
47
|
+
rescue LoadError
|
48
|
+
#
|
49
|
+
# There is no 'aws/s3' in Gemfile
|
50
|
+
#
|
51
|
+
#puts "There is no 'aws/s3' gem in Gemfile."
|
69
52
|
end
|
70
53
|
|
54
|
+
if defined?(AWS)
|
55
|
+
#
|
56
|
+
# Using 'aws/s3' gem as Amazon S3 interface
|
57
|
+
#
|
58
|
+
#puts "Using \'aws/s3\' gem as Amazon S3 interface."
|
59
|
+
def HerokuMongoBackup::s3_connect(bucket, key, secret)
|
60
|
+
AWS::S3::Base.establish_connection!(:access_key_id => key,
|
61
|
+
:secret_access_key => secret)
|
62
|
+
# This is probably doesn't work
|
63
|
+
return bucket
|
64
|
+
end
|
65
|
+
|
66
|
+
def HerokuMongoBackup::s3_upload(bucket, filename)
|
67
|
+
AWS::S3::S3Object.store("backups/#{filename}", open(filename), bucket)
|
68
|
+
end
|
69
|
+
|
70
|
+
def HerokuMongoBackup::s3_download(bucket, filename)
|
71
|
+
content = AWS::S3::S3Object.value("backups/#{filename}", bucket)
|
72
|
+
return content
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
begin
|
80
|
+
require 'fog'
|
81
|
+
rescue LoadError
|
82
|
+
#
|
83
|
+
# There is no 'fog' in Gemfile
|
84
|
+
#
|
85
|
+
#puts "There is no 'fog' gem in Gemfile."
|
86
|
+
end
|
87
|
+
|
88
|
+
if defined?(Fog)
|
89
|
+
#
|
90
|
+
# Using 'aws/s3' gem as Amazon S3 interface
|
91
|
+
#
|
92
|
+
#puts "Using \'aws/s3\' gem as Amazon S3 interface."
|
93
|
+
def HerokuMongoBackup::s3_connect(bucket, key, secret)
|
94
|
+
connection = Fog::Storage.new({
|
95
|
+
:provider => 'AWS',
|
96
|
+
:aws_access_key_id => key,
|
97
|
+
:aws_secret_access_key => secret
|
98
|
+
})
|
99
|
+
directory = connection.directories.new(:key => bucket)
|
100
|
+
return directory
|
101
|
+
end
|
102
|
+
|
103
|
+
def HerokuMongoBackup::s3_upload(directory, filename)
|
104
|
+
file = directory.files.create(
|
105
|
+
:key => "backups/#{filename}",
|
106
|
+
:body => open(filename),
|
107
|
+
:public => true
|
108
|
+
)
|
109
|
+
end
|
110
|
+
|
111
|
+
def HerokuMongoBackup::s3_download(directory, filename)
|
112
|
+
file = directory.files.get("backups/#{filename}")
|
113
|
+
return file.body
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
else
|
122
|
+
logging = Logger.new(STDOUT)
|
123
|
+
logging.error "\n\nheroku-mongo-backup: Please include 's3', 'aws/s3' or 'fog' gem in applications Gemfile for uploading backup to S3 bucket. (ignore this if using FTP)\n\n"
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
|
@@ -13,7 +13,7 @@ namespace :mongo do
|
|
13
13
|
if ENV['FILE']
|
14
14
|
HerokuMongoBackup::Backup.new.restore ENV['FILE']
|
15
15
|
else
|
16
|
-
puts "Please provide backup file to restore from.
|
16
|
+
puts "Please provide backup file to restore from, format: rake mongo:restore FILE=<backup-file.gz>"
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: heroku-mongo-backup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,8 +13,24 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2012-
|
17
|
-
dependencies:
|
16
|
+
date: 2012-10-02 00:00:00.000000000 Z
|
17
|
+
dependencies:
|
18
|
+
- !ruby/object:Gem::Dependency
|
19
|
+
name: mongo
|
20
|
+
requirement: !ruby/object:Gem::Requirement
|
21
|
+
none: false
|
22
|
+
requirements:
|
23
|
+
- - ! '>='
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '0'
|
26
|
+
type: :runtime
|
27
|
+
prerelease: false
|
28
|
+
version_requirements: !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
18
34
|
description: Rake task for backing up mongo database on heroku and push it to S3 or
|
19
35
|
FTP. Library can be used as rake task or be easily integrated into daily cron job.
|
20
36
|
email: santyor@gmail.com
|
@@ -22,6 +38,10 @@ executables: []
|
|
22
38
|
extensions: []
|
23
39
|
extra_rdoc_files: []
|
24
40
|
files:
|
41
|
+
- .gitignore
|
42
|
+
- README.md
|
43
|
+
- Rakefile
|
44
|
+
- heroku-mongo-backup.gemspec
|
25
45
|
- lib/heroku-mongo-backup.rb
|
26
46
|
- lib/s3_helpers.rb
|
27
47
|
- lib/tasks/heroku_mongo_backup.rake
|