capistrano-unicorn-nginx 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []