brightbox-server-tools 2.0.3 → 2.1.2

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.
@@ -27,21 +27,24 @@ def ssl_certificate_key
27
27
  end
28
28
  end
29
29
 
30
- def http_config
31
- %Q{
32
- #{config_time_stamp}
33
- <VirtualHost *:80>
30
+ def standard_server_contents
31
+ %Q@
34
32
  ServerName #{@domain}
35
33
  ServerAlias #{local_app_alias} #{@aliases}
36
34
  DocumentRoot #{@webroot}
37
35
 
38
36
  <Directory "#{@webroot}">
37
+ Header set Cache-Control "max-age=#{@maxage}"
39
38
  Options FollowSymLinks
40
39
  AllowOverride None
41
40
  Order allow,deny
42
41
  Allow from all
43
42
  </Directory>
44
43
 
44
+ <Directory "#{@webroot}/system">
45
+ Header set Cache-Control "no-cache"
46
+ </Directory>
47
+
45
48
  # Configure mongrel_cluster
46
49
  <Proxy balancer://mongrel_cluster>
47
50
  #{balancer_members}
@@ -51,58 +54,68 @@ def http_config
51
54
  CustomLog /var/log/web/#{@application}.log combined
52
55
 
53
56
  # Rails specific rewrite rules
54
- Include /etc/apache2/brightbox-common
57
+ RewriteEngine On
58
+
59
+ # Check for maintenance file and redirect all requests
60
+ ErrorDocument 503 /system/maintenance.html
61
+ RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
62
+ RewriteCond %{SCRIPT_FILENAME} !^/system
63
+ RewriteRule ^.*$ /system/maintenance.html [R=503,L]
64
+
65
+ # Rewrite index to check for static
66
+ RewriteRule ^/$ /index.html [QSA]
67
+
68
+ # Rewrite to check for Rails cached page
69
+ RewriteRule ^([^.]+)$ $1.html [QSA]
70
+
71
+ # Redirect all non-static requests to cluster
72
+ RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f [OR]
73
+ RewriteCond %{REQUEST_METHOD} !^(GET|HEAD)
74
+ RewriteRule ^/(.*)$ balancer://mongrel_cluster%{REQUEST_URI} [P,QSA,L]
75
+
76
+ # Deflate
77
+ AddOutputFilterByType DEFLATE text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript
78
+ BrowserMatch ^Mozilla/4 gzip-only-text/html
79
+ BrowserMatch ^Mozilla/4\.0[678] no-gzip
80
+ BrowserMatch \\bMSIE !no-gzip !gzip-only-text/html
55
81
 
56
82
  # Add any access limit directives here
57
83
  <Location />
58
84
  Allow from all
59
85
  </Location>
86
+ @
87
+ end
88
+
89
+
90
+ def http_config
91
+ %Q@
92
+ #{config_time_stamp}
93
+ <VirtualHost *:80>
94
+ #{standard_server_contents}
60
95
  </VirtualHost>
61
- }
96
+ @
62
97
  end
63
98
 
64
99
  def https_config
65
- %Q{
100
+ %Q@
66
101
  #{config_time_stamp}
67
102
  <VirtualHost _default_:443>
68
103
  SSLEngine On
69
104
  SSLCertificateFile #{@certificate_file}
70
105
  #{ssl_certificate_key}
71
106
  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>
107
+ #{standard_server_contents}
98
108
  </VirtualHost>
99
- }
109
+ @
100
110
  end
101
111
 
102
112
 
103
113
  def activate_modules(modules)
104
- modules.each do |mod|
105
- system %Q{/usr/sbin/a2enmod "#{mod}"}
114
+ enmod="/usr/sbin/a2enmod"
115
+ if File.executable?(enmod)
116
+ modules.each do |mod|
117
+ system %Q{#{enmod} "#{mod}"}
118
+ end
106
119
  end
107
120
  end
108
121
 
@@ -114,14 +127,16 @@ def configure_ports
114
127
  end
115
128
 
116
129
  def balancer_members
117
- (@port..@port+@mongrels-1).collect do |i|
118
- " BalancerMember http://#{@mongrelhost}:#{i} retry=5"
130
+ @mongrelhost.split(",").collect do |host|
131
+ (@port..@port+@mongrels-1).collect do |i|
132
+ " BalancerMember http://#{host}:#{i} retry=5"
133
+ end
119
134
  end.join("\n")
120
135
  end
121
136
 
122
137
  #MAIN PROGRAM
123
- @apache_http_modules = %w(proxy_balancer proxy_http rewrite)
124
- @apache_https_modules = %w(ssl headers)
138
+ @apache_http_modules = %w(proxy_balancer proxy_http rewrite headers deflate)
139
+ @apache_https_modules = %w(ssl)
125
140
 
126
141
  #Create a normal HTTP config
127
142
  @config=http_config
@@ -21,56 +21,58 @@
21
21
 
22
22
  require 'rubygems'
23
23
  require 'optparse'
24
- require 'erb'
25
24
  require 'fileutils'
25
+ require 'brightbox/version'
26
26
 
27
27
  @size = '100M'
28
28
  @keep = '10'
29
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]"
30
+ def has_required_options?
31
+ [@application, @logdir].all?
32
+ end
33
+
34
+ @opts = OptionParser.new do |opts|
35
+ opts.banner = "#{opts.program_name} creates a logrotate config for a Rails app\n#{opts.banner}"
33
36
 
34
37
  opts.on("-nAPPLICATION_NAME", "--name APPLICATION_NAME",
35
- "Name of application (a short useful name for the app such as 'myforum')"
38
+ "Name of application (a short useful name","for the app such as 'myforum')"
36
39
  ) { |value| @application = value }
37
40
  opts.on("-lLOG_DIR", "--logdir LOG_DIR",
38
- "Full path to the directory containing the rails logs (e.g: /home/rails/myforum/current/log)"
41
+ "Full path to the directory containing the","rails logs","(e.g: /home/rails/myforum/current/log)"
39
42
  ) { |value| @logdir = value }
40
43
  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}"
44
+ "When the current log file reaches this","size, rotate it (e.g: 100M, 1G).","Default: #{@size}"
42
45
  ) { |value| @size = value }
43
46
  opts.on("-kPERIOD_TO_KEEP", "--keep PERIOD_TO_KEEP",
44
- "Number of previous compressed logs to keep (default: #{@keep})"
47
+ "Number of previous compressed logs to keep","(default: #{@keep})"
45
48
  ) { |value| @keep = value }
46
49
 
47
- if ARGV.empty?
50
+ begin
51
+ opts.parse!(ARGV)
52
+ raise OptionParser::ParseError,
53
+ "You must supply the required arguments" unless has_required_options?
54
+ rescue OptionParser::ParseError => e
55
+ warn e.message
48
56
  puts opts
49
57
  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
58
  end
57
59
  end
58
60
 
59
61
 
60
- TEMPLATE = <<EOT
61
- # Created by brightbox-logrotate at <%= Time.now %>
62
- <%= @logdir %>/*.log {
62
+ def logrotate_config
63
+ %Q{
64
+ # Created by #{@opts.program_name} at #{Time.now}
65
+ #{@logdir}/*.log {
63
66
  compress
64
- size <%= @size %>
65
- rotate <%= @keep %>
67
+ size #{@size}
68
+ rotate #{@keep}
66
69
  missingok
67
70
  compress
68
71
  copytruncate
69
72
  }
70
- EOT
73
+ }
74
+ end
71
75
 
72
- template = ERB.new(TEMPLATE)
73
- config = template.result
74
76
  filename = "/etc/logrotate.d/rails-#{@application}"
75
77
 
76
- File.open(filename, "w") { |f| f.write config }
78
+ File.open(filename, "w") { |f| f.write logrotate_config }
@@ -0,0 +1,59 @@
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
+ begin
23
+ require 'rubygems'
24
+ rescue LoadError
25
+ # no rubygems to load, so we fail silently
26
+ end
27
+
28
+ require 'optparse'
29
+ require 'brightbox/version'
30
+ require 'brightbox/maintenance'
31
+
32
+
33
+ opts = OptionParser.new do |opts|
34
+ opts.banner = "Create the default maintenance site\n"
35
+ opts.banner << "Usage: #{opts.program_name} <directory_name>\n\n"
36
+
37
+ begin
38
+ opts.parse!(ARGV)
39
+ rescue OptionParser::ParseError => e
40
+ warn e.message
41
+ puts opts
42
+ exit 1
43
+ end
44
+ end
45
+
46
+
47
+ abort "Please specify the directory where the maintenance site should live e.g. '#{@progname} .'" if ARGV.empty?
48
+ abort "Too many arguments; please provide a single directory name." unless ARGV.length == 1
49
+ abort "'#{ARGV.first}' does not exist." unless File.exists?(ARGV.first)
50
+ abort "'#{ARGV.first}' is not a directory." unless File.directory?(ARGV.first)
51
+
52
+
53
+ system_dir = ARGV.shift
54
+ if File.exists?(File.join(system_dir, "index.html"))
55
+ puts "Existing site detected - leaving alone"
56
+ else
57
+ puts "Deploying default maintenance site"
58
+ deploy_maintenance_page(system_dir)
59
+ end
@@ -22,44 +22,46 @@
22
22
  require 'rubygems'
23
23
  require 'optparse'
24
24
  require 'fileutils'
25
+ require 'brightbox/version'
25
26
  require 'erb'
26
27
 
27
28
  @mongrelhost = "127.0.0.1"
28
29
  @mongrels = 2
30
+ @port = 9200
29
31
  @railsenv = "production"
30
32
  @pidfile = "log/mongrel.pid"
31
33
 
32
34
  def has_required_options?
33
- [@application, @config, @pidfile, @port, @mongrels, @railsenv, @railsroot, @mongrelhost].all?
35
+ [@application, @config, @railsroot].all?
34
36
  end
35
37
 
36
38
  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
+ opts.banner = "#{opts.program_name} creates a Mongrel config for a Rails app\n#{opts.banner}"
39
40
 
40
41
  opts.on("-n", "--name APPLICATION_NAME",
41
- "Name of application (a short useful name for the app such as: myforum)"
42
+ "Name of application (a short useful name",
43
+ "for the app such as: myforum)"
42
44
  ) { |value| @application = value }
43
45
  opts.on("-r", "--railsroot RAILS_ROOT",
44
- "Full path to rails root (e.g: /home/rails/myforum/current)"
46
+ "Full path to rails root","(e.g: /home/rails/myforum/current)"
45
47
  ) { |value| @railsroot = value }
46
48
  opts.on("-C", "--config MONGREL_CONFIG_FILE",
47
- "Location of this application's mongrel config file"
49
+ "Location of this application's mongrel","config file"
48
50
  ) { |value| @config = value }
49
51
  opts.on("-e", "--railsenv RAILS_ENV",
50
52
  "rails environment (default: #{@railsenv})"
51
53
  ) { |value| @railsenv = value }
52
54
  opts.on("-p", "--port MONGREL_PORT",
53
- "Port of the first mongrel service (e.g: 9200)"
55
+ "Port of the first mongrel service","(default: #{@port})"
54
56
  ) { |value| @port = value.to_i }
55
57
  opts.on("-s", "--servers MONGRELS",
56
- "Number of mongrel servers running (default: #{@mongrels})"
58
+ "Number of mongrel servers running","(default: #{@mongrels})"
57
59
  ) { |value| @mongrels = value.to_i }
58
60
  opts.on("-h", "--mongrelhost MONGREL_HOST",
59
- "IP/host where mongrel is running (default: #{@mongrelhost})"
61
+ "IP/host where mongrel is running","(default: #{@mongrelhost})"
60
62
  ) { |value| @mongrelhost = value }
61
63
  opts.on("-P", "--pidfile MONGREL_PID_FILE",
62
- "Name of Mongrel PID file template (default: #{@pidfile})"
64
+ "Name of Mongrel PID file template","(default: #{@pidfile})"
63
65
  ) { |value| @pidfile = value }
64
66
 
65
67
  begin
@@ -22,7 +22,8 @@
22
22
  require 'rubygems'
23
23
  require 'optparse'
24
24
  require 'fileutils'
25
- require 'erb'
25
+ require 'brightbox/version'
26
+ require 'uri'
26
27
 
27
28
  @mongrelhost = "127.0.0.1"
28
29
  @mongrels = 2
@@ -30,45 +31,59 @@ require 'erb'
30
31
  @railsuser = "rails"
31
32
  @railsgroup = "rails"
32
33
  @pidfile = "log/mongrel.pid"
34
+ @port = 9200
35
+ @check_url = "http://localhost"
36
+ @max_memory = 110
37
+ @max_cpu = 80
33
38
 
34
39
  def has_required_options?
35
- [@railsuser, @railsgroup, @application, @config, @pidfile, @port, @mongrels, @railsenv, @railsroot, @mongrelhost].all?
40
+ [@application, @config, @port, @railsroot].all?
36
41
  end
37
42
 
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]"
43
+ @opts = OptionParser.new do |opts|
44
+ opts.banner = "#{opts.program_name} creates a Monit config for a Rails app\n#{opts.banner}"
41
45
 
42
46
  opts.on("-n", "--name APPLICATION_NAME",
43
- "Name of application (a short useful name for the app such as: myforum)"
47
+ "Name of application (a short useful name",
48
+ "for the app such as: myforum)"
44
49
  ) { |value| @application = value }
45
50
  opts.on("-r", "--railsroot RAILS_ROOT",
46
- "Full path to rails root (e.g: /home/rails/myforum/current)"
51
+ "Full path to rails root",
52
+ "(e.g: /home/rails/myforum/current)"
47
53
  ) { |value| @railsroot = value }
48
54
  opts.on("-C", "--config MONGREL_CONFIG_FILE",
49
- "Location of this application's mongrel config file"
55
+ "Location of this application's mongrel","config file"
50
56
  ) { |value| @config = value }
51
57
  opts.on("-e", "--railsenv RAILS_ENV",
52
58
  "rails environment (default: #{@railsenv})"
53
59
  ) { |value| @railsenv = value }
54
60
  opts.on("-p", "--port MONGREL_PORT",
55
- "Port of the first mongrel service (e.g: 9200)"
61
+ "Port of the first mongrel service","(default: #{@port})"
56
62
  ) { |value| @port = value.to_i }
57
63
  opts.on("-s", "--servers MONGRELS",
58
- "Number of mongrel servers running (default: #{@mongrels})"
64
+ "Number of mongrel servers running","(default: #{@mongrels})"
59
65
  ) { |value| @mongrels = value.to_i }
60
66
  opts.on("-h", "--mongrelhost MONGREL_HOST",
61
- "IP/host where mongrel is running (default: #{@mongrelhost})"
67
+ "IP/host where mongrel is running","(default: #{@mongrelhost})"
62
68
  ) { |value| @mongrelhost = value }
63
69
  opts.on("-u", "--user USERNAME",
64
- "The unix username the mongrel process should be started as (default: #{@railsuser})"
70
+ "The unix username the mongrel process","should be started as (default: #{@railsuser})"
65
71
  ) { |value| @railsuser = value }
66
72
  opts.on("-g", "--group USERNAME",
67
- "The unix group the mongrel process should be started as (default: #{@railsgroup})"
73
+ "The unix group the mongrel process should","be started as (default: #{@railsgroup})"
68
74
  ) { |value| @railsgroup = value }
69
75
  opts.on("-P", "--pidfile MONGREL_PID_FILE",
70
- "Name of Mongrel PID file template (default: #{@pidfile})"
76
+ "Name of Mongrel PID file template","(default: #{@pidfile})"
71
77
  ) { |value| @pidfile = value }
78
+ opts.on("-U", "--checkurl URL_TO_CHECK",
79
+ "URL to check to make sure application is","live (default: #{@check_url})"
80
+ ) { |value| @check_url = value }
81
+ opts.on("-m", "--maxmemory MAX_MONGREL_MEM",
82
+ "Amount of memory mongrel can use before","being killed (default: #{@max_memory}Mb)"
83
+ ) { |value| @max_memory = value }
84
+ opts.on("-c", "--maxcpu MAX_MONGREL_CPU",
85
+ "Amount of cpu mongrel can use before","being killed (default: #{@max_cpu}%)"
86
+ ) { |value| @max_cpu = value }
72
87
 
73
88
  begin
74
89
  opts.parse(ARGV)
@@ -96,38 +111,52 @@ def mongrel_ports
96
111
  @port..(@port + @mongrels - 1)
97
112
  end
98
113
 
114
+ def updated_url(current_url, new_port)
115
+ url_holder = URI.parse(current_url)
116
+ url_holder.port = new_port
117
+ url_holder.to_s
118
+ end
119
+
99
120
  process_pid_file
100
121
  @mongrel_instances = mongrel_ports.collect do |port|
101
122
  [port, File.join(@railsroot, port_pid_file(port))]
102
123
  end
103
124
 
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 %>"
125
+ def config_time_stamp
126
+ "# Created by #{@opts.program_name} at #{Time.now}\n"
127
+ end
128
+
129
+ def mongrel_config(port, pidfile)
130
+ %Q{
131
+ check process mongrel_#{@application}_#{port} with pidfile #{pidfile}
132
+ group #{@application}
133
+ start program = "/usr/bin/mongrel_rails cluster::start -C #{@config} --clean --only #{port}"
110
134
  as uid #{@railsuser} and gid #{@railsgroup}
111
- stop program = "/usr/bin/mongrel_rails cluster::stop -C <%= @config %> --clean --only <%= port %>"
135
+ stop program = "/usr/bin/mongrel_rails cluster::stop -C #{@config} --clean --only #{port}"
112
136
  as uid #{@railsuser} and gid #{@railsgroup}
113
137
 
114
- if failed host <%= @mongrelhost %> port <%= port %> protocol http
115
- with timeout 30 seconds
138
+ if failed url #{updated_url(@check_url, port)}
139
+ with timeout 15 seconds
140
+ for 2 cycles
116
141
  then restart
117
142
 
118
- if mem > 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
143
+ if mem > #{@max_memory} Mb for 3 cycles then restart
144
+ if cpu > #{@max_cpu}% for 5 cycles then restart
121
145
  if 20 restarts within 20 cycles then timeout
122
- <% end %>
123
- EOT
146
+ }
147
+ end
148
+
149
+ def monit_config
150
+ config_time_stamp +
151
+ @mongrel_instances.collect do |port, pidfile|
152
+ mongrel_config(port,pidfile)
153
+ end.join("\n")
154
+ end
124
155
 
125
- template = ERB.new(TEMPLATE)
126
- config = template.result
127
156
  filename = "/etc/monit/conf.d/rails-#{@application}.monitrc"
128
157
  if File.exists?(filename)
129
158
  FileUtils.mkdir_p("/etc/monit/archived-configs")
130
159
  FileUtils.cp filename, "/etc/monit/archived-configs/rails-#{@application}.monitrc.#{Time.now.strftime('%y%m%d%H%M%S')}"
131
160
  end
132
161
 
133
- File.open(filename, "w") { |f| f.write config }
162
+ File.open(filename, "w") { |f| f.write monit_config }
@@ -2,7 +2,7 @@
2
2
  # Brightbox - Easy Ruby Web Application Deployment
3
3
  # Copyright (C) 2008, Neil Wilson, Brightbox Systems
4
4
  #
5
- # This file is part of the Brightbox @application system
5
+ # This file is part of the Brightbox deployment system
6
6
  #
7
7
  # Brightbox gem is free software: you can redistribute it and/or modify it
8
8
  # under the terms of the GNU Affero General Public License as published
@@ -23,36 +23,79 @@
23
23
  WEBSERVER='nginx'
24
24
  require 'brightbox/webserver-common'
25
25
 
26
-
27
- def http_config
26
+ def standard_server_contents
28
27
  <<-EOT
29
- #{config_time_stamp}
30
- upstream #{@application}_mongrels {
31
- fair;
32
- # List of mongrels
33
- #{balancer_members}
34
- }
35
- server {
36
28
  server_name #{@domain} #{local_app_alias} #{@aliases};
37
29
  root #{@webroot};
30
+
31
+ log_not_found off;
32
+ log_format main '$remote_addr $host $remote_user [$time_local] '
33
+ '"$request" $status $body_bytes_sent "$http_referer" '
34
+ '"$http_user_agent" "$http_x_forwarded_for"' ;
38
35
  access_log /var/log/web/#{@application}.log main;
36
+
37
+ client_body_temp_path /var/spool/nginx-client-body 1 2;
38
+ client_max_body_size 32m;
39
+ client_body_buffer_size 32k;
40
+
41
+ tcp_nopush on;
42
+
43
+ gzip_http_version 1.0;
44
+ gzip_comp_level 2;
45
+ gzip_proxied any;
46
+ gzip_min_length 1100;
47
+ gzip_buffers 16 8k;
48
+ gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
49
+ # Some version of IE 6 don't handle compression well on some mime-types, so just disable for them
50
+ gzip_disable "MSIE [1-6].(?!.*SV1)";
51
+ # Set a vary header so downstream proxies don't send cached gzipped content to IE6
52
+ gzip_vary on;
53
+
54
+ # Send along useful info to the mongrels
55
+ proxy_set_header X-Real-IP $remote_addr;
56
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
57
+ proxy_set_header Host $host;
58
+ proxy_set_header X_FORWARDED_PROTO $scheme;
59
+ proxy_redirect false;
60
+ proxy_max_temp_file_size 0;
61
+ proxy_buffering on;
62
+ proxy_buffer_size 4k;
63
+ proxy_buffers 16 32k;
64
+
65
+ fastcgi_buffer_size 4k;
66
+ fastcgi_buffers 16 32k;
39
67
 
40
- # Capistrano maintenance message support
41
- if (-f $document_root/system/maintenance.html) {
42
- rewrite ^(.*)$ /system/maintenance.html last;
43
- break;
68
+ location /system {
69
+ add_header Cache-Control no-cache;
44
70
  }
45
71
 
46
72
  location / {
47
73
  ## General Rails error page stuff
48
74
  error_page 404 /404.html;
49
75
  error_page 422 /422.html;
50
- error_page 500 502 503 504 /500.html;
76
+ error_page 500 /500.html;
77
+ error_page 502 /502.html;
78
+ error_page 504 /504.html;
51
79
  error_page 403 /403.html;
52
80
 
81
+ error_page 503 /system/maintenance.html;
82
+
83
+ # Capistrano maintenance message support
84
+ if (-f $document_root/system/maintenance.html) {
85
+ return 503;
86
+ break;
87
+ }
88
+
89
+ # Send to mongrels if not a read request
90
+ if ($request_method !~ "GET|HEAD") {
91
+ proxy_pass http://#{@application}_mongrels;
92
+ break;
93
+ }
94
+
53
95
  # If the file exists then stop here. Saves 4 more stats and some
54
96
  # rewrites.
55
97
  if (-f $request_filename) {
98
+ expires #{@maxage};
56
99
  break;
57
100
  }
58
101
  # Rails page caching
@@ -66,15 +109,51 @@ server {
66
109
  # then send to the mongrels
67
110
  if (!-f $request_filename) {
68
111
  proxy_pass http://#{@application}_mongrels;
112
+ break;
69
113
  }
70
114
  }
115
+ EOT
116
+ end
117
+
118
+ def ssl_certificate_key
119
+ if @key_file
120
+ " ssl_certificate_key #{key_file};"
121
+ end
122
+ end
123
+
124
+ def http_config
125
+ <<-EOT
126
+ #{config_time_stamp}
127
+ upstream #{@application}_mongrels {
128
+ fair;
129
+ # List of mongrels
130
+ #{balancer_members}
131
+ }
132
+ server {
133
+ listen 80;
134
+ #{standard_server_contents}
135
+ }
136
+ EOT
137
+ end
138
+
139
+ def https_config
140
+ <<-EOT
141
+ #{config_time_stamp}
142
+ server {
143
+ listen 443;
144
+ ssl on;
145
+ ssl_certificate #{@certificate_file};
146
+ #{ssl_certificate_key}
147
+ #{standard_server_contents}
71
148
  }
72
149
  EOT
73
150
  end
74
151
 
75
152
  def balancer_members
76
- (@port..@port+@mongrels-1).collect do |i|
77
- " server #{@mongrelhost}:#{i};"
153
+ @mongrelhost.split(",").collect do |host|
154
+ (@port..@port+@mongrels-1).collect do |i|
155
+ " server #{host}:#{i};"
156
+ end
78
157
  end.join("\n")
79
158
  end
80
159
 
@@ -83,3 +162,10 @@ end
83
162
  #Create a normal HTTP config
84
163
  @config=http_config
85
164
  configure_site(@application)
165
+
166
+ #Create an SSL site if requested
167
+ if @certificate
168
+ @config=https_config
169
+ configure_site("default-ssl")
170
+ end
171
+
@@ -30,7 +30,7 @@ end
30
30
  @server = Gem::Specification.new do |s|
31
31
  add_common(s)
32
32
  s.name = "brightbox-server-tools"
33
- s.files = FileList["LICENSE", "Rakefile", "*.rb", "bin/railsapp-*","{lib,spec}/**/*.rb"].exclude(/recipe/).to_a
33
+ s.files = FileList["LICENSE", "Rakefile", "*.rb", "bin/railsapp-*","lib/**/*.{rb,gz}"].exclude(/recipe/).to_a
34
34
  s.summary = "Brightbox Server configuration scripts"
35
35
  s.executables = FileList["bin/railsapp-*"].sub(/bin\//,'')
36
36
  end
@@ -39,7 +39,7 @@ end
39
39
  add_common(s)
40
40
  s.name = "brightbox"
41
41
  s.files = FileList["LICENSE", "Rakefile", "*.rb", "lib/**/*.rb","bin/brightbox"].exclude("lib/brightbox/webserver-common.rb").to_a
42
- s.add_dependency("capistrano", ">= 2.3")
42
+ s.add_dependency("capistrano", ">= 2.5")
43
43
  s.summary = "Brightbox rails deployment scripts for Capistrano"
44
44
  s.executable = 'brightbox'
45
45
  end
@@ -0,0 +1,24 @@
1
+ # Brightbox - Easy Ruby Web Application Deployment
2
+ # Copyright (C) 2008, Neil Wilson, Brightbox Systems
3
+ #
4
+ # This file is part of the Brightbox deployment system
5
+ #
6
+ # Brightbox gem is free software: you can redistribute it and/or modify it
7
+ # under the terms of the GNU Affero General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License,
9
+ # or (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General
17
+ # Public License along with this program. If not, see
18
+ # <http://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ def deploy_maintenance_page(system_directory)
22
+ maintenance_site = File.join(File.dirname(__FILE__),"maintenance-site.tar.gz")
23
+ system ("tar --directory #{system_directory} --extract --gzip --file #{maintenance_site}")
24
+ end
@@ -1,3 +1,5 @@
1
1
  module Brightbox
2
- VERSION = "2.0.3"
2
+ VERSION = "2.1.2"
3
3
  end
4
+ # Set global scope version so that OptionParser picks it up.
5
+ ::Version = Brightbox::VERSION
@@ -21,16 +21,18 @@
21
21
  require 'rubygems'
22
22
  require 'optparse'
23
23
  require 'fileutils'
24
+ require 'brightbox/version'
24
25
 
25
26
  @mongrelhost = "127.0.0.1"
26
27
  @mongrels = 2
28
+ @port = 9200
27
29
  @aliases = nil
28
30
  @certificate = nil
29
31
  @key_file = nil
30
- @app_name = File.basename $0
32
+ @maxage = 315360000
31
33
 
32
34
  def has_required_options?
33
- [@application, @webroot, @domain, @port].all? &&
35
+ [@application, @webroot, @domain].all? &&
34
36
  (@certificate || @certificate_key.nil?)
35
37
  end
36
38
 
@@ -40,11 +42,11 @@ def certificate_file
40
42
  test_path = File.join('','etc','ssl','certs', cert_base + '.*')
41
43
  candidates = Dir[test_path]
42
44
  if candidates.empty?
43
- abort "#{@app_name}: Unable to find certificate file for #{@cert_base}"
45
+ abort "#{@opts.program_name}: Unable to find certificate file for #{@cert_base}"
44
46
  end
45
47
  result = candidates.pop
46
48
  unless candidates.empty?
47
- abort "#{@app_name}: #{@cert_base} resolves to more than one file. Please be more specific"
49
+ abort "#{@opts.program_name}: #{@cert_base} resolves to more than one file. Please be more specific"
48
50
  end
49
51
  result
50
52
  end
@@ -61,50 +63,62 @@ def key_file
61
63
  return nil if candidates.empty?
62
64
  result = candidates.pop
63
65
  unless candidates.empty?
64
- abort "#{@app_name}: #{key_base} resolves to more than one file. Please be more specific"
66
+ abort "#{@opts.program_name}: #{key_base} resolves to more than one file. Please be more specific"
65
67
  end
66
68
  result
67
69
  end
68
70
 
69
- OptionParser.new do |opts|
70
- opts.banner = "#{@app_name} creates an #{WEBSERVER} config for a Rails app\n"
71
- opts.banner << "Usage: #{@app_name} [options] [args]"
71
+ @opts = OptionParser.new do |opts|
72
+ opts.banner = "#{opts.program_name} creates an #{WEBSERVER} config for a Rails app\n#{opts.banner}"
72
73
 
73
74
  opts.on("-n APPLICATION_NAME", "--name APPLICATION_NAME",
74
- "Name of application (a short useful name for the app such as 'myforum')"
75
+ "Name of application (a short useful",
76
+ "name for the app such as 'myforum')"
75
77
  ) { |value| @application = value }
76
78
 
77
79
  opts.on("-w", "--webroot WEB_ROOT",
78
- "Full path to web root (e.g: /home/rails/myforum/current/public)"
80
+ "Full path to web root",
81
+ "(e.g: /home/rails/myforum/current/public)"
79
82
  ) { |value| @webroot = value }
80
83
 
81
84
  opts.on("-d", "--domain DOMAIN_NAME",
82
- "Domain name for application (e.g: www.example.com)"
85
+ "Domain name for application",
86
+ "(e.g: www.example.com)"
83
87
  ) { |value| @domain = value }
84
88
 
85
89
  opts.on("-a", "--aliases ALIASES",
86
- "Aliases for domain name, comma separated (e.g: www.example.org,www.example.net)"
90
+ "Aliases for domain name, comma separated",
91
+ "(e.g: www.example.org,www.example.net)"
87
92
  ) { |value| @aliases = value.to_s.split(',').join(' ')}
88
93
 
89
94
  opts.on("-p", "--port MONGREL_PORT", Integer,
90
- "Port of the first mongrel service"
95
+ "Port of the first mongrel service",
96
+ "(default: #{@port})"
91
97
  ) { |value| @port = value.to_i }
92
98
 
93
99
  opts.on("-s", "--servers MONGRELS", Integer,
94
- "Number of mongrel servers running (default: #{@mongrels})"
100
+ "Number of mongrel servers running",
101
+ "(default: #{@mongrels})"
95
102
  ) { |value| @mongrels = value.to_i }
96
103
 
97
104
  opts.on("-h", "--mongrelhost MONGREL_HOST",
98
- "ip/host where mongrel is running (default: #{@mongrelhost})"
105
+ "ip/host where mongrel is running",
106
+ "(default: #{@mongrelhost})"
99
107
  ) { |value| @mongrelhost = value }
100
108
 
101
109
  opts.on("-c", "--ssl-cert CERTIFICATE_NAME",
102
- "create an SSL configuration using CERTIFICATE_NAME"
110
+ "create an SSL configuration",
111
+ "using CERTIFICATE_NAME"
103
112
  ) { |value| @certificate = value }
104
113
 
105
114
  opts.on("-k", "--ssl-key KEY_NAME",
106
115
  "Name of private key to use CERTIFICATE"
107
116
  ) { |value| @certificate_key = value }
117
+
118
+ opts.on("-m", "--max-age MAX_AGE",
119
+ "Number of seconds to keep static assets","in cache",
120
+ "(default: #{@maxage})"
121
+ ) { |value| @maxage = value }
108
122
 
109
123
  begin
110
124
  opts.parse(ARGV)
@@ -145,7 +159,7 @@ def configure_site(site_name)
145
159
  end
146
160
 
147
161
  def config_time_stamp
148
- "# Created by #{@app_name} at #{Time.now}"
162
+ "# Created by #{@opts.program_name} at #{Time.now}"
149
163
  end
150
164
 
151
165
  def local_app_alias
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brightbox-server-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 2.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Leach
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2008-06-16 00:00:00 +01:00
13
+ date: 2008-10-08 00:00:00 +01:00
14
14
  default_executable:
15
15
  dependencies: []
16
16
 
@@ -18,6 +18,7 @@ description:
18
18
  email: support@brightbox.co.uk
19
19
  executables:
20
20
  - railsapp-nginx
21
+ - railsapp-maintenance
21
22
  - railsapp-apache
22
23
  - railsapp-logrotate
23
24
  - railsapp-monit
@@ -31,12 +32,15 @@ files:
31
32
  - Rakefile
32
33
  - brightbox-gemspec.rb
33
34
  - bin/railsapp-nginx
35
+ - bin/railsapp-maintenance
34
36
  - bin/railsapp-apache
35
37
  - bin/railsapp-logrotate
36
38
  - bin/railsapp-monit
37
39
  - bin/railsapp-mongrel
38
40
  - lib/brightbox/version.rb
39
41
  - lib/brightbox/webserver-common.rb
42
+ - lib/brightbox/maintenance.rb
43
+ - lib/brightbox/maintenance-site.tar.gz
40
44
  has_rdoc: false
41
45
  homepage: http://wiki.brightbox.co.uk/docs:thebrightboxgem
42
46
  post_install_message:
@@ -59,7 +63,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
59
63
  requirements: []
60
64
 
61
65
  rubyforge_project: brightbox
62
- rubygems_version: 1.1.1
66
+ rubygems_version: 1.2.0
63
67
  signing_key:
64
68
  specification_version: 2
65
69
  summary: Brightbox Server configuration scripts