brightbox-server-tools 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +619 -0
- data/Rakefile +23 -0
- data/bin/railsapp-apache +139 -0
- data/bin/railsapp-logrotate +76 -0
- data/bin/railsapp-mongrel +78 -0
- data/bin/railsapp-monit +133 -0
- data/bin/railsapp-nginx +85 -0
- data/brightbox-gemspec.rb +46 -0
- data/lib/brightbox/version.rb +3 -0
- data/lib/brightbox/webserver-common.rb +153 -0
- metadata +67 -0
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rake/gempackagetask'
|
2
|
+
require "brightbox-gemspec.rb"
|
3
|
+
|
4
|
+
namespace :client do
|
5
|
+
Rake::GemPackageTask.new(@client).define
|
6
|
+
|
7
|
+
task :default => [:reinstall, :clobber_package]
|
8
|
+
|
9
|
+
desc "Reinstall the client gem locally"
|
10
|
+
task :reinstall => [:repackage] do
|
11
|
+
sh %Q{sudo gem uninstall -x -v #{@client.version} #{@client.name} }
|
12
|
+
sh %q{sudo gem install pkg/*.gem}
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
namespace :server do
|
18
|
+
Rake::GemPackageTask.new(@server).define
|
19
|
+
end
|
20
|
+
|
21
|
+
task :clobber_package => "client:clobber_package"
|
22
|
+
task :package => ["client:package", "server:package"]
|
23
|
+
task :repackage => ["client:repackage", "server:package"]
|
data/bin/railsapp-apache
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Brightbox - Easy Ruby Web Application Deployment
|
3
|
+
# Copyright (C) 2008, Neil Wilson, Brightbox Systems
|
4
|
+
#
|
5
|
+
# This file is part of the Brightbox deployment system
|
6
|
+
#
|
7
|
+
# Brightbox gem is free software: you can redistribute it and/or modify it
|
8
|
+
# under the terms of the GNU Affero General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License,
|
10
|
+
# or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
# Affero General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Affero General
|
18
|
+
# Public License along with this program. If not, see
|
19
|
+
# <http://www.gnu.org/licenses/>.
|
20
|
+
#
|
21
|
+
WEBSERVER="apache2"
|
22
|
+
require "brightbox/webserver-common"
|
23
|
+
|
24
|
+
def ssl_certificate_key
|
25
|
+
if @key_file
|
26
|
+
" SSLCertificateKeyFile #{key_file}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def http_config
|
31
|
+
%Q{
|
32
|
+
#{config_time_stamp}
|
33
|
+
<VirtualHost *:80>
|
34
|
+
ServerName #{@domain}
|
35
|
+
ServerAlias #{local_app_alias} #{@aliases}
|
36
|
+
DocumentRoot #{@webroot}
|
37
|
+
|
38
|
+
<Directory "#{@webroot}">
|
39
|
+
Options FollowSymLinks
|
40
|
+
AllowOverride None
|
41
|
+
Order allow,deny
|
42
|
+
Allow from all
|
43
|
+
</Directory>
|
44
|
+
|
45
|
+
# Configure mongrel_cluster
|
46
|
+
<Proxy balancer://mongrel_cluster>
|
47
|
+
#{balancer_members}
|
48
|
+
</Proxy>
|
49
|
+
|
50
|
+
ErrorLog /var/log/web/#{@application}.err
|
51
|
+
CustomLog /var/log/web/#{@application}.log combined
|
52
|
+
|
53
|
+
# Rails specific rewrite rules
|
54
|
+
Include /etc/apache2/brightbox-common
|
55
|
+
|
56
|
+
# Add any access limit directives here
|
57
|
+
<Location />
|
58
|
+
Allow from all
|
59
|
+
</Location>
|
60
|
+
</VirtualHost>
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def https_config
|
65
|
+
%Q{
|
66
|
+
#{config_time_stamp}
|
67
|
+
<VirtualHost _default_:443>
|
68
|
+
SSLEngine On
|
69
|
+
SSLCertificateFile #{@certificate_file}
|
70
|
+
#{ssl_certificate_key}
|
71
|
+
RequestHeader set X_FORWARDED_PROTO "https"
|
72
|
+
ServerName #{@domain}
|
73
|
+
ServerAlias #{local_app_alias} #{@aliases}
|
74
|
+
DocumentRoot #{@webroot}
|
75
|
+
|
76
|
+
<Directory "#{@webroot}">
|
77
|
+
Options FollowSymLinks
|
78
|
+
AllowOverride None
|
79
|
+
Order allow,deny
|
80
|
+
Allow from all
|
81
|
+
</Directory>
|
82
|
+
|
83
|
+
# Configure mongrel_cluster
|
84
|
+
<Proxy balancer://mongrel_cluster>
|
85
|
+
#{balancer_members}
|
86
|
+
</Proxy>
|
87
|
+
|
88
|
+
ErrorLog /var/log/web/#{@application}.err
|
89
|
+
CustomLog /var/log/web/#{@application}.log combined
|
90
|
+
|
91
|
+
# Rails specific rewrite rules
|
92
|
+
Include /etc/apache2/brightbox-common
|
93
|
+
|
94
|
+
# Add any access limit directives here
|
95
|
+
<Location />
|
96
|
+
Allow from all
|
97
|
+
</Location>
|
98
|
+
</VirtualHost>
|
99
|
+
}
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
def activate_modules(modules)
|
104
|
+
modules.each do |mod|
|
105
|
+
system %Q{/usr/sbin/a2enmod "#{mod}"}
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def configure_ports
|
110
|
+
File.open("/etc/apache2/ports.conf", "w") do |f|
|
111
|
+
f.puts "Listen 80"
|
112
|
+
f.puts "Listen 443" if File.file?("/etc/apache2/sites-enabled/rails-default-ssl")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def balancer_members
|
117
|
+
(@port..@port+@mongrels-1).collect do |i|
|
118
|
+
" BalancerMember http://#{@mongrelhost}:#{i} retry=5"
|
119
|
+
end.join("\n")
|
120
|
+
end
|
121
|
+
|
122
|
+
#MAIN PROGRAM
|
123
|
+
@apache_http_modules = %w(proxy_balancer proxy_http rewrite)
|
124
|
+
@apache_https_modules = %w(ssl headers)
|
125
|
+
|
126
|
+
#Create a normal HTTP config
|
127
|
+
@config=http_config
|
128
|
+
configure_site(@application)
|
129
|
+
activate_modules(@apache_http_modules)
|
130
|
+
|
131
|
+
#Create an SSL site if requested
|
132
|
+
if @certificate
|
133
|
+
@config=https_config
|
134
|
+
configure_site("default-ssl")
|
135
|
+
activate_modules(@apache_https_modules)
|
136
|
+
end
|
137
|
+
|
138
|
+
# Make apache listen on the right ports
|
139
|
+
configure_ports
|
@@ -0,0 +1,76 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Brightbox - Easy Ruby Web Application Deployment
|
3
|
+
# Copyright (C) 2008, Neil Wilson, Brightbox Systems
|
4
|
+
#
|
5
|
+
# This file is part of the Brightbox deployment system
|
6
|
+
#
|
7
|
+
# Brightbox gem is free software: you can redistribute it and/or modify it
|
8
|
+
# under the terms of the GNU Affero General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License,
|
10
|
+
# or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
# Affero General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Affero General
|
18
|
+
# Public License along with this program. If not, see
|
19
|
+
# <http://www.gnu.org/licenses/>.
|
20
|
+
#
|
21
|
+
|
22
|
+
require 'rubygems'
|
23
|
+
require 'optparse'
|
24
|
+
require 'erb'
|
25
|
+
require 'fileutils'
|
26
|
+
|
27
|
+
@size = '100M'
|
28
|
+
@keep = '10'
|
29
|
+
|
30
|
+
OptionParser.new do |opts|
|
31
|
+
opts.banner = "brightbox-logrotate creates a logrotate config for a Rails app\n"
|
32
|
+
opts.banner << "Usage: #{$0} [options] [args]"
|
33
|
+
|
34
|
+
opts.on("-nAPPLICATION_NAME", "--name APPLICATION_NAME",
|
35
|
+
"Name of application (a short useful name for the app such as 'myforum')"
|
36
|
+
) { |value| @application = value }
|
37
|
+
opts.on("-lLOG_DIR", "--logdir LOG_DIR",
|
38
|
+
"Full path to the directory containing the rails logs (e.g: /home/rails/myforum/current/log)"
|
39
|
+
) { |value| @logdir = value }
|
40
|
+
opts.on("-sMAX_LOG_SIZE", "--size MAX_LOG_SIZE",
|
41
|
+
"When the current log file reaches this size, rotate it (e.g: 100M, 1G). Default: #{@size}"
|
42
|
+
) { |value| @size = value }
|
43
|
+
opts.on("-kPERIOD_TO_KEEP", "--keep PERIOD_TO_KEEP",
|
44
|
+
"Number of previous compressed logs to keep (default: #{@keep})"
|
45
|
+
) { |value| @keep = value }
|
46
|
+
|
47
|
+
if ARGV.empty?
|
48
|
+
puts opts
|
49
|
+
exit 1
|
50
|
+
else
|
51
|
+
opts.parse!(ARGV)
|
52
|
+
if @logdir.nil? or @application.nil?
|
53
|
+
puts "required option missing"
|
54
|
+
exit 1
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
TEMPLATE = <<EOT
|
61
|
+
# Created by brightbox-logrotate at <%= Time.now %>
|
62
|
+
<%= @logdir %>/*.log {
|
63
|
+
compress
|
64
|
+
size <%= @size %>
|
65
|
+
rotate <%= @keep %>
|
66
|
+
missingok
|
67
|
+
compress
|
68
|
+
copytruncate
|
69
|
+
}
|
70
|
+
EOT
|
71
|
+
|
72
|
+
template = ERB.new(TEMPLATE)
|
73
|
+
config = template.result
|
74
|
+
filename = "/etc/logrotate.d/rails-#{@application}"
|
75
|
+
|
76
|
+
File.open(filename, "w") { |f| f.write config }
|
@@ -0,0 +1,78 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Brightbox - Easy Ruby Web Application Deployment
|
3
|
+
# Copyright (C) 2008, Neil Wilson, Brightbox Systems
|
4
|
+
#
|
5
|
+
# This file is part of the Brightbox deployment system
|
6
|
+
#
|
7
|
+
# Brightbox gem is free software: you can redistribute it and/or modify it
|
8
|
+
# under the terms of the GNU Affero General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License,
|
10
|
+
# or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
# Affero General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Affero General
|
18
|
+
# Public License along with this program. If not, see
|
19
|
+
# <http://www.gnu.org/licenses/>.
|
20
|
+
#
|
21
|
+
|
22
|
+
require 'rubygems'
|
23
|
+
require 'optparse'
|
24
|
+
require 'fileutils'
|
25
|
+
require 'erb'
|
26
|
+
|
27
|
+
@mongrelhost = "127.0.0.1"
|
28
|
+
@mongrels = 2
|
29
|
+
@railsenv = "production"
|
30
|
+
@pidfile = "log/mongrel.pid"
|
31
|
+
|
32
|
+
def has_required_options?
|
33
|
+
[@application, @config, @pidfile, @port, @mongrels, @railsenv, @railsroot, @mongrelhost].all?
|
34
|
+
end
|
35
|
+
|
36
|
+
OptionParser.new do |opts|
|
37
|
+
opts.banner = "brightbox-mongrel creates a Mongrel config for a Rails app\n"
|
38
|
+
opts.banner << "Usage: #{$0} [options] [args]"
|
39
|
+
|
40
|
+
opts.on("-n", "--name APPLICATION_NAME",
|
41
|
+
"Name of application (a short useful name for the app such as: myforum)"
|
42
|
+
) { |value| @application = value }
|
43
|
+
opts.on("-r", "--railsroot RAILS_ROOT",
|
44
|
+
"Full path to rails root (e.g: /home/rails/myforum/current)"
|
45
|
+
) { |value| @railsroot = value }
|
46
|
+
opts.on("-C", "--config MONGREL_CONFIG_FILE",
|
47
|
+
"Location of this application's mongrel config file"
|
48
|
+
) { |value| @config = value }
|
49
|
+
opts.on("-e", "--railsenv RAILS_ENV",
|
50
|
+
"rails environment (default: #{@railsenv})"
|
51
|
+
) { |value| @railsenv = value }
|
52
|
+
opts.on("-p", "--port MONGREL_PORT",
|
53
|
+
"Port of the first mongrel service (e.g: 9200)"
|
54
|
+
) { |value| @port = value.to_i }
|
55
|
+
opts.on("-s", "--servers MONGRELS",
|
56
|
+
"Number of mongrel servers running (default: #{@mongrels})"
|
57
|
+
) { |value| @mongrels = value.to_i }
|
58
|
+
opts.on("-h", "--mongrelhost MONGREL_HOST",
|
59
|
+
"IP/host where mongrel is running (default: #{@mongrelhost})"
|
60
|
+
) { |value| @mongrelhost = value }
|
61
|
+
opts.on("-P", "--pidfile MONGREL_PID_FILE",
|
62
|
+
"Name of Mongrel PID file template (default: #{@pidfile})"
|
63
|
+
) { |value| @pidfile = value }
|
64
|
+
|
65
|
+
begin
|
66
|
+
opts.parse(ARGV)
|
67
|
+
raise OptionParser::ParseError,
|
68
|
+
"You must supply the required arguments" unless has_required_options?
|
69
|
+
rescue OptionParser::ParseError => e
|
70
|
+
warn e.message
|
71
|
+
puts opts
|
72
|
+
exit 1
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
command = %Q{ mongrel_rails cluster::configure -N #{@mongrels} -p #{@port} -e #{@railsenv} -a #{@mongrelhost} -c #{@railsroot} -P "#{@pidfile}" -C "#{@config}"}
|
77
|
+
puts command
|
78
|
+
exec command
|
data/bin/railsapp-monit
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Brightbox - Easy Ruby Web Application Deployment
|
3
|
+
# Copyright (C) 2008, Neil Wilson, Brightbox Systems
|
4
|
+
#
|
5
|
+
# This file is part of the Brightbox deployment system
|
6
|
+
#
|
7
|
+
# Brightbox gem is free software: you can redistribute it and/or modify it
|
8
|
+
# under the terms of the GNU Affero General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License,
|
10
|
+
# or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
# Affero General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Affero General
|
18
|
+
# Public License along with this program. If not, see
|
19
|
+
# <http://www.gnu.org/licenses/>.
|
20
|
+
#
|
21
|
+
|
22
|
+
require 'rubygems'
|
23
|
+
require 'optparse'
|
24
|
+
require 'fileutils'
|
25
|
+
require 'erb'
|
26
|
+
|
27
|
+
@mongrelhost = "127.0.0.1"
|
28
|
+
@mongrels = 2
|
29
|
+
@railsenv = "production"
|
30
|
+
@railsuser = "rails"
|
31
|
+
@railsgroup = "rails"
|
32
|
+
@pidfile = "log/mongrel.pid"
|
33
|
+
|
34
|
+
def has_required_options?
|
35
|
+
[@railsuser, @railsgroup, @application, @config, @pidfile, @port, @mongrels, @railsenv, @railsroot, @mongrelhost].all?
|
36
|
+
end
|
37
|
+
|
38
|
+
OptionParser.new do |opts|
|
39
|
+
opts.banner = "brightbox-monit creates a Monit config for a Rails app\n"
|
40
|
+
opts.banner << "Usage: #{$0} [options] [args]"
|
41
|
+
|
42
|
+
opts.on("-n", "--name APPLICATION_NAME",
|
43
|
+
"Name of application (a short useful name for the app such as: myforum)"
|
44
|
+
) { |value| @application = value }
|
45
|
+
opts.on("-r", "--railsroot RAILS_ROOT",
|
46
|
+
"Full path to rails root (e.g: /home/rails/myforum/current)"
|
47
|
+
) { |value| @railsroot = value }
|
48
|
+
opts.on("-C", "--config MONGREL_CONFIG_FILE",
|
49
|
+
"Location of this application's mongrel config file"
|
50
|
+
) { |value| @config = value }
|
51
|
+
opts.on("-e", "--railsenv RAILS_ENV",
|
52
|
+
"rails environment (default: #{@railsenv})"
|
53
|
+
) { |value| @railsenv = value }
|
54
|
+
opts.on("-p", "--port MONGREL_PORT",
|
55
|
+
"Port of the first mongrel service (e.g: 9200)"
|
56
|
+
) { |value| @port = value.to_i }
|
57
|
+
opts.on("-s", "--servers MONGRELS",
|
58
|
+
"Number of mongrel servers running (default: #{@mongrels})"
|
59
|
+
) { |value| @mongrels = value.to_i }
|
60
|
+
opts.on("-h", "--mongrelhost MONGREL_HOST",
|
61
|
+
"IP/host where mongrel is running (default: #{@mongrelhost})"
|
62
|
+
) { |value| @mongrelhost = value }
|
63
|
+
opts.on("-u", "--user USERNAME",
|
64
|
+
"The unix username the mongrel process should be started as (default: #{@railsuser})"
|
65
|
+
) { |value| @railsuser = value }
|
66
|
+
opts.on("-g", "--group USERNAME",
|
67
|
+
"The unix group the mongrel process should be started as (default: #{@railsgroup})"
|
68
|
+
) { |value| @railsgroup = value }
|
69
|
+
opts.on("-P", "--pidfile MONGREL_PID_FILE",
|
70
|
+
"Name of Mongrel PID file template (default: #{@pidfile})"
|
71
|
+
) { |value| @pidfile = value }
|
72
|
+
|
73
|
+
begin
|
74
|
+
opts.parse(ARGV)
|
75
|
+
raise OptionParser::ParseError,
|
76
|
+
"You must supply the required arguments" unless has_required_options?
|
77
|
+
rescue OptionParser::ParseError => e
|
78
|
+
warn e.message
|
79
|
+
puts opts
|
80
|
+
exit 1
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def process_pid_file
|
85
|
+
@pid_file_ext = File.extname(@pidfile)
|
86
|
+
@pid_file_base = File.basename(@pidfile, @pid_file_ext)
|
87
|
+
@pid_file_dir = File.dirname(@pidfile)
|
88
|
+
end
|
89
|
+
|
90
|
+
def port_pid_file(port)
|
91
|
+
pid_file = [@pid_file_base, port].join(".") + @pid_file_ext
|
92
|
+
File.join(@pid_file_dir, pid_file)
|
93
|
+
end
|
94
|
+
|
95
|
+
def mongrel_ports
|
96
|
+
@port..(@port + @mongrels - 1)
|
97
|
+
end
|
98
|
+
|
99
|
+
process_pid_file
|
100
|
+
@mongrel_instances = mongrel_ports.collect do |port|
|
101
|
+
[port, File.join(@railsroot, port_pid_file(port))]
|
102
|
+
end
|
103
|
+
|
104
|
+
TEMPLATE = <<EOT
|
105
|
+
# Created by brightbox-monit at <%= Time.now %>
|
106
|
+
<% @mongrel_instances.each do |port, pidfile| %>
|
107
|
+
check process mongrel_<%= @application %>_<%= port %> with pidfile <%= pidfile %>
|
108
|
+
group <%= @application %>
|
109
|
+
start program = "/usr/bin/mongrel_rails cluster::start -C <%= @config %> --clean --only <%= port %>"
|
110
|
+
as uid #{@railsuser} and gid #{@railsgroup}
|
111
|
+
stop program = "/usr/bin/mongrel_rails cluster::stop -C <%= @config %> --clean --only <%= port %>"
|
112
|
+
as uid #{@railsuser} and gid #{@railsgroup}
|
113
|
+
|
114
|
+
if failed host <%= @mongrelhost %> port <%= port %> protocol http
|
115
|
+
with timeout 30 seconds
|
116
|
+
then restart
|
117
|
+
|
118
|
+
if totalmem > 110 Mb for 3 cycles then restart
|
119
|
+
if cpu > 80% for 5 cycles then restart
|
120
|
+
#if loadavg(5min) greater than 10 for 8 cycles then restart
|
121
|
+
if 20 restarts within 20 cycles then timeout
|
122
|
+
<% end %>
|
123
|
+
EOT
|
124
|
+
|
125
|
+
template = ERB.new(TEMPLATE)
|
126
|
+
config = template.result
|
127
|
+
filename = "/etc/monit/conf.d/rails-#{@application}.monitrc"
|
128
|
+
if File.exists?(filename)
|
129
|
+
FileUtils.mkdir_p("/etc/monit/archived-configs")
|
130
|
+
FileUtils.cp filename, "/etc/monit/archived-configs/rails-#{@application}.monitrc.#{Time.now.strftime('%y%m%d%H%M%S')}"
|
131
|
+
end
|
132
|
+
|
133
|
+
File.open(filename, "w") { |f| f.write config }
|