capistrano-unicorn-nginx 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 334f1a9b32d324cb61abc30de2f70652e7e5d01c
4
+ data.tar.gz: 491c76d4ccd11448b9603a55c699284bd25e48e9
5
+ SHA512:
6
+ metadata.gz: a5ead97ec48101db2a2a10143ed0c2b4a39094ae47b051f37eb007a8b580735aa4b05626b4f7b6e92f29ff26b3b1f6701481031433b2980bb16879723389b72d
7
+ data.tar.gz: 26249b36ecb21b3c990d0f8aa40c02044d6bff1813f88babc066c722285cf85439dada54793248239d9cea3a1966969e58f59752dc7f37e2703d2a980b3a0773
data/.gitignore ADDED
@@ -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 *.gemspec
4
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2014 Bruno Sutic
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the "Software"),
5
+ to deal in the Software without restriction, including without limitation
6
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
7
+ and/or sell copies of the Software, and to permit persons to whom the
8
+ Software is furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included
11
+ in all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
18
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
19
+ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,189 @@
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
+ * creates logrotate record to rotate application logs
12
+
13
+ Provides several capistrano variables for easy customization.
14
+ Also, for full customization, all configs can be copied to the application using generators.
15
+
16
+ ## Installation
17
+
18
+ Add this line to your application's Gemfile:
19
+
20
+ gem 'capistrano-nginx-unicorn', require: false, group: :development
21
+
22
+ And then execute:
23
+
24
+ $ bundle
25
+
26
+ Or install it yourself as:
27
+
28
+ $ gem install capistrano-nginx-unicorn
29
+
30
+ ## Usage
31
+
32
+ Add this line to your `deploy.rb`
33
+
34
+ require 'capistrano-nginx-unicorn'
35
+
36
+ Note, that following capistrano variables should be defined:
37
+
38
+ application
39
+ current_path
40
+ shared_path
41
+ user
42
+
43
+ You can check that new tasks are available (`cap -T`):
44
+
45
+ for nginx:
46
+
47
+ # add and enable application to nginx
48
+ cap nginx:setup
49
+
50
+ # reload nginx configuration
51
+ cap nginx:reload
52
+
53
+ and for unicorn:
54
+
55
+ # create unicorn configuration and init script
56
+ cap unicorn:setup
57
+
58
+ # start unicorn
59
+ cap unicorn:start
60
+
61
+ # stop unicorn
62
+ cap unicorn:stop
63
+
64
+ # reload unicorn with no downtime
65
+ # old workers will process new request until new master is fully loaded
66
+ # then old workers will be automatically killed and new workers will start processing requests
67
+ cap unicorn:restart
68
+
69
+ and shared:
70
+
71
+ # create logrotate record to rotate application logs
72
+ cap logrotate
73
+
74
+ There is no need to execute any of these tasks manually.
75
+ They will be called automatically on different deploy stages:
76
+
77
+ * `nginx:setup`, `nginx:reload`, `unicorn:setup` and `logrotate` are hooked to `deploy:setup`
78
+ * `unicorn:restart` is hooked to `deploy:restart`
79
+
80
+ This means that if you run `cap deploy:setup`,
81
+ nginx and unicorn will be automatically configured.
82
+ And after each deploy, unicorn will be automatically reloaded.
83
+
84
+ However, if you changed variables or customized templates,
85
+ you can run any of these tasks to update configuration.
86
+
87
+ ## Customization
88
+
89
+ ### Using variables
90
+
91
+ You can customize nginx and unicorn configs using capistrano variables:
92
+
93
+
94
+ ```ruby
95
+ # path to customized templates (see below for details)
96
+ # default value: "config/deploy/templates"
97
+ set :templates_path, "config/deploy/templates"
98
+
99
+ # server name for nginx, default value: no (will be prompted if not set)
100
+ # set this to your site name as it is visible from outside
101
+ # this will allow 1 nginx to serve several sites with different `server_name`
102
+ set :nginx_server_name, "example.com"
103
+
104
+ # path, where unicorn pid file will be stored
105
+ # default value: `"#{current_path}/tmp/pids/unicorn.pid"`
106
+ set :unicorn_pid, "#{current_path}/tmp/pids/unicorn.pid"
107
+
108
+ # path, where nginx pid file will be stored (used in logrotate recipe)
109
+ # default value: `"/run/nginx.pid"`
110
+ set :nginx_pid, "/run/nginx.pid"
111
+
112
+ # path, where unicorn config file will be stored
113
+ # default value: `"#{shared_path}/config/unicorn.rb"`
114
+ set :unicorn_config, "#{shared_path}/config/unicorn.rb"
115
+
116
+ # path, where unicorn log file will be stored
117
+ # default value: `"#{shared_path}/config/unicorn.rb"`
118
+ set :unicorn_log, "#{shared_path}/config/unicorn.rb"
119
+
120
+ # user name to run unicorn
121
+ # default value: `user` (user varibale defined in your `deploy.rb`)
122
+ set :unicorn_user, "user"
123
+
124
+ # number of unicorn workers
125
+ # default value: no (will be prompted if not set)
126
+ set :unicorn_workers, 4
127
+
128
+ # if set, nginx will be configured to 443 port and port 80 will be auto rewritten to 443
129
+ # also, on `nginx:setup`, paths to ssl certificate and key will be configured
130
+ # and certificate file and key will be copied to `/etc/ssl/certs` and `/etc/ssl/private/` directories
131
+ # default value: false
132
+ set :nginx_use_ssl, false
133
+
134
+ # if set, it will ask to upload certificates from a local path. Otherwise, it will expect
135
+ # the certificate and key defined in the next 2 variables to be already in the server.
136
+ set :nginx_upload_local_certificate, { true }
137
+
138
+ # remote file name of the certificate, only makes sense if `nginx_use_ssl` is set
139
+ # default value: `nginx_server_name + ".crt"`
140
+ set :nginx_ssl_certificate, "#{nginx_server_name}.crt"
141
+
142
+ # remote file name of the certificate, only makes sense if `nginx_use_ssl` is set
143
+ # default value: `nginx_server_name + ".key"`
144
+ set :nginx_ssl_certificate_key, "#{nginx_server_name}.key"
145
+
146
+ # local path to file with certificate, only makes sense if `nginx_use_ssl` is set
147
+ # this file will be copied to remote server
148
+ # default value: none (will be prompted if not set)
149
+ set :nginx_ssl_certificate_local_path, "/home/ivalkeen/ssl/myssl.cert"
150
+
151
+ # local path to file with certificate key, only makes sense if `nginx_use_ssl` is set
152
+ # this file will be copied to remote server
153
+ # default value: none (will be prompted if not set)
154
+ set :nginx_ssl_certificate_key_local_path, "/home/ivalkeen/ssl/myssl.key"
155
+ ```
156
+
157
+ For example, of you site name is `example.com` and you want to use 8 unicorn workers,
158
+ your `deploy.rb` will look like this:
159
+
160
+ ```ruby
161
+ set :server_name, "example.com"
162
+ set :unicorn_workers, 4
163
+ require 'capistrano-nginx-unicorn'
164
+ ```
165
+
166
+ ### Template Customization
167
+
168
+ If you want to change default templates, you can generate them using `rails generator`
169
+
170
+ rails g capistrano:nginx_unicorn:config
171
+
172
+ This will copy default templates to `config/deploy/templates` directory,
173
+ so you can customize them as you like, and capistrano tasks will use this templates instead of default.
174
+
175
+ You can also provide path, where to generate templates:
176
+
177
+ rails g capistrano:nginx_unicorn:config config/templates
178
+
179
+ # TODO:
180
+
181
+ * add tests
182
+
183
+ ## Contributing
184
+
185
+ 1. Fork it
186
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
187
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
188
+ 4. Push to the branch (`git push origin my-new-feature`)
189
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'capistrano/unicorn_nginx/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "capistrano-unicorn-nginx"
8
+ gem.version = Capistrano::UnicornNginx::VERSION
9
+ gem.authors = ["Bruno Sutic"]
10
+ gem.email = ["bruno.sutic@gmail.com"]
11
+ gem.description = <<-EOF.gsub(/^\s+/, '')
12
+ Capistrano tasks for automatic and sensible unicorn + nginx configuraion.
13
+
14
+ Enables zero downtime deployments of Rails applications. Configs can be
15
+ copied to the application using generators and easily customized.
16
+
17
+ Works *only* with Capistrano 3+. For Capistrano 2 try version 0.0.8 of this
18
+ gem: http://rubygems.org/gems/capistrano-nginx-unicorn
19
+ EOF
20
+ gem.summary = "Create and manage unicorn + nginx configs from capistrano"
21
+ gem.homepage = "https://github.com/bruno-/capistrano-unicorn-nginx"
22
+
23
+ gem.files = `git ls-files`.split($/)
24
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
25
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
26
+ gem.require_paths = ["lib"]
27
+
28
+ gem.add_dependency "capistrano", ">= 3.1"
29
+ gem.add_dependency "sshkit", ">= 1.2.0"
30
+
31
+ gem.add_development_dependency "rake"
32
+ end
File without changes
@@ -0,0 +1,68 @@
1
+ require 'capistrano/unicorn_nginx/helpers'
2
+
3
+ include Capistrano::UnicornNginx::Helpers
4
+
5
+ namespace :load do
6
+ task :defaults do
7
+ set :templates_path, "config/deploy/templates"
8
+ set :nginx_server_name, -> { ask(:nginx_server_name, "Nginx server name: ") }
9
+ set :nginx_config_name, -> { "#{fetch(:application)}_#{fetch(:stage)}" }
10
+ set :nginx_use_ssl, false
11
+ set :nginx_pid, "/run/nginx.pid"
12
+ set :nginx_ssl_certificate, -> { "#{fetch(:nginx_server_name)}.crt" }
13
+ set :nginx_ssl_certificate_key, -> { "#{fetch(:nginx_server_name)}.key" }
14
+ set :nginx_upload_local_certificate, true
15
+ set :nginx_ssl_certificate_local_path, -> { ask(:nginx_ssl_certificate_local_path, "Local path to ssl certificate: ") }
16
+ set :nginx_ssl_certificate_key_local_path, -> { ask(:nginx_ssl_certificate_key_local_path, "Local path to ssl certificate key: ") }
17
+ set :nginx_config_path, "/etc/nginx/sites-available"
18
+ end
19
+ end
20
+
21
+ namespace :nginx do
22
+ desc "Setup nginx configuration"
23
+ task :setup do
24
+ on roles(:web) do
25
+ next if file_exists? "#{fetch(:nginx_config_path)}/#{fetch(:nginx_config_name)}"
26
+
27
+ execute :mkdir, "-p", shared_path.join("log")
28
+ template("nginx_conf.erb", "/tmp/nginx_#{fetch(:nginx_config_name)}")
29
+ if fetch(:nginx_config_path) == "/etc/nginx/sites-available"
30
+ sudo :mv, "/tmp/nginx_#{fetch(:nginx_config_name)} /etc/nginx/sites-available/#{fetch(:nginx_config_name)}"
31
+ sudo :ln, "-fs", "/etc/nginx/sites-available/#{fetch(:nginx_config_name)} /etc/nginx/sites-enabled/#{fetch(:nginx_config_name)}"
32
+ else
33
+ sudo :mv, "/tmp/#{fetch(:nginx_config_name)} #{fetch(:nginx_config_path)}/#{fetch(:nginx_config_name)}"
34
+ end
35
+ end
36
+ end
37
+
38
+ desc "Setup nginx ssl certs"
39
+ task :setup_ssl do
40
+ on roles(:web) do
41
+ if fetch(:nginx_use_ssl)
42
+ if fetch(:nginx_upload_local_certificate)
43
+ upload! fetch(:nginx_ssl_certificate_local_path), "/tmp/#{fetch(:nginx_ssl_certificate)}"
44
+ upload! fetch(:nginx_ssl_certificate_key_local_path), "/tmp/#{fetch(:nginx_ssl_certificate_key)}"
45
+
46
+ sudo :mv, "/tmp/#{fetch(:nginx_ssl_certificate)} /etc/ssl/certs/#{fetch(:nginx_ssl_certificate)}"
47
+ sudo :mv, "/tmp/#{fetch(:nginx_ssl_certificate_key)} /etc/ssl/private/#{fetch(:nginx_ssl_certificate_key)}"
48
+ end
49
+
50
+ sudo :chown, "root:root /etc/ssl/certs/#{fetch(:nginx_ssl_certificate)}"
51
+ sudo :chown, "root:root /etc/ssl/private/#{fetch(:nginx_ssl_certificate_key)}"
52
+ end
53
+ end
54
+ end
55
+
56
+ desc "Reload nginx configuration"
57
+ task :reload do
58
+ on roles(:web) do
59
+ sudo "/etc/init.d/nginx reload"
60
+ end
61
+ end
62
+ end
63
+
64
+ namespace :deploy do
65
+ after :started, "nginx:setup"
66
+ after :started, "nginx:setup_ssl"
67
+ after :publishing, "nginx:reload"
68
+ end
@@ -0,0 +1,56 @@
1
+ require 'capistrano/unicorn_nginx/helpers'
2
+
3
+ include Capistrano::UnicornNginx::Helpers
4
+
5
+ namespace :load do
6
+ task :defaults do
7
+ set :unicorn_service_name, -> { "unicorn_#{fetch(:application)}_#{fetch(:stage)}" }
8
+ set :templates_path, "config/deploy/templates"
9
+ set :unicorn_pid, -> { shared_path.join("pids/unicorn.pid") }
10
+ set :unicorn_config, -> { shared_path.join("config/unicorn.rb") }
11
+ set :unicorn_log, -> { shared_path.join("log/unicorn.log") }
12
+ set :unicorn_user, -> { fetch(:user) }
13
+ set :unicorn_workers, 2
14
+ end
15
+ end
16
+
17
+ namespace :unicorn do
18
+ desc "Setup Unicorn initializer"
19
+ task :setup_initializer do
20
+ on roles(:app) do
21
+ next if file_exists? "/etc/init.d/#{fetch(:unicorn_service_name)}"
22
+
23
+ template "unicorn_init.erb", "/tmp/unicorn_init"
24
+ execute :chmod, "+x", "/tmp/unicorn_init"
25
+ sudo :mv, "/tmp/unicorn_init /etc/init.d/#{fetch(:unicorn_service_name)}"
26
+ sudo "update-rc.d -f #{fetch(:unicorn_service_name)} defaults"
27
+ end
28
+ end
29
+
30
+ desc "Setup Unicorn app configuration"
31
+ task :setup_app_config do
32
+ on roles(:app) do
33
+ next if file_exists? fetch(:unicorn_config)
34
+
35
+ execute :mkdir, "-p", shared_path.join("config")
36
+ execute :mkdir, "-p", shared_path.join("log")
37
+ execute :mkdir, "-p", shared_path.join("pids")
38
+ template "unicorn.rb.erb", fetch(:unicorn_config)
39
+ end
40
+ end
41
+
42
+ %w[start stop restart].each do |command|
43
+ desc "#{command} unicorn"
44
+ task command do
45
+ on roles(:app) do
46
+ execute "service #{fetch(:unicorn_service_name)} #{command}"
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ namespace :deploy do
53
+ after :updated, "unicorn:setup_initializer"
54
+ after :updated, "unicorn:setup_app_config"
55
+ after :publishing, "unicorn:restart"
56
+ end
@@ -0,0 +1,2 @@
1
+ load File.expand_path("../tasks/nginx.rake", __FILE__)
2
+ load File.expand_path("../tasks/unicorn.rake", __FILE__)
@@ -0,0 +1,27 @@
1
+ require 'erb'
2
+
3
+ module Capistrano
4
+ module UnicornNginx
5
+ module Helpers
6
+
7
+ def bundle_unicorn(*args)
8
+ SSHKit::Command.new(:bundle, :exec, :unicorn, args).to_command
9
+ end
10
+
11
+ def template(template_name, target)
12
+ config_file = "#{fetch(:templates_path)}/#{template_name}"
13
+ # if no customized file, proceed with default
14
+ unless File.exists?(config_file)
15
+ config_file = File.join(File.dirname(__FILE__), "../../generators/capistrano/unicorn_nginx/templates/#{template_name}")
16
+ end
17
+ config_stream = StringIO.new(ERB.new(File.read(config_file)).result(binding))
18
+ upload! config_stream, target
19
+ end
20
+
21
+ def file_exists?(path)
22
+ test "[ -e #{path} ]"
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,5 @@
1
+ module Capistrano
2
+ module UnicornNginx
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
+ bundle exec rails generate capistrano:unicorn_nginx:config [path]
4
+
5
+ The default path is "config/deploy/templates". You can override it like so:
6
+
7
+ bundle rails generate capistrano:unicorn_nginx: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,20 @@
1
+ module Capistrano
2
+ module UnicornNginx
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
+ copy_file "logrotate.erb", "#{templates_path}/logrotate.erb"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,78 @@
1
+ upstream unicorn_<%= fetch(:nginx_config_name) %> {
2
+ server unix:/tmp/unicorn.<%= fetch(:nginx_config_name) %>.sock fail_timeout=0;
3
+ }
4
+
5
+ <% if fetch(:nginx_use_ssl) %>
6
+ server {
7
+ listen 80;
8
+ rewrite ^(.*) https://$host$1 permanent;
9
+ }
10
+ <% end %>
11
+
12
+ server {
13
+ <% if fetch(:nginx_use_ssl) %>
14
+ listen 443;
15
+ ssl on;
16
+ ssl_certificate /etc/ssl/certs/<%= fetch(:nginx_ssl_certificate) %>;
17
+ ssl_certificate_key /etc/ssl/private/<%= fetch(:nginx_ssl_certificate_key) %>;
18
+ <% else %>
19
+ listen 80;
20
+ <% end %>
21
+
22
+ client_max_body_size 4G;
23
+ keepalive_timeout 10;
24
+
25
+ error_page 500 502 504 /500.html;
26
+ error_page 503 @503;
27
+
28
+ server_name <%= fetch(:nginx_server_name) %>;
29
+ root <%= current_path %>/public;
30
+ try_files $uri/index.html $uri @unicorn_<%= fetch(:nginx_config_name) %>;
31
+
32
+ location @unicorn_<%= fetch(:nginx_config_name) %> {
33
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
34
+ proxy_set_header Host $http_host;
35
+ proxy_redirect off;
36
+ <% if fetch(:nginx_use_ssl) %>
37
+ proxy_set_header X-Forwarded-Proto https;
38
+ <% end %>
39
+ proxy_pass http://unicorn_<%= fetch(:nginx_config_name) %>;
40
+ # limit_req zone=one;
41
+ access_log <%= shared_path %>/log/nginx.access.log;
42
+ error_log <%= shared_path %>/log/nginx.error.log;
43
+ }
44
+
45
+ location ^~ /assets/ {
46
+ gzip_static on;
47
+ expires max;
48
+ add_header Cache-Control public;
49
+ }
50
+
51
+ location = /50x.html {
52
+ root html;
53
+ }
54
+
55
+ location = /404.html {
56
+ root html;
57
+ }
58
+
59
+ location @503 {
60
+ error_page 405 = /system/maintenance.html;
61
+ if (-f $document_root/system/maintenance.html) {
62
+ rewrite ^(.*)$ /system/maintenance.html break;
63
+ }
64
+ rewrite ^(.*)$ /503.html break;
65
+ }
66
+
67
+ if ($request_method !~ ^(GET|HEAD|PUT|POST|DELETE|OPTIONS)$ ){
68
+ return 405;
69
+ }
70
+
71
+ if (-f $document_root/system/maintenance.html) {
72
+ return 503;
73
+ }
74
+
75
+ location ~ \.(php|html)$ {
76
+ return 405;
77
+ }
78
+ }
@@ -0,0 +1,48 @@
1
+ working_directory "<%= current_path %>"
2
+ pid "<%= fetch(:unicorn_pid) %>"
3
+ stderr_path "<%= fetch(:unicorn_log) %>"
4
+ stdout_path "<%= fetch(:unicorn_log) %>"
5
+
6
+ listen "/tmp/unicorn.<%= fetch(:nginx_config_name) %>.sock"
7
+ worker_processes <%= fetch(: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,87 @@
1
+ #!/bin/bash
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=<%= fetch(:unicorn_pid) %>
17
+
18
+ CMD="cd $APP_ROOT && <%= bundle_unicorn("-D -c", fetch(:unicorn_config), "-E", fetch(:stage)) %>"
19
+
20
+ AS_USER=<%= fetch(:unicorn_user) %>
21
+ set -u
22
+
23
+ OLD_PIN="$PID.oldbin"
24
+
25
+ sig () {
26
+ test -s "$PID" && kill -$1 `cat $PID`
27
+ }
28
+
29
+ oldsig () {
30
+ test -s $OLD_PIN && kill -$1 `cat $OLD_PIN`
31
+ }
32
+
33
+ run () {
34
+ if [ "$(id -un)" = "$AS_USER" ]; then
35
+ eval $1
36
+ else
37
+ su -c "$1" - $AS_USER
38
+ fi
39
+ }
40
+
41
+ case "$1" in
42
+ start)
43
+ sig 0 && echo >&2 "Already running" && exit 0
44
+ run "$CMD"
45
+ ;;
46
+ stop)
47
+ sig QUIT && exit 0
48
+ echo >&2 "Not running"
49
+ ;;
50
+ force-stop)
51
+ sig TERM && exit 0
52
+ echo >&2 "Not running"
53
+ ;;
54
+ restart|reload)
55
+ sig USR2 && echo reloaded OK && exit 0
56
+ echo >&2 "Couldn't reload, starting '$CMD' instead"
57
+ run "$CMD"
58
+ ;;
59
+ upgrade)
60
+ if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
61
+ then
62
+ n=$TIMEOUT
63
+ while test -s $OLD_PIN && test $n -ge 0
64
+ do
65
+ printf '.' && sleep 1 && n=$(( $n - 1 ))
66
+ done
67
+ echo
68
+
69
+ if test $n -lt 0 && test -s $OLD_PIN
70
+ then
71
+ echo >&2 "$OLD_PIN still exists after $TIMEOUT seconds"
72
+ exit 1
73
+ fi
74
+ exit 0
75
+ fi
76
+ echo >&2 "Couldn't upgrade, starting '$CMD' instead"
77
+ run "$CMD"
78
+ ;;
79
+ reopen-logs)
80
+ sig USR1
81
+ ;;
82
+ *)
83
+ echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
84
+ exit 1
85
+ ;;
86
+ esac
87
+
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capistrano-unicorn-nginx
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Bruno Sutic
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capistrano
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '3.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sshkit
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.2.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.2.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: |
56
+ Capistrano tasks for automatic and sensible unicorn + nginx configuraion.
57
+ Enables zero downtime deployments of Rails applications. Configs can be
58
+ copied to the application using generators and easily customized.
59
+ Works *only* with Capistrano 3+. For Capistrano 2 try version 0.0.8 of this
60
+ gem: http://rubygems.org/gems/capistrano-nginx-unicorn
61
+ email:
62
+ - bruno.sutic@gmail.com
63
+ executables: []
64
+ extensions: []
65
+ extra_rdoc_files: []
66
+ files:
67
+ - ".gitignore"
68
+ - Gemfile
69
+ - LICENSE.md
70
+ - README.md
71
+ - Rakefile
72
+ - capistrano-unicorn-nginx.gemspec
73
+ - lib/capistrano-unicorn-nginx.rb
74
+ - lib/capistrano/tasks/nginx.rake
75
+ - lib/capistrano/tasks/unicorn.rake
76
+ - lib/capistrano/unicorn_nginx.rb
77
+ - lib/capistrano/unicorn_nginx/helpers.rb
78
+ - lib/capistrano/unicorn_nginx/version.rb
79
+ - lib/generators/capistrano/unicorn_nginx/USAGE.md
80
+ - lib/generators/capistrano/unicorn_nginx/config_generator.rb
81
+ - lib/generators/capistrano/unicorn_nginx/templates/nginx_conf.erb
82
+ - lib/generators/capistrano/unicorn_nginx/templates/unicorn.rb.erb
83
+ - lib/generators/capistrano/unicorn_nginx/templates/unicorn_init.erb
84
+ homepage: https://github.com/bruno-/capistrano-unicorn-nginx
85
+ licenses: []
86
+ metadata: {}
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 2.1.5
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: Create and manage unicorn + nginx configs from capistrano
107
+ test_files: []