capistrano-nginx-unicorn 0.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.
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ /vendor/ruby
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in capistrano-nginx-unicorn.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Ivan Tkalin
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,146 @@
1
+ # Capistrano-Nginx-Unicorn
2
+
3
+ Capistrano tasks for configuration and management nginx+unicorn combo for zero downtime deployments of Rails applications.
4
+
5
+ Provides capistrano tasks to:
6
+
7
+ * easily add application to nginx and reload it's configuration
8
+ * create unicorn init script for application, so it will be automatically started when OS restarts
9
+ * start/stop unicorn (also can be done using `sudo service unicorn_<your_app> start/stop`)
10
+ * reload unicorn using `USR2` signal to load new application version with zero downtime
11
+
12
+ Provides several capistrano variables for easy customization.
13
+ Also, for full customization, all configs can be copied to the application using generators.
14
+
15
+ ## Installation
16
+
17
+ Add this line to your application's Gemfile:
18
+
19
+ gem 'capistrano-nginx-unicorn', require: false, group: :development
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install capistrano-nginx-unicorn
28
+
29
+ ## Usage
30
+
31
+ Add this line to your `deploy.rb`
32
+
33
+ require 'capistrano-nginx-unicorn'
34
+
35
+ Note, that following capistrano variables should be defined:
36
+
37
+ application
38
+ current_path
39
+ shared_path
40
+ user
41
+
42
+ You can check that new tasks are available (`cap -T`):
43
+
44
+ for nginx:
45
+
46
+ # add and enable application to nginx
47
+ cap nginx:setup
48
+
49
+ # reload nginx configuration
50
+ cap nginx:reload
51
+
52
+ and for unicorn:
53
+
54
+ # create unicorn configuration and init script
55
+ cap unicorn:setup
56
+
57
+ # start unicorn
58
+ cap unicorn:start
59
+
60
+ # stop unicorn
61
+ cap unicorn:stop
62
+
63
+ # reload unicorn with no downtime
64
+ # old workers will process new request until new master is fully loaded
65
+ # then old workers will be automatically killed and new workers will start processing requests
66
+ cap unicorn:reload
67
+
68
+ There is no need to execute any of these tasks manually.
69
+ They will be called automatically on different deploy stages:
70
+
71
+ * `nginx:setup`, `nginx:reload` and `unicorn:setup` are hooked to `deploy:setup`
72
+ * `unicorn:restart` is hooked to `deploy:restart`
73
+
74
+ This means that if you run `cap deploy:setup`,
75
+ nginx and unicorn will be automatically configured
76
+ And after each deploy, unicorn will be automatically reloaded.
77
+
78
+ However, if you changed variables or customized templates,
79
+ you can run any of these tasks to update configuration.
80
+
81
+ ## Customization
82
+
83
+ ### Using variables
84
+
85
+ You can customize nginx and unicorn configs using capistrano variables:
86
+
87
+ # path to customized templates (see below for details)
88
+ # default value: "config/deploy/templates"
89
+ set :templates_path, "config/deploy/templates"
90
+
91
+ # server name for nginx, default value: no (will be prompted if not set)
92
+ # set this to your site name as it is visible from outside
93
+ # this will allow 1 nginx to serve several sites with different `server_name`
94
+ set :nginx_server_name, "example.com"
95
+
96
+ # path, where unicorn pid file will be stored
97
+ # default value: `"#{current_path}/tmp/pids/unicorn.pid"`
98
+ set :unicorn_pid, "#{current_path}/tmp/pids/unicorn.pid"
99
+
100
+ # path, where unicorn config file will be stored
101
+ # default value: `"#{shared_path}/config/unicorn.rb"`
102
+ set :unicorn_config, "#{shared_path}/config/unicorn.rb"
103
+
104
+ # path, where unicorn log file will be stored
105
+ # default value: `"#{shared_path}/config/unicorn.rb"`
106
+ set :unicorn_log, "#{shared_path}/config/unicorn.rb"
107
+
108
+ # user name to run unicorn
109
+ # default value: `user` (user varibale defined in your `deploy.rb`)
110
+ set :unicorn_user, "user"
111
+
112
+ # number of unicorn workers
113
+ # default value: no (will be prompted if not set)
114
+ set :unicorn_workers, 4
115
+
116
+ For example, of you site name is `example.com` and you want to use 8 unicorn workers,
117
+ your `deploy.rb` will look like this:
118
+
119
+ set :server_name, "example.com"
120
+ set :unicorn_workers, 4
121
+ require 'capistrano-nginx-unicorn'
122
+
123
+ ### Template Customization
124
+
125
+ If you want to change default templates, you can generate them using `rails generator`
126
+
127
+ rails g capistrano:nginx_unicorn:config
128
+
129
+ This will copy default templates to `config/deploy/templates` directory,
130
+ so you can customize them as you like, and capistrano tasks will use this templates instead of default.
131
+
132
+ You can also provide path, where to generate templates:
133
+
134
+ rails g capistrano:nginx_unicorn:config config/templates
135
+
136
+ # TODO:
137
+
138
+ * add tests
139
+
140
+ ## Contributing
141
+
142
+ 1. Fork it
143
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
144
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
145
+ 4. Push to the branch (`git push origin my-new-feature`)
146
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'capistrano/nginx_unicorn/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "capistrano-nginx-unicorn"
8
+ gem.version = Capistrano::NginxUnicorn::VERSION
9
+ gem.authors = ["Ivan Tkalin"]
10
+ gem.email = ["itkalin@gmail.com"]
11
+ gem.description = %q{Capistrano tasks for configuration and management nginx+unicorn combo for zero downtime deployments of Rails applications. Configs can be copied to the application using generators and easily customized.}
12
+ gem.summary = %q{Create and manage nginx+unicorn configs from capistrano}
13
+ gem.homepage = "https://github.com/ivalkeen/capistrano-nginx-unicorn"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency 'capistrano', '>= 2.0'
21
+
22
+ gem.add_development_dependency "rake"
23
+ end
@@ -0,0 +1,2 @@
1
+ require "capistrano/nginx_unicorn/version"
2
+ require "capistrano/nginx_unicorn/tasks"
@@ -0,0 +1,62 @@
1
+ require 'capistrano'
2
+
3
+ Capistrano::Configuration.instance.load do
4
+ set_default(:templates_path, "config/deploy/templates")
5
+
6
+ set_default(:nginx_server_name) { Capistrano::CLI.ui.ask "Nginx server name: " }
7
+
8
+ set_default(:unicorn_pid, "#{current_path}/tmp/pids/unicorn.pid")
9
+ set_default(:unicorn_config, "#{shared_path}/config/unicorn.rb")
10
+ set_default(:unicorn_log, "#{shared_path}/log/unicorn.log")
11
+ set_default(:unicorn_user, user)
12
+ set_default(:unicorn_workers) { Capistrano::CLI.ui.ask "Number of unicorn workers: " }
13
+
14
+ namespace :nginx do
15
+ desc "Setup nginx configuration for this application"
16
+ task :setup, roles: :web do
17
+ template("nginx_conf.erb", "/tmp/#{application}")
18
+ run "#{sudo} mv /tmp/#{application} /etc/nginx/sites-available/#{application}"
19
+ run "#{sudo} ln -fs /etc/nginx/sites-available/#{application} /etc/nginx/sites-enabled/#{application}"
20
+ end
21
+
22
+ after "deploy:setup", "nginx:setup"
23
+ after "deploy:setup", "nginx:reload"
24
+
25
+ desc "Reload nginx configuration"
26
+ task :reload, roles: :web do
27
+ run "#{sudo} /etc/init.d/nginx reload"
28
+ end
29
+ end
30
+
31
+ namespace :unicorn do
32
+ desc "Setup Unicorn initializer and app configuration"
33
+ task :setup, roles: :app do
34
+ run "mkdir -p #{shared_path}/config"
35
+ template "unicorn.rb.erb", unicorn_config
36
+ template "unicorn_init.erb", "/tmp/unicorn_init"
37
+ run "chmod +x /tmp/unicorn_init"
38
+ run "#{sudo} mv /tmp/unicorn_init /etc/init.d/unicorn_#{application}"
39
+ run "#{sudo} update-rc.d -f unicorn_#{application} defaults"
40
+ end
41
+
42
+ after "deploy:setup", "unicorn:setup"
43
+
44
+ %w[start stop restart].each do |command|
45
+ desc "#{command} unicorn"
46
+ task command, roles: :app do
47
+ run "service unicorn_#{application} #{command}"
48
+ end
49
+
50
+ after "deploy:#{command}", "unicorn:#{command}"
51
+ end
52
+ end
53
+
54
+ def template(template_name, target)
55
+ config_file = "#{templates_path}/#{template_name}"
56
+ # if no customized file, proceed with default
57
+ unless File.exists?(config_file)
58
+ config_file = File.join(File.dirname(__FILE__), "../../generators/capistrano/nginx_unicorn/templates/#{template_name}")
59
+ end
60
+ put ERB.new(File.read(config_file)).result(binding), target
61
+ end
62
+ end
@@ -0,0 +1,5 @@
1
+ module Capistrano
2
+ module NginxUnicorn
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ To create local nginx and unicorn configuration files call
2
+
3
+ rails generate capistrano:nginx_unicorn:config [path]
4
+
5
+ The default path is "config/deploy/templates". You can override it like so:
6
+
7
+ rails generate capistrano:nginx_unicorn:config "config/templates"
8
+
9
+ If you override templates path, don't forget to set "templates_path" variable in your deploy.rb
@@ -0,0 +1,19 @@
1
+ module Capistrano
2
+ module NginxUnicorn
3
+ module Generators
4
+ class ConfigGenerator < Rails::Generators::Base
5
+ desc "Create local nginx and unicorn configuration files for customization"
6
+ source_root File.expand_path('../templates', __FILE__)
7
+ argument :templates_path, :type => :string,
8
+ :default => "config/deploy/templates",
9
+ :banner => "path to templates"
10
+
11
+ def copy_template
12
+ copy_file "nginx_conf.erb", "#{templates_path}/nginx_conf.erb"
13
+ copy_file "unicorn.rb.erb", "#{templates_path}/unicorn.rb.erb"
14
+ copy_file "unicorn_init.erb", "#{templates_path}/unicorn_init.erb"
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,67 @@
1
+ upstream unicorn_<%= application %> {
2
+ server unix:/tmp/unicorn.<%= application %>.sock fail_timeout=0;
3
+ }
4
+
5
+ server {
6
+ listen 80;
7
+ server_name <%= nginx_server_name %>;
8
+ root <%= current_path %>/public;
9
+ try_files $uri/index.html $uri @unicorn_<%= application %>;
10
+
11
+ location @unicorn_<%= application %> {
12
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
13
+ proxy_set_header Host $http_host;
14
+ proxy_redirect off;
15
+ proxy_pass http://unicorn_<%= application %>;
16
+ # limit_req zone=one;
17
+ access_log <%= shared_path %>/log/nginx.access.log;
18
+ error_log <%= shared_path %>/log/nginx.error.log;
19
+ }
20
+
21
+ location ~ ^/(assets|images|javascripts|stylesheets|swfs|system)/ {
22
+ gzip_static on;
23
+ expires max;
24
+ add_header Cache-Control public;
25
+ add_header Last-Modified "";
26
+ add_header ETag "";
27
+
28
+ open_file_cache max=1000 inactive=500s;
29
+ open_file_cache_valid 600s;
30
+ open_file_cache_errors on;
31
+ break;
32
+ }
33
+
34
+ client_max_body_size 4G;
35
+ keepalive_timeout 10;
36
+
37
+ error_page 500 502 504 /500.html;
38
+ error_page 503 @503;
39
+
40
+ location = /50x.html {
41
+ root html;
42
+ }
43
+
44
+ location = /404.html {
45
+ root html;
46
+ }
47
+
48
+ location @503 {
49
+ error_page 405 = /system/maintenance.html;
50
+ if (-f $document_root/system/maintenance.html) {
51
+ rewrite ^(.*)$ /system/maintenance.html break;
52
+ }
53
+ rewrite ^(.*)$ /503.html break;
54
+ }
55
+
56
+ if ($request_method !~ ^(GET|HEAD|PUT|POST|DELETE|OPTIONS)$ ){
57
+ return 405;
58
+ }
59
+
60
+ if (-f $document_root/system/maintenance.html) {
61
+ return 503;
62
+ }
63
+
64
+ location ~ \.(php|html)$ {
65
+ return 405;
66
+ }
67
+ }
@@ -0,0 +1,48 @@
1
+ working_directory "<%= current_path %>"
2
+ pid "<%= unicorn_pid %>"
3
+ stderr_path "<%= unicorn_log %>"
4
+ stdout_path "<%= unicorn_log %>"
5
+
6
+ listen "/tmp/unicorn.<%= application %>.sock"
7
+ worker_processes <%= unicorn_workers %>
8
+ timeout 30
9
+
10
+ preload_app true
11
+
12
+ before_exec do |server|
13
+ ENV["BUNDLE_GEMFILE"] = "<%= current_path %>/Gemfile"
14
+ end
15
+
16
+ before_fork do |server, worker|
17
+ # Disconnect since the database connection will not carry over
18
+ if defined? ActiveRecord::Base
19
+ ActiveRecord::Base.connection.disconnect!
20
+ end
21
+
22
+ # Quit the old unicorn process
23
+ old_pid = "#{server.config[:pid]}.oldbin"
24
+ if File.exists?(old_pid) && server.pid != old_pid
25
+ begin
26
+ Process.kill("QUIT", File.read(old_pid).to_i)
27
+ rescue Errno::ENOENT, Errno::ESRCH
28
+ # someone else did our job for us
29
+ end
30
+ end
31
+
32
+ if defined?(Resque)
33
+ Resque.redis.quit
34
+ end
35
+
36
+ sleep 1
37
+ end
38
+
39
+ after_fork do |server, worker|
40
+ # Start up the database connection again in the worker
41
+ if defined?(ActiveRecord::Base)
42
+ ActiveRecord::Base.establish_connection
43
+ end
44
+
45
+ if defined?(Resque)
46
+ Resque.redis = 'localhost:6379'
47
+ end
48
+ end
@@ -0,0 +1,84 @@
1
+ #!/bin/sh
2
+ ### BEGIN INIT INFO
3
+ # Provides: unicorn
4
+ # Required-Start: $remote_fs $syslog
5
+ # Required-Stop: $remote_fs $syslog
6
+ # Default-Start: 2 3 4 5
7
+ # Default-Stop: 0 1 6
8
+ # Short-Description: Manage unicorn server
9
+ # Description: Start, stop, restart unicorn server for a specific application.
10
+ ### END INIT INFO
11
+ set -e
12
+
13
+ # Feel free to change any of the following variables for your app:
14
+ TIMEOUT=${TIMEOUT-60}
15
+ APP_ROOT=<%= current_path %>
16
+ PID=<%= unicorn_pid %>
17
+ CMD="cd <%= current_path %>; bundle exec unicorn -D -c <%= unicorn_config %> -E production"
18
+ AS_USER=<%= unicorn_user %>
19
+ set -u
20
+
21
+ OLD_PIN="$PID.oldbin"
22
+
23
+ sig () {
24
+ test -s "$PID" && kill -$1 `cat $PID`
25
+ }
26
+
27
+ oldsig () {
28
+ test -s $OLD_PIN && kill -$1 `cat $OLD_PIN`
29
+ }
30
+
31
+ run () {
32
+ if [ "$(id -un)" = "$AS_USER" ]; then
33
+ eval $1
34
+ else
35
+ su -c "$1" - $AS_USER
36
+ fi
37
+ }
38
+
39
+ case "$1" in
40
+ start)
41
+ sig 0 && echo >&2 "Already running" && exit 0
42
+ run "$CMD"
43
+ ;;
44
+ stop)
45
+ sig QUIT && exit 0
46
+ echo >&2 "Not running"
47
+ ;;
48
+ force-stop)
49
+ sig TERM && exit 0
50
+ echo >&2 "Not running"
51
+ ;;
52
+ restart|reload)
53
+ sig USR2 && echo reloaded OK && exit 0
54
+ echo >&2 "Couldn't reload, starting '$CMD' instead"
55
+ run "$CMD"
56
+ ;;
57
+ upgrade)
58
+ if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
59
+ then
60
+ n=$TIMEOUT
61
+ while test -s $OLD_PIN && test $n -ge 0
62
+ do
63
+ printf '.' && sleep 1 && n=$(( $n - 1 ))
64
+ done
65
+ echo
66
+
67
+ if test $n -lt 0 && test -s $OLD_PIN
68
+ then
69
+ echo >&2 "$OLD_PIN still exists after $TIMEOUT seconds"
70
+ exit 1
71
+ fi
72
+ exit 0
73
+ fi
74
+ echo >&2 "Couldn't upgrade, starting '$CMD' instead"
75
+ run "$CMD"
76
+ ;;
77
+ reopen-logs)
78
+ sig USR1
79
+ ;;
80
+ *)
81
+ echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
82
+ exit 1
83
+ ;;
84
+ esac
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capistrano-nginx-unicorn
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ivan Tkalin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ prerelease: false
16
+ name: capistrano
17
+ version_requirements: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '2.0'
22
+ none: false
23
+ requirement: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ! '>='
26
+ - !ruby/object:Gem::Version
27
+ version: '2.0'
28
+ none: false
29
+ type: :runtime
30
+ - !ruby/object:Gem::Dependency
31
+ prerelease: false
32
+ name: rake
33
+ version_requirements: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ none: false
39
+ requirement: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ none: false
45
+ type: :development
46
+ description: Capistrano tasks for configuration and management nginx+unicorn combo
47
+ for zero downtime deployments of Rails applications. Configs can be copied to the
48
+ application using generators and easily customized.
49
+ email:
50
+ - itkalin@gmail.com
51
+ executables: []
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - .gitignore
56
+ - Gemfile
57
+ - LICENSE.txt
58
+ - README.md
59
+ - Rakefile
60
+ - capistrano-nginx-unicorn.gemspec
61
+ - lib/capistrano-nginx-unicorn.rb
62
+ - lib/capistrano/nginx_unicorn/tasks.rb
63
+ - lib/capistrano/nginx_unicorn/version.rb
64
+ - lib/generators/capistrano/nginx_unicorn/USAGE
65
+ - lib/generators/capistrano/nginx_unicorn/config_generator.rb
66
+ - lib/generators/capistrano/nginx_unicorn/templates/nginx_conf.erb
67
+ - lib/generators/capistrano/nginx_unicorn/templates/unicorn.rb.erb
68
+ - lib/generators/capistrano/nginx_unicorn/templates/unicorn_init.erb
69
+ homepage: https://github.com/ivalkeen/capistrano-nginx-unicorn
70
+ licenses: []
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ segments:
81
+ - 0
82
+ hash: -2151274067948030801
83
+ none: false
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ segments:
90
+ - 0
91
+ hash: -2151274067948030801
92
+ none: false
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 1.8.23
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: Create and manage nginx+unicorn configs from capistrano
99
+ test_files: []