capper 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -46,3 +46,4 @@ pkg
46
46
 
47
47
  # For rubinius:
48
48
  #*.rbc
49
+ .idea/
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- capper (1.0.1)
4
+ capper (1.2.0)
5
5
  capistrano (~> 2.12.0)
6
6
  capistrano_colors (~> 0.5.5)
7
7
  dedent
data/README.rst CHANGED
@@ -225,6 +225,12 @@ ruby
225
225
  The ruby recipe provides basic support for Ruby applications. It will setup a
226
226
  gemrc file and and variables for ``ruby_exec_prefix`` (such as bundler).
227
227
 
228
+ thin
229
+ ----
230
+
231
+ The thin recipe provides integration with Thin. A script to manage the
232
+ thin process is uploaded to ``#{bin_path}/thin``.
233
+
228
234
  unicorn
229
235
  -------
230
236
 
@@ -267,6 +273,41 @@ integration. With one application per user account the whole crontab can be
267
273
  used for whenever. Additionally this recipe take the ``ruby_exec_prefix``
268
274
  setting into account.
269
275
 
276
+ node deployment
277
+ --------
278
+ read http://big-elephants.com/2012-07/deploying-node-with-capistrano/ about the
279
+ the use case.
280
+
281
+ nave
282
+ --------
283
+
284
+ The nave recipe sets up nave Virtual Environments for Node::
285
+
286
+ set :use_nave, true
287
+ set :nave_dir, '~/.nave'
288
+ set :node_version, '0.8.1'
289
+
290
+ npm
291
+ --------
292
+
293
+ The npm recipe runs npm install after deploy:update_code. When used with the nave
294
+ recipe npm install runs ``nave use <ver> npm install``.
295
+ Not it is recommended to add npm-shrinkwrap.json into version control to manage npm
296
+ dependencies::
297
+
298
+ set :npm_cmd, "npm"
299
+
300
+ forever
301
+ --------
302
+
303
+ The forever recipe starts your app as daemon in the background.
304
+ When used with the nave recipe it runs ``nave use <ver> forever [action]``::
305
+
306
+ set :forever_cmd, "forever" # e.g. "./node_modules/.bin/forever"
307
+ set :node_env, "production" # the NODE_ENV environment variable used to start the script
308
+ set :main_js, "index.js" # e.g. "./build/main.js" the script you want to start
309
+
310
+
270
311
  Contributing to capper
271
312
  ======================
272
313
 
@@ -10,7 +10,7 @@ set(:ruby_exec_prefix, "bundle exec")
10
10
  set(:bundle_dir) do
11
11
  begin
12
12
  File.join(shared_path, 'bundle', rvm_ruby_string)
13
- rescue NoMethodError
13
+ rescue NoMethodError, NameError
14
14
  File.join(shared_path, 'bundle')
15
15
  end
16
16
  end
@@ -0,0 +1,97 @@
1
+ after "deploy:restart", "forever:restart"
2
+ after "deploy:start", "forever:start"
3
+ after "deploy:stop", "forever:stop"
4
+
5
+ namespace :forever do
6
+ desc <<-DESC
7
+ Start the servers using the forever cmd If the forever cmd cannot \
8
+ be found then you can override the forever_cmd variable to specify \
9
+ which one it should use.
10
+ By default index.js in the applications root folder will be used for startup.
11
+
12
+ You can override any of these defaults by setting the variables shown below.
13
+
14
+ set :forever_cmd, "forever" # e.g. "./node_modules/.bin/forever"
15
+ set :main_js, "index.js" # e.g. "./build/main.js"
16
+ set :node_env, "production" # the NODE_ENV environment variable used to start the script
17
+ DESC
18
+ task :start, :roles => :app do
19
+ forever_cmd = fetch(:forever_cmd, "forever")
20
+ main_js = fetch(:main_js, "index.js")
21
+ app_path = fetch(:latest_release)
22
+ node_env = fetch(:node_env,'production')
23
+ if app_path.to_s.empty?
24
+ raise error_type.new("Cannot detect current release path - make sure you have deployed at least once.")
25
+ end
26
+ prefix = fetch(:use_nave, false) ? "#{fetch(:nave_dir)}/nave.sh use #{fetch(:node_version, 'stable')}" :''
27
+ run "cd #{app_path} && NODE_ENV=#{node_env} #{prefix} #{forever_cmd} start #{main_js}"
28
+ end
29
+
30
+ desc <<-DESC
31
+ Stop the servers using the forever cmd If the forever cmd cannot \
32
+ be found then you can override the forever_cmd variable to specify \
33
+ which one it should use.
34
+ By default index.js in the applications root folder will be used for startup.
35
+
36
+ You can override any of these defaults by setting the variables shown below.
37
+
38
+ set :forever_cmd, "forever" # e.g. "./node_modules/.bin/forever"
39
+ set :main_js, "index.js" # e.g. "./build/main.js"
40
+ set :node_env, "production" # the NODE_ENV environment variable used to start the script
41
+ DESC
42
+ task :stop, :roles => :app do
43
+ forever_cmd = fetch(:forever_cmd, "forever")
44
+ main_js = fetch(:main_js, "index.js")
45
+ app_path = fetch(:latest_release)
46
+ node_env = fetch(:node_env,'production')
47
+ if app_path.to_s.empty?
48
+ raise error_type.new("Cannot detect current release path - make sure you have deployed at least once.")
49
+ end
50
+ prefix = fetch(:use_nave, false) ? "#{fetch(:nave_dir)}/nave.sh use #{fetch(:node_version, 'stable')}" :''
51
+ run "cd #{app_path} && NODE_ENV=#{node_env} #{prefix} #{forever_cmd} stop #{main_js}"
52
+ end
53
+ desc <<-DESC
54
+ Restart the servers using the forever cmd If the forever cmd cannot \
55
+ be found then you can override the forever_cmd variable to specify \
56
+ which one it should use.
57
+ By default index.js in the applications root folder will be used for startup.
58
+
59
+ You can override any of these defaults by setting the variables shown below.
60
+
61
+ set :forever_cmd, "forever" # e.g. "./node_modules/.bin/forever"
62
+ set :main_js, "index.js" # e.g. "./build/main.js"
63
+ set :node_env, "production" # the NODE_ENV environment variable used to start the script
64
+ DESC
65
+ task :restart do
66
+ transaction do
67
+ stop
68
+ start
69
+ end
70
+ end
71
+
72
+ desc <<-DESC
73
+ tail the forever logfile using the forever cmd If the forever cmd cannot \
74
+ be found then you can override the forever_cmd variable to specify \
75
+ which one it should use.
76
+ By default index.js in the applications root folder will be used for startup.
77
+
78
+ You can override any of these defaults by setting the variables shown below.
79
+
80
+ set :forever_cmd, "forever" # e.g. "./node_modules/.bin/forever"
81
+ set :main_js, "index.js" # e.g. "./build/main.js"
82
+ DESC
83
+ task :tail do
84
+ forever_cmd = fetch(:forever_cmd, "forever")
85
+ main_js = fetch(:main_js, "index.js")
86
+ app_path = fetch(:latest_release)
87
+ if app_path.to_s.empty?
88
+ raise error_type.new("Cannot detect current release path - make sure you have deployed at least once.")
89
+ end
90
+ prefix = fetch(:use_nave, false) ? "#{fetch(:nave_dir)}/nave.sh use #{fetch(:node_version, 'stable')}" :''
91
+ resp = capture "cd #{app_path} && #{prefix} #{forever_cmd} logs | grep #{main_js}"
92
+ #logs = resp.split("\n")[2..-1].map{|l| l.split(" " ).last.gsub(/.\[3[5,9]m/,'')}
93
+ logs = resp.split("\n").map{|l| l.split(" " ).last.gsub(/.\[3[5,9]m/,'')}
94
+ run "tail -n10 -f #{logs.join(" ")}"
95
+ end
96
+ end
97
+
@@ -0,0 +1,34 @@
1
+ after "deploy:setup", "nave:setup"
2
+
3
+ _cset(:nave_installer_url, "https://raw.github.com/isaacs/nave/master/nave.sh")
4
+ _cset(:use_nave, true)
5
+ _cset(:nave_dir, "~/.nave")
6
+ _cset(:node_version, "stable")
7
+
8
+ namespace :nave do
9
+
10
+ desc <<-DESC
11
+ Install nave into nave target dir.\
12
+
13
+ You can override the defaults by setting the variables shown below.
14
+
15
+ set :nave_dir, "~/.nave" # e.g. "/usr/local/nave"
16
+ DESC
17
+
18
+ task :setup do
19
+ run("mkdir -p #{fetch(:nave_dir)}")
20
+ run("curl -s -L #{nave_installer_url} > #{fetch(:nave_dir)}/nave.sh; " +
21
+ "chmod +x #{fetch(:nave_dir)}/nave.sh", :shell => "/bin/bash")
22
+ install
23
+ end
24
+
25
+ desc <<-DESC
26
+ Installs the specified node version. (default: stable) \
27
+
28
+ set :node_version, "stable" # e.g. "0.8.1"
29
+ DESC
30
+
31
+ task :install do
32
+ run("#{fetch(:nave_dir)}/nave.sh install #{fetch(:node_version)}")
33
+ end
34
+ end
data/lib/capper/npm.rb ADDED
@@ -0,0 +1,23 @@
1
+ after 'deploy:update_code', "npm:install"
2
+
3
+ namespace :npm do
4
+ desc <<-DESC
5
+ Install the current npm environment. \
6
+ Note it is recommended to check in npm-shrinkwrap.json into version control\
7
+ and to put node_module into .gitignore to manage dependencies. \
8
+ See http://blog.nodejs.org/2012/02/27/managing-node-js-dependencies-with-shrinkwrap \
9
+ If no npm-shrinkwrap.json is found packages are installed from package.json with no guarantee\
10
+ about the version beeing installed
11
+ If the npm cmd cannot be found then you can override the npm_cmd variable to specifiy \
12
+ which one it should use.
13
+
14
+ You can override any of these defaults by setting the variables shown below.
15
+
16
+ set :npm_cmd, "npm" # e.g. "/usr/local/bin/npm"
17
+ DESC
18
+ task :install, :roles => :app, :except => { :no_release => true } do
19
+ prefix = fetch(:use_nave, false) ? "#{fetch(:nave_dir)}/nave.sh use #{fetch(:node_version, 'stable')}" : ''
20
+ run("cd #{latest_release} && #{prefix} #{fetch(:npm_cmd, "npm")} install")
21
+ end
22
+ end
23
+
data/lib/capper/rails.rb CHANGED
@@ -55,6 +55,14 @@ namespace :rails do
55
55
  run "cd #{directory} && #{rake} RAILS_ENV=#{rails_env} #{migrate_env} db:migrate"
56
56
  end
57
57
 
58
+ namespace :db do
59
+ desc "create the database running rake db:create"
60
+ task :create, :roles => :db, :only => { :primary => true } do
61
+ migrate_env = fetch(:migrate_env, "")
62
+ run "cd #{current_path} && #{rake} RAILS_ENV=#{rails_env} #{migrate_env} db:create"
63
+ end
64
+ end
65
+
58
66
  namespace :assets do
59
67
  desc <<-DESC
60
68
  Run the asset precompilation rake task. You can specify the full path \
data/lib/capper/rvm.rb CHANGED
@@ -9,7 +9,7 @@ require "rvm/capistrano"
9
9
  set(:rvm_type, :user)
10
10
  set(:rvm_ruby_string, File.read(".rvmrc").gsub(/^rvm( use)? --create (.*)/, '\2').strip)
11
11
 
12
- _cset(:rvm_version, "1.14.5")
12
+ _cset(:rvm_version, "1.17.0")
13
13
  set(:rvm_install_type) { rvm_version }
14
14
 
15
15
  before "deploy:setup", "rvm:install_ruby"
@@ -0,0 +1,35 @@
1
+ #!/bin/bash
2
+ export HOME=<%= deploy_to %>
3
+ export RAILS_ENV=<%= rails_env rescue "production" %>
4
+
5
+ if [[ -e "${HOME}"/.rvm/scripts/rvm ]]; then
6
+ source "${HOME}"/.rvm/scripts/rvm
7
+ fi
8
+
9
+ PIDFILE=<%= thin_pidfile %>
10
+ CMD="<%= ruby_exec_prefix %> thin -p <%= thin_port %> -e $RAILS_ENV -d -R config.ru start"
11
+
12
+ cd <%= current_path %> >/dev/null
13
+
14
+ sig () {
15
+ test -s "$PIDFILE" && kill -$1 $(<$PIDFILE)
16
+ }
17
+
18
+ case $1 in
19
+ start)
20
+ sig 0 && echo >&2 "Already running" && exit 0
21
+ $CMD
22
+ ;;
23
+ stop)
24
+ sig QUIT && exit 0
25
+ echo >&2 "Not running"
26
+ ;;
27
+ kill)
28
+ sig TERM && exit 0
29
+ echo >&2 "Not running"
30
+ ;;
31
+ *)
32
+ echo >&2 "Usage: $0 <start|stop|kill>"
33
+ exit 1
34
+ ;;
35
+ esac
@@ -26,7 +26,7 @@ pid "<%= unicorn_pidfile %>"
26
26
  begin
27
27
  require "syslogger"
28
28
  logger Syslogger.new("<%= application %>-unicorn", Syslog::LOG_PID, Syslog::LOG_LOCAL1)
29
- rescue
29
+ rescue LoadError
30
30
  end
31
31
 
32
32
  # these do not seem to support syslog
@@ -0,0 +1,58 @@
1
+ # these cannot be overriden
2
+ set(:thin_script) { File.join(bin_path, "thin") }
3
+ set(:thin_pidfile) { File.join(pid_path, "thin.pid") }
4
+
5
+ _cset(:thin_port, 3000)
6
+
7
+ after "deploy:update_code", "thin:setup"
8
+ after "deploy:restart", "thin:restart"
9
+
10
+ monit_config "thin", <<EOF.dedent, :roles => :app
11
+ check process thin
12
+ with pidfile "<%= thin_pidfile %>"
13
+ start program = "<%= thin_script %> start" with timeout 60 seconds
14
+ stop program = "<%= thin_script %> stop"
15
+ EOF
16
+
17
+ bluepill_config "thin", <<EOF, :roles => :app
18
+ app.process("thin") do |process|
19
+ process.pid_file = "<%= thin_pidfile %>"
20
+ process.working_dir = "<%= current_path %>"
21
+
22
+ process.start_command = "<%= thin_script %> start"
23
+ process.start_grace_time = 60.seconds
24
+
25
+ process.stop_signals = [:quit, 5.seconds, :quit, 30.seconds, :term, 5.seconds, :kill]
26
+ process.stop_grace_time = 45.seconds
27
+ end
28
+ EOF
29
+
30
+ namespace :thin do
31
+ desc "Generate thin configuration files"
32
+ task :setup, :roles => :app, :except => { :no_release => true } do
33
+ upload_template_file("thin.sh",
34
+ thin_script,
35
+ :mode => "0755")
36
+ end
37
+
38
+ desc "Start thin"
39
+ task :start, :roles => :app, :except => { :no_release => true } do
40
+ run "#{thin_script} start"
41
+ end
42
+
43
+ desc "Stop thin"
44
+ task :stop, :roles => :app, :except => { :no_release => true } do
45
+ run "#{thin_script} stop"
46
+ end
47
+
48
+ desc "Restart thin with zero downtime"
49
+ task :restart, :roles => :app, :except => { :no_release => true } do
50
+ run "#{thin_script} kill"
51
+ run "#{thin_script} start"
52
+ end
53
+
54
+ desc "Kill thin (this should only be used if all else fails)"
55
+ task :kill, :roles => :app, :except => { :no_release => true } do
56
+ run "#{thin_script} kill"
57
+ end
58
+ end
@@ -1,3 +1,3 @@
1
1
  module Capper
2
- VERSION = "1.1.0"
2
+ VERSION = "1.2.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-03 00:00:00.000000000 Z
12
+ date: 2012-12-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: erubis
@@ -114,8 +114,11 @@ files:
114
114
  - lib/capper/bundler.rb
115
115
  - lib/capper/delayed_job.rb
116
116
  - lib/capper/django.rb
117
+ - lib/capper/forever.rb
117
118
  - lib/capper/monit.rb
118
119
  - lib/capper/multistage.rb
120
+ - lib/capper/nave.rb
121
+ - lib/capper/npm.rb
119
122
  - lib/capper/python.rb
120
123
  - lib/capper/rails.rb
121
124
  - lib/capper/ruby.rb
@@ -125,10 +128,12 @@ files:
125
128
  - lib/capper/templates/maintenance.html.erb
126
129
  - lib/capper/templates/manage.py.erb
127
130
  - lib/capper/templates/rails.console.sh.erb
131
+ - lib/capper/templates/thin.sh.erb
128
132
  - lib/capper/templates/unicorn.rb.erb
129
133
  - lib/capper/templates/unicorn.sh.erb
130
134
  - lib/capper/templates/uwsgi.sh.erb
131
135
  - lib/capper/templates/uwsgi.xml.erb
136
+ - lib/capper/thin.rb
132
137
  - lib/capper/unicorn.rb
133
138
  - lib/capper/utils/bluepill.rb
134
139
  - lib/capper/utils/monit.rb