brightbox-server-tools 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 }
|