sunshine 1.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +237 -0
- data/Manifest.txt +70 -0
- data/README.txt +277 -0
- data/Rakefile +46 -0
- data/bin/sunshine +5 -0
- data/examples/deploy.rb +61 -0
- data/examples/deploy_tasks.rake +112 -0
- data/examples/standalone_deploy.rb +31 -0
- data/lib/commands/add.rb +96 -0
- data/lib/commands/default.rb +169 -0
- data/lib/commands/list.rb +322 -0
- data/lib/commands/restart.rb +62 -0
- data/lib/commands/rm.rb +83 -0
- data/lib/commands/run.rb +151 -0
- data/lib/commands/start.rb +72 -0
- data/lib/commands/stop.rb +61 -0
- data/lib/sunshine/app.rb +876 -0
- data/lib/sunshine/binder.rb +70 -0
- data/lib/sunshine/crontab.rb +143 -0
- data/lib/sunshine/daemon.rb +380 -0
- data/lib/sunshine/daemons/ar_sendmail.rb +28 -0
- data/lib/sunshine/daemons/delayed_job.rb +30 -0
- data/lib/sunshine/daemons/nginx.rb +104 -0
- data/lib/sunshine/daemons/rainbows.rb +35 -0
- data/lib/sunshine/daemons/server.rb +66 -0
- data/lib/sunshine/daemons/unicorn.rb +26 -0
- data/lib/sunshine/dependencies.rb +103 -0
- data/lib/sunshine/dependency_lib.rb +200 -0
- data/lib/sunshine/exceptions.rb +54 -0
- data/lib/sunshine/healthcheck.rb +83 -0
- data/lib/sunshine/output.rb +131 -0
- data/lib/sunshine/package_managers/apt.rb +48 -0
- data/lib/sunshine/package_managers/dependency.rb +349 -0
- data/lib/sunshine/package_managers/gem.rb +54 -0
- data/lib/sunshine/package_managers/yum.rb +62 -0
- data/lib/sunshine/remote_shell.rb +241 -0
- data/lib/sunshine/repo.rb +128 -0
- data/lib/sunshine/repos/git_repo.rb +122 -0
- data/lib/sunshine/repos/rsync_repo.rb +29 -0
- data/lib/sunshine/repos/svn_repo.rb +78 -0
- data/lib/sunshine/server_app.rb +554 -0
- data/lib/sunshine/shell.rb +384 -0
- data/lib/sunshine.rb +391 -0
- data/templates/logrotate/logrotate.conf.erb +11 -0
- data/templates/nginx/nginx.conf.erb +109 -0
- data/templates/nginx/nginx_optimize.conf +23 -0
- data/templates/nginx/nginx_proxy.conf +13 -0
- data/templates/rainbows/rainbows.conf.erb +18 -0
- data/templates/tasks/sunshine.rake +114 -0
- data/templates/unicorn/unicorn.conf.erb +6 -0
- data/test/fixtures/app_configs/test_app.yml +11 -0
- data/test/fixtures/sunshine_test/test_upload +0 -0
- data/test/mocks/mock_object.rb +179 -0
- data/test/mocks/mock_open4.rb +117 -0
- data/test/test_helper.rb +188 -0
- data/test/unit/test_app.rb +489 -0
- data/test/unit/test_binder.rb +20 -0
- data/test/unit/test_crontab.rb +128 -0
- data/test/unit/test_git_repo.rb +26 -0
- data/test/unit/test_healthcheck.rb +70 -0
- data/test/unit/test_nginx.rb +107 -0
- data/test/unit/test_rainbows.rb +26 -0
- data/test/unit/test_remote_shell.rb +102 -0
- data/test/unit/test_repo.rb +42 -0
- data/test/unit/test_server.rb +324 -0
- data/test/unit/test_server_app.rb +425 -0
- data/test/unit/test_shell.rb +97 -0
- data/test/unit/test_sunshine.rb +157 -0
- data/test/unit/test_svn_repo.rb +55 -0
- data/test/unit/test_unicorn.rb +22 -0
- metadata +217 -0
data/lib/sunshine.rb
ADDED
@@ -0,0 +1,391 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'open4'
|
3
|
+
require 'rainbow'
|
4
|
+
require 'highline'
|
5
|
+
require 'tmpdir'
|
6
|
+
|
7
|
+
require 'yaml'
|
8
|
+
require 'erb'
|
9
|
+
require 'logger'
|
10
|
+
require 'optparse'
|
11
|
+
require 'time'
|
12
|
+
require 'fileutils'
|
13
|
+
|
14
|
+
##
|
15
|
+
# Sunshine is an object oriented deploy tool for rack applications.
|
16
|
+
#
|
17
|
+
# Writing a Sunshine config script is easy:
|
18
|
+
#
|
19
|
+
# options = {
|
20
|
+
# :name => 'myapp',
|
21
|
+
# :repo => {:type => :svn, :url => 'svn://blah...'},
|
22
|
+
# :deploy_path => '/usr/local/myapp',
|
23
|
+
# :remote_shells => ['user@someserver.com']
|
24
|
+
# }
|
25
|
+
#
|
26
|
+
# Sunshine::App.deploy(options) do |app|
|
27
|
+
#
|
28
|
+
# app.yum_install 'sqlite'
|
29
|
+
# app.gem_install 'sqlite3-ruby'
|
30
|
+
#
|
31
|
+
# app.rake "db:migrate"
|
32
|
+
#
|
33
|
+
# app_server = Sunshine::Rainbows.new(app)
|
34
|
+
# app_server.restart
|
35
|
+
#
|
36
|
+
# Sunshine::Nginx.new(app, :point_to => app_server).restart
|
37
|
+
#
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# The App::deploy and App::new methods also support passing
|
41
|
+
# a path to a yaml file:
|
42
|
+
#
|
43
|
+
# app = Sunshine::App.new("path/to/config.yml")
|
44
|
+
# app.deploy{|app| Sunshine::Rainbows.new(app).restart }
|
45
|
+
#
|
46
|
+
#
|
47
|
+
# Command line execution:
|
48
|
+
#
|
49
|
+
# Usage:
|
50
|
+
# sunshine -h/--help
|
51
|
+
# sunshine -v/--version
|
52
|
+
# sunshine command [arguments...] [options...]
|
53
|
+
#
|
54
|
+
# Examples:
|
55
|
+
# sunshine run deploy_script.rb
|
56
|
+
# sunshine restart myapp -r user@server.com,user@host.com
|
57
|
+
# sunshine list myapp myotherapp --health -r user@server.com
|
58
|
+
# sunshine list myapp --status
|
59
|
+
#
|
60
|
+
# Commands:
|
61
|
+
# add Register an app with sunshine
|
62
|
+
# list Display deployed apps
|
63
|
+
# restart Restart a deployed app
|
64
|
+
# rm Unregister an app with sunshine
|
65
|
+
# run Run a Sunshine script
|
66
|
+
# start Start a deployed app
|
67
|
+
# stop Stop a deployed app
|
68
|
+
#
|
69
|
+
# For more help on sunshine commands, use 'sunshine COMMAND --help'
|
70
|
+
|
71
|
+
module Sunshine
|
72
|
+
|
73
|
+
##
|
74
|
+
# Sunshine version.
|
75
|
+
VERSION = '1.0.0.pre'
|
76
|
+
|
77
|
+
|
78
|
+
##
|
79
|
+
# Handles input/output to the shell. See Sunshine::Shell.
|
80
|
+
|
81
|
+
def self.shell
|
82
|
+
@shell ||= Sunshine::Shell.new
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# The default deploy environment to use. Set with the -e option.
|
87
|
+
# See App#deploy_env for app specific deploy environments.
|
88
|
+
|
89
|
+
def self.deploy_env
|
90
|
+
@config['deploy_env'].to_s
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
##
|
95
|
+
# Returns the main Sunshine dependencies library.
|
96
|
+
|
97
|
+
def self.dependencies
|
98
|
+
@dependency_lib ||= DependencyLib.new
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
##
|
103
|
+
# The default directory where apps should be deployed to:
|
104
|
+
# '/var/www' by default. Overridden in the ~/.sunshine config file.
|
105
|
+
# See also App#deploy_path.
|
106
|
+
|
107
|
+
def self.web_directory
|
108
|
+
@config['web_directory']
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
##
|
113
|
+
# Should sunshine ever ask for user input? True by default; overridden with
|
114
|
+
# the -a option.
|
115
|
+
|
116
|
+
def self.interactive?
|
117
|
+
!@config['auto']
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
##
|
122
|
+
# Handles all output for sunshine. See Sunshine::Output.
|
123
|
+
|
124
|
+
def self.logger
|
125
|
+
@logger ||= Sunshine::Output.new \
|
126
|
+
:level => Logger.const_get(@config['level'].upcase)
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
##
|
131
|
+
# Maximum number of deploys (history) to keep on the remote server,
|
132
|
+
# 5 by default. Overridden in the ~/.sunshine config file.
|
133
|
+
|
134
|
+
def self.max_deploy_versions
|
135
|
+
@config['max_deploy_versions']
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
##
|
140
|
+
# Check if trace log should be output at all.
|
141
|
+
# This value can be assigned by default in ~/.sunshine
|
142
|
+
# or switched off with the run command's --no-trace option.
|
143
|
+
# Defaults to true.
|
144
|
+
|
145
|
+
def self.trace?
|
146
|
+
@config['trace']
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
##
|
151
|
+
# Adds an INT signal trap with its description on the stack.
|
152
|
+
# Returns a trap_item Array.
|
153
|
+
|
154
|
+
def self.add_trap desc, &block
|
155
|
+
trap_item = [desc, block]
|
156
|
+
(@trap_stack ||= []).unshift trap_item
|
157
|
+
trap_item
|
158
|
+
end
|
159
|
+
|
160
|
+
add_trap "Disconnecting all remote shells." do
|
161
|
+
RemoteShell.disconnect_all
|
162
|
+
end
|
163
|
+
|
164
|
+
|
165
|
+
##
|
166
|
+
# Call a trap item and display it's message.
|
167
|
+
|
168
|
+
def self.call_trap trap_item
|
169
|
+
return unless trap_item
|
170
|
+
|
171
|
+
msg, block = trap_item
|
172
|
+
|
173
|
+
logger.info :INT, msg do
|
174
|
+
block.call
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
##
|
180
|
+
# Remove a trap_item from the stack.
|
181
|
+
|
182
|
+
def self.delete_trap trap_item
|
183
|
+
@trap_stack.delete trap_item
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
trap "INT" do
|
188
|
+
$stderr << "\n\n"
|
189
|
+
logger.indent = 0
|
190
|
+
logger.fatal :INT, "Caught INT signal!"
|
191
|
+
|
192
|
+
call_trap @trap_stack.shift
|
193
|
+
Kernel.exit 1
|
194
|
+
end
|
195
|
+
|
196
|
+
|
197
|
+
##
|
198
|
+
# Global value of sudo to use. Returns true, nil, or a username.
|
199
|
+
# This value can be assigned by default in ~/.sunshine
|
200
|
+
# or with the --sudo [username] option. Defaults to nil.
|
201
|
+
|
202
|
+
def self.sudo
|
203
|
+
@config['sudo']
|
204
|
+
end
|
205
|
+
|
206
|
+
|
207
|
+
##
|
208
|
+
# Path to the list of installed sunshine apps.
|
209
|
+
APP_LIST_PATH = "~/.sunshine_list"
|
210
|
+
|
211
|
+
READ_LIST_CMD = "test -f #{Sunshine::APP_LIST_PATH} && "+
|
212
|
+
"cat #{APP_LIST_PATH} || echo ''"
|
213
|
+
|
214
|
+
##
|
215
|
+
# Commands supported by Sunshine
|
216
|
+
COMMANDS = %w{add list restart rm run start stop}
|
217
|
+
|
218
|
+
##
|
219
|
+
# Default Sunshine config file
|
220
|
+
USER_CONFIG_FILE = File.expand_path("~/.sunshine")
|
221
|
+
|
222
|
+
##
|
223
|
+
# Default configuration
|
224
|
+
DEFAULT_CONFIG = {
|
225
|
+
'level' => 'info',
|
226
|
+
'deploy_env' => :development,
|
227
|
+
'auto' => false,
|
228
|
+
'max_deploy_versions' => 5,
|
229
|
+
'web_directory' => '/var/www'
|
230
|
+
}
|
231
|
+
|
232
|
+
##
|
233
|
+
# Temp directory used by various sunshine classes
|
234
|
+
# for uploads, checkouts, etc...
|
235
|
+
TMP_DIR = File.join Dir.tmpdir, "sunshine_#{$$}"
|
236
|
+
FileUtils.mkdir_p TMP_DIR
|
237
|
+
|
238
|
+
##
|
239
|
+
# Path where sunshine assumes repo information can be found if missing.
|
240
|
+
PATH = Dir.getwd
|
241
|
+
|
242
|
+
##
|
243
|
+
# File DATA from sunshine run files.
|
244
|
+
DATA = defined?(::DATA) ? ::DATA : nil
|
245
|
+
|
246
|
+
##
|
247
|
+
# Root directory of the Sunshine gem.
|
248
|
+
ROOT = File.expand_path File.join(File.dirname(__FILE__), "..")
|
249
|
+
|
250
|
+
##
|
251
|
+
# Cleanup after sunshine has run, remove temp dirs, etc...
|
252
|
+
|
253
|
+
def self.cleanup
|
254
|
+
FileUtils.rm_rf TMP_DIR if Dir.glob("#{TMP_DIR}/*").empty?
|
255
|
+
end
|
256
|
+
|
257
|
+
|
258
|
+
##
|
259
|
+
# Setup sunshine with a custom config:
|
260
|
+
# Sunshine.setup 'level' => 'debug', 'deploy_env' => :production
|
261
|
+
|
262
|
+
def self.setup new_config={}, reset=false
|
263
|
+
@config = DEFAULT_CONFIG.dup if !defined?(@config) || reset
|
264
|
+
@config.merge! new_config
|
265
|
+
@config
|
266
|
+
end
|
267
|
+
|
268
|
+
|
269
|
+
##
|
270
|
+
# Run sunshine with the passed argv and exits with appropriate exitcode.
|
271
|
+
# run %w{run my_script.rb -l debug}
|
272
|
+
# run %w{list -d}
|
273
|
+
|
274
|
+
def self.run argv=ARGV
|
275
|
+
unless File.file? USER_CONFIG_FILE
|
276
|
+
File.open(USER_CONFIG_FILE, "w+"){|f| f.write DEFAULT_CONFIG.to_yaml}
|
277
|
+
|
278
|
+
msg = "Missing config file was created for you: #{USER_CONFIG_FILE}\n\n"
|
279
|
+
msg << DEFAULT_CONFIG.to_yaml
|
280
|
+
|
281
|
+
self.exit 1, msg
|
282
|
+
end
|
283
|
+
|
284
|
+
command_name = find_command argv.first
|
285
|
+
argv.shift if command_name
|
286
|
+
command_name ||= "default"
|
287
|
+
|
288
|
+
command = Sunshine.const_get("#{command_name.capitalize}Command")
|
289
|
+
|
290
|
+
config = YAML.load_file USER_CONFIG_FILE
|
291
|
+
config.merge! command.parse_args(argv)
|
292
|
+
|
293
|
+
self.setup config, true
|
294
|
+
|
295
|
+
result = command.exec argv, config
|
296
|
+
|
297
|
+
self.exit(*result)
|
298
|
+
end
|
299
|
+
|
300
|
+
|
301
|
+
##
|
302
|
+
# Find the sunshine command to run based on the passed name.
|
303
|
+
# Handles partial command names if they can be uniquely mapped to a command.
|
304
|
+
# find_command "dep" #=> "run"
|
305
|
+
# find_command "zzz" #=> false
|
306
|
+
|
307
|
+
def self.find_command name
|
308
|
+
commands = COMMANDS.select{|c| c =~ /^#{name}/}
|
309
|
+
commands.length == 1 && commands.first
|
310
|
+
end
|
311
|
+
|
312
|
+
|
313
|
+
##
|
314
|
+
# Exits sunshine process and returns the appropriate exit code
|
315
|
+
# exit 0, "ok"
|
316
|
+
# exit false, "ok"
|
317
|
+
# # both output: stdout >> ok - exitcode 0
|
318
|
+
# exit 1, "oh noes"
|
319
|
+
# exit true, "oh noes"
|
320
|
+
# # both output: stderr >> oh noes - exitcode 1
|
321
|
+
|
322
|
+
def self.exit status, msg=nil
|
323
|
+
self.cleanup
|
324
|
+
|
325
|
+
status = case status
|
326
|
+
when true
|
327
|
+
0
|
328
|
+
when false
|
329
|
+
1
|
330
|
+
when Integer
|
331
|
+
status
|
332
|
+
else
|
333
|
+
status.to_i
|
334
|
+
end
|
335
|
+
|
336
|
+
output = status == 0 ? $stdout : $stderr
|
337
|
+
|
338
|
+
output << "#{msg}\n" if !msg.nil?
|
339
|
+
|
340
|
+
Kernel.exit status
|
341
|
+
end
|
342
|
+
|
343
|
+
|
344
|
+
require 'sunshine/exceptions'
|
345
|
+
|
346
|
+
require 'sunshine/shell'
|
347
|
+
require 'sunshine/output'
|
348
|
+
|
349
|
+
require 'sunshine/binder'
|
350
|
+
|
351
|
+
require 'sunshine/dependency_lib'
|
352
|
+
require 'sunshine/package_managers/dependency'
|
353
|
+
require 'sunshine/package_managers/apt'
|
354
|
+
require 'sunshine/package_managers/yum'
|
355
|
+
require 'sunshine/package_managers/gem'
|
356
|
+
|
357
|
+
require 'sunshine/repo'
|
358
|
+
require 'sunshine/repos/svn_repo'
|
359
|
+
require 'sunshine/repos/git_repo'
|
360
|
+
require 'sunshine/repos/rsync_repo'
|
361
|
+
|
362
|
+
require 'sunshine/daemon'
|
363
|
+
require 'sunshine/daemons/server'
|
364
|
+
require 'sunshine/daemons/nginx'
|
365
|
+
require 'sunshine/daemons/unicorn'
|
366
|
+
require 'sunshine/daemons/rainbows'
|
367
|
+
require 'sunshine/daemons/ar_sendmail'
|
368
|
+
require 'sunshine/daemons/delayed_job'
|
369
|
+
|
370
|
+
require 'sunshine/crontab'
|
371
|
+
|
372
|
+
require 'sunshine/healthcheck'
|
373
|
+
|
374
|
+
require 'sunshine/remote_shell'
|
375
|
+
|
376
|
+
require 'sunshine/server_app'
|
377
|
+
require 'sunshine/app'
|
378
|
+
|
379
|
+
require 'commands/default'
|
380
|
+
require 'commands/list'
|
381
|
+
require 'commands/add'
|
382
|
+
require 'commands/run'
|
383
|
+
require 'commands/restart'
|
384
|
+
require 'commands/rm'
|
385
|
+
require 'commands/start'
|
386
|
+
require 'commands/stop'
|
387
|
+
end
|
388
|
+
|
389
|
+
|
390
|
+
Sunshine.setup
|
391
|
+
require 'sunshine/dependencies'
|
@@ -0,0 +1,109 @@
|
|
1
|
+
<% darwin = shell.os_name =~ /^darwin$/i %>
|
2
|
+
|
3
|
+
<% if sudo == true || sudo == 'root' %>
|
4
|
+
user nobody nobody;
|
5
|
+
<% end %>
|
6
|
+
worker_processes <%= processes %>;
|
7
|
+
pid <%= expand_path pid %>;
|
8
|
+
error_log <%= expand_path log_file(:stderr) %> info;
|
9
|
+
|
10
|
+
events {
|
11
|
+
worker_connections 1024;
|
12
|
+
<% unless darwin %>
|
13
|
+
use epoll;
|
14
|
+
<% end %>
|
15
|
+
}
|
16
|
+
|
17
|
+
http {
|
18
|
+
|
19
|
+
<% if use_passenger? %>
|
20
|
+
passenger_root <%= passenger_root %>;
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
client_body_temp_path <%= darwin ? '/var/tmp/nginx' : '/dev/shm' %>;
|
24
|
+
proxy_temp_path <%= darwin ? '/var/tmp/nginx' : '/dev/shm' %>;
|
25
|
+
|
26
|
+
include <%= File.join nginx_conf_path, 'mime.types' %>;
|
27
|
+
default_type application/octet-stream;
|
28
|
+
|
29
|
+
log_format sunshine '$remote_addr - $remote_user [$time_local] '
|
30
|
+
'"$request" $status $body_bytes_sent "$http_referer" '
|
31
|
+
'"$http_user_agent" "$http_cookie" $request_time '
|
32
|
+
'$upstream_http_x_urid';
|
33
|
+
access_log <%= expand_path log_file(:stdout) %> sunshine;
|
34
|
+
|
35
|
+
|
36
|
+
# This should be some other include file
|
37
|
+
include <%= expand_path config_path %>/nginx_optimize.conf;
|
38
|
+
|
39
|
+
|
40
|
+
##
|
41
|
+
# gZip config
|
42
|
+
gzip on;
|
43
|
+
gzip_disable "MSIE [1-6]\.";
|
44
|
+
gzip_min_length 1100;
|
45
|
+
gzip_buffers 4 8k;
|
46
|
+
gzip_http_version 1.0;
|
47
|
+
gzip_comp_level 5;
|
48
|
+
gzip_proxied any;
|
49
|
+
gzip_types text/plain text/html text/css application/x-javascript application/xml application/xml+rss text/javascript;
|
50
|
+
|
51
|
+
<% if target.is_a?(Sunshine::Server) %>
|
52
|
+
upstream app_server {
|
53
|
+
server 0:<%= target.port %> fail_timeout=<%= timeout %>;
|
54
|
+
}
|
55
|
+
<% end %>
|
56
|
+
|
57
|
+
##
|
58
|
+
# 301 redirect www to non-www host.
|
59
|
+
server {
|
60
|
+
listen <%= port %>;
|
61
|
+
server_name www.<%= server_name %>;
|
62
|
+
rewrite ^/(.*) http://<%= server_name %>/$1 permanent;
|
63
|
+
}
|
64
|
+
|
65
|
+
##
|
66
|
+
# Main server definition.
|
67
|
+
server {
|
68
|
+
listen <%= port %> default;
|
69
|
+
server_name <%= server_name %>;
|
70
|
+
port_in_redirect off; # needed for the F5, unfortunately
|
71
|
+
server_name_in_redirect off;
|
72
|
+
|
73
|
+
|
74
|
+
root <%= expand_path app.current_path %>/public;
|
75
|
+
|
76
|
+
<% if use_passenger? %>
|
77
|
+
passenger_enabled on;
|
78
|
+
|
79
|
+
<% else %>
|
80
|
+
|
81
|
+
##
|
82
|
+
# Main proxy
|
83
|
+
location / {
|
84
|
+
<% if darwin %>
|
85
|
+
ssi on;
|
86
|
+
<% end %>
|
87
|
+
if (-f $request_filename) {
|
88
|
+
break;
|
89
|
+
}
|
90
|
+
|
91
|
+
include <%= expand_path config_path %>/nginx_proxy.conf;
|
92
|
+
expires -1;
|
93
|
+
|
94
|
+
<% if target.is_a?(Sunshine::Server) %>
|
95
|
+
if (!-f $request_filename) {
|
96
|
+
proxy_pass http://app_server;
|
97
|
+
break;
|
98
|
+
}
|
99
|
+
<% end %>
|
100
|
+
|
101
|
+
error_page 500 502 503 504 /500.html;
|
102
|
+
location = /500.html {
|
103
|
+
root <%= expand_path app.current_path %>/public;
|
104
|
+
}
|
105
|
+
}
|
106
|
+
<% end %>
|
107
|
+
}
|
108
|
+
|
109
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
server_name_in_redirect off;
|
2
|
+
|
3
|
+
sendfile on;
|
4
|
+
tcp_nodelay on;
|
5
|
+
tcp_nopush off;
|
6
|
+
keepalive_timeout 75 20;
|
7
|
+
server_names_hash_bucket_size 128; # Seems to be required for vhosts.
|
8
|
+
|
9
|
+
##
|
10
|
+
# Optimizations: http://www.typemiss.net/blog/kounoike/20060227-75
|
11
|
+
client_header_timeout 10m;
|
12
|
+
client_body_timeout 10m;
|
13
|
+
send_timeout 10m;
|
14
|
+
|
15
|
+
connection_pool_size 256;
|
16
|
+
client_header_buffer_size 12k;
|
17
|
+
large_client_header_buffers 4 8k;
|
18
|
+
request_pool_size 4k;
|
19
|
+
|
20
|
+
output_buffers 1 32k;
|
21
|
+
postpone_output 1460;
|
22
|
+
|
23
|
+
ignore_invalid_headers on;
|
@@ -0,0 +1,13 @@
|
|
1
|
+
proxy_redirect off;
|
2
|
+
proxy_set_header Host $host;
|
3
|
+
proxy_set_header X-Real-IP $remote_addr;
|
4
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
5
|
+
client_max_body_size 10m;
|
6
|
+
client_body_buffer_size 128k;
|
7
|
+
proxy_connect_timeout 90;
|
8
|
+
proxy_send_timeout 90;
|
9
|
+
proxy_read_timeout 90;
|
10
|
+
proxy_buffer_size 4k;
|
11
|
+
proxy_buffers 4 32k;
|
12
|
+
proxy_busy_buffers_size 64k;
|
13
|
+
proxy_temp_file_write_size 64k;
|
@@ -0,0 +1,18 @@
|
|
1
|
+
timeout <%= timeout %>
|
2
|
+
worker_processes <%= processes %>
|
3
|
+
listen "0.0.0.0:<%= port %>"
|
4
|
+
pid File.expand_path("<%= pid %>")
|
5
|
+
stderr_path File.expand_path("<%= log_file :stderr %>")
|
6
|
+
stdout_path File.expand_path("<%= log_file :stdout %>")
|
7
|
+
|
8
|
+
<% if concurrency && !concurrency.empty? %>
|
9
|
+
Rainbows! do
|
10
|
+
use <%= concurrency[:model].inspect %>
|
11
|
+
<% if concurrency[:connections] %>
|
12
|
+
worker_connections <%= concurrency[:connections] %>
|
13
|
+
<% end %>
|
14
|
+
<% if concurrency[:timeout] %>
|
15
|
+
keepalive_timeout <%= concurrency[:timeout] %>
|
16
|
+
<% end %>
|
17
|
+
end
|
18
|
+
<% end %>
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'sunshine'
|
2
|
+
|
3
|
+
namespace :sunshine do
|
4
|
+
|
5
|
+
##
|
6
|
+
# If using rails, have rails information available by updating :app task to:
|
7
|
+
# task :app => :environment do
|
8
|
+
# ...
|
9
|
+
# end
|
10
|
+
|
11
|
+
desc "Instantiate Sunshine"
|
12
|
+
task :app do
|
13
|
+
deploy_env = ENV['env'] || ENV['RACK_ENV'] || ENV['RAILS_ENV']
|
14
|
+
|
15
|
+
Sunshine.setup 'deploy_env' => ( deploy_env || "development" )
|
16
|
+
|
17
|
+
|
18
|
+
# View the Sunshine README, scripts in the sunshine/examples
|
19
|
+
# directory, or the docs for Sunshine::App for more information on
|
20
|
+
# App instantiation.
|
21
|
+
|
22
|
+
@app = Sunshine::App.new "path/to/app_deploy_config.yml"
|
23
|
+
# or
|
24
|
+
# @app = Sunshine::App.new app_config_hash
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
desc "Deploy the app"
|
29
|
+
task :deploy => :app do
|
30
|
+
Sunshine.setup 'trace' => true
|
31
|
+
|
32
|
+
@app.deploy do |app|
|
33
|
+
|
34
|
+
# Do deploy-specific stuff here, e.g.
|
35
|
+
#
|
36
|
+
# app.run_bundler
|
37
|
+
#
|
38
|
+
# unicorn = Sunshine::Unicorn.new app, :port => 3000,
|
39
|
+
# :processes => 8
|
40
|
+
# unicorn.setup
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
@app.start :force => true
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
# Post-deploy control tasks:
|
49
|
+
|
50
|
+
desc "Run db:migrate on remote :db servers"
|
51
|
+
task :db_migrate => :app do
|
52
|
+
@app.rake 'db:migrate', :role => :db
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
desc "Run the remote start script"
|
57
|
+
task :start => :app do
|
58
|
+
@app.start
|
59
|
+
puts @app.status.to_yaml
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
desc "Run the remote stop script"
|
64
|
+
task :stop => :app do
|
65
|
+
@app.stop
|
66
|
+
puts @app.status.to_yaml
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
desc "Run the remote restart script"
|
71
|
+
task :restart => :app do
|
72
|
+
@app.restart
|
73
|
+
puts @app.status.to_yaml
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
desc "Check if the deployed app is running"
|
78
|
+
task :status => :app do
|
79
|
+
puts @app.status.to_yaml
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
desc "Get deployed app info"
|
84
|
+
task :info => :app do
|
85
|
+
puts @app.deploy_details.to_yaml
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
desc "Get the health state"
|
90
|
+
task :health => :app do
|
91
|
+
puts @app.health.to_yaml
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
namespace :health do
|
96
|
+
|
97
|
+
desc "Turn on health check"
|
98
|
+
task :enable => :app do
|
99
|
+
puts @app.health(:enable).to_yaml
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
desc "Turn off health check"
|
104
|
+
task :disable => :app do
|
105
|
+
puts @app.health(:disable).to_yaml
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
desc "Remove health check"
|
110
|
+
task :remove => :app do
|
111
|
+
puts @app.health(:remove).to_yaml
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
File without changes
|