capistrano-pumaio 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Capistrano Recipes for Puma
2
2
 
3
- This gem provides recipes for [Puma](http://puma.io) to setup runit and monit
3
+ This gem provides recipes for [Puma](http://puma.io) to setup [runit](smarden.org/runit/), [monit](http://mmonit.com/monit) and [nginx](http://nginx.org) for both running and monitoring puma and a nginx site connected to a puma socket
4
4
 
5
5
  ## Usage
6
6
 
@@ -60,7 +60,7 @@ cap puma:runit:stop # Stop Puma runit-service
60
60
  To use runit to start/stop/restart services instead of monit, use the example below.
61
61
 
62
62
  ```ruby
63
- # stop before deployment
63
+ # stop before deployment
64
64
  # (must be done after monit has stopped monitoring the task. If not, the service will be restarted by monit)
65
65
  before "monit:unmonitor", "puma:runit:stop"
66
66
  # start before enabling monitor
@@ -69,7 +69,44 @@ before "monit:monitor", "puma:runit:start"
69
69
  before "monit:monitor", "puma:runit:restart"
70
70
  ```
71
71
 
72
- ## Configuration
72
+ ### nginx
73
+
74
+ #### Specific to puma and nginx for the application:
75
+
76
+ ```ruby
77
+ cap puma:nginx:disable # Disable nginx site for the application
78
+ cap puma:nginx:enable # Enable nginx site for the application
79
+ cap puma:nginx:purge # Purge nginx site config for the application
80
+ cap puma:nginx:setup # Parses and uploads nginx configuration for this app.
81
+ ```
82
+
83
+ #### Global nginx commands
84
+
85
+ ```ruby
86
+ cap nginx:restart # Restart nginx
87
+ cap nginx:start # Start nginx
88
+ cap nginx:status # Show nginx status
89
+ cap nginx:stop # Stop nginx
90
+ ```
91
+
92
+ #### Configuration for nginx
93
+
94
+ See nginx.rb for configuration options.
95
+
96
+ #### Notes when using nginx
97
+
98
+
99
+ puma:nginx:setup is setup to run automatically after deploy:setup, and you will be asked if you want to enable the site.
100
+
101
+ If you do not enable the site during setup, be sure to run the following two commands when you want to enable your site:
102
+
103
+ ```ruby
104
+ cap puma:nginx:enable
105
+ cap nginx:restart
106
+ ```
107
+
108
+
109
+ ## Configuration of Monit/Runit
73
110
 
74
111
  See puma/config.rb for default options, and ovveride any in your deploy.rb file.
75
112
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.7
1
+ 0.0.8
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "capistrano-pumaio"
8
- s.version = "0.0.7"
8
+ s.version = "0.0.8"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Leif Ringstad"]
12
- s.date = "2013-07-29"
12
+ s.date = "2013-07-31"
13
13
  s.description = "Capistrano recipes for puma using runit and monit."
14
14
  s.email = "leifcr@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -27,8 +27,11 @@ Gem::Specification.new do |s|
27
27
  "lib/capistrano/puma.rb",
28
28
  "lib/capistrano/puma/config.rb",
29
29
  "lib/capistrano/puma/monit.rb",
30
+ "lib/capistrano/puma/nginx.rb",
30
31
  "lib/capistrano/puma/runit.rb",
31
32
  "templates/monit/puma.conf.erb",
33
+ "templates/nginx/application.conf.erb",
34
+ "templates/nginx/htpasswd.erb",
32
35
  "templates/runit/config.rb.erb",
33
36
  "templates/runit/control-q.erb",
34
37
  "templates/runit/finish.erb",
@@ -0,0 +1,125 @@
1
+ Capistrano::Configuration.instance.load do
2
+
3
+ # Where your nginx lives. Usually /opt/nginx or /usr/local/nginx for source compiled.
4
+ _cset :nginx_sites_enabled_path, "/etc/nginx/sites-enabled"
5
+
6
+ # simple authorization in nginx recipe
7
+ # Remember NOT to share your deployment file in case you have sensitive passwords stored in it...
8
+ # This is added to make it easier to deploy staging sites with a simple htpasswd.
9
+
10
+ _cset :nginx_use_simple_auth, false
11
+ _cset :nginx_simple_auth_message, "Restricted site"
12
+ _cset :nginx_simple_auth_user, "user"
13
+ _cset :nginx_simple_auth_password, "password"
14
+ _cset :nginx_simple_auth_salt, (0...8).map{ ('a'..'z').to_a[rand(26)] }.join
15
+
16
+ # Server names. Defaults to application name.
17
+ _cset :server_names, "#{application}_#{Capistrano::BaseHelper.environment}" unless exists?(:server_names)
18
+
19
+ # Path to the nginx erb template to be parsed before uploading to remote
20
+ _cset :nginx_local_config, File.join(File.expand_path(File.join(File.dirname(__FILE__),"../../../templates", "nginx", )), "application.conf.erb")
21
+
22
+ # Path to where your remote config will reside (I use a directory sites inside conf)
23
+ _cset :nginx_remote_config, defer {File.join("#{fetch(:shared_path)}", "config", "nginx_#{fetch(:application)}_#{Capistrano::BaseHelper.environment}.conf")}
24
+
25
+ # Path to local htpasswd template file
26
+ _cset :nginx_local_htpasswd, defer {File.join(File.expand_path(File.join(File.dirname(__FILE__),"../../../templates", "nginx", )), "htpasswd.erb")}
27
+
28
+ # Path to remote htpasswd file
29
+ _cset :nginx_remote_htpasswd, defer {File.join("#{fetch(:shared_path)}", "config", ".htpasswd")}
30
+
31
+ _cset :nginx_sites_enabled_symlink, defer {File.join(nginx_sites_enabled_path, "#{fetch(:application)}_#{Capistrano::BaseHelper.environment}")}
32
+
33
+ _cset :nginx_uses_http, true
34
+ _cset :nginx_uses_ssl, false
35
+ _cset :nginx_port, 80
36
+
37
+ _cset :nginx_log_path, File.join("/var", "log", "nginx", "#{fetch(:application)}")
38
+
39
+ _cset :nginx_client_max_body_size, "10M"
40
+
41
+ _cset :nginx_ssl_port, 443
42
+ _cset :nginx_ssl_use_simple_auth, false
43
+ _cset :nginx_ssl_client_max_body_size, "10M"
44
+ _cset :nginx_ssl_public_crt, File.join("/etc", "certs", "server.crt")
45
+ _cset :nginx_ssl_private_key, File.join("/etc", "certs", "server.key")
46
+
47
+ # Nginx tasks are not *nix agnostic, they assume you're using Debian/Ubuntu.
48
+ # Override them as needed.
49
+ namespace :puma do
50
+ namespace :nginx do
51
+ desc "Parses and uploads nginx configuration for this app."
52
+ task :setup, :roles => :app , :except => { :no_release => true } do
53
+
54
+ Capistrano::BaseHelper.generate_and_upload_config(fetch(:nginx_local_config), fetch(:nginx_remote_config))
55
+
56
+ # if auth is enabled, upload htpasswd file
57
+ # Since passwords are stored in plaintext in the deployment file, you should use simple auth with care.
58
+ # It is generally better to implement a full authorization stack like oauth, use devise on rails, or other login/auth system
59
+ if fetch(:nginx_use_simple_auth) or fetch(:nginx_ssl_use_simple_auth)
60
+ if Capistrano::CLI.ui.agree("Create .htpasswd configuration file? [Yn]")
61
+ Capistrano::BaseHelper.generate_and_upload_config(fetch(:nginx_local_htpasswd), fetch(:nginx_remote_htpasswd))
62
+ else
63
+ set :nginx_use_simple_auth, false
64
+ set :nginx_ssl_use_simple_auth, false
65
+ end
66
+ end
67
+
68
+ # create log path, must sudo since path can have root-only permissions
69
+ run "#{sudo} mkdir -p /var/log/nginx/#{fetch(:application)} && #{sudo} chown root:www-data /var/log/nginx/#{fetch(:application)}"
70
+ end
71
+
72
+ desc "Enable nginx site for the application"
73
+ task :enable, :roles => :app , :except => { :no_release => true } do
74
+ # symlink to nginx site configuration file
75
+ run("[ -h #{fetch(:nginx_sites_enabled_symlink)} ] || #{sudo} ln -sf #{fetch(:nginx_remote_config)} #{fetch(:nginx_sites_enabled_symlink)}")
76
+ end
77
+
78
+ desc "Disable nginx site for the application"
79
+ task :disable, :roles => :app , :except => { :no_release => true } do
80
+ run("[ ! -h #{fetch(:nginx_sites_enabled_symlink)} ] || #{sudo} rm -f #{fetch(:nginx_sites_enabled_symlink)}")
81
+ end
82
+
83
+ desc "Purge nginx site config for the application"
84
+ task :purge, :roles => :app , :except => { :no_release => true } do
85
+ run("[ ! -h #{fetch(:nginx_sites_enabled_symlink)} ] || #{sudo} rm -f #{fetch(:nginx_sites_enabled_symlink)}")
86
+ # must restart nginx to make sure site is disabled when config is purge
87
+ run "#{sudo} service nginx restart"
88
+ run "rm -f #{fetch(:nginx_remote_htpasswd)} && rm -f #{fetch(:nginx_remote_config)}"
89
+ end
90
+
91
+ end
92
+ end
93
+
94
+ namespace :nginx do
95
+ desc "Restart nginx"
96
+ task :restart, :roles => :app , :except => { :no_release => true } do
97
+ run "#{sudo} service nginx restart"
98
+ end
99
+
100
+ desc "Stop nginx"
101
+ task :stop, :roles => :app , :except => { :no_release => true } do
102
+ run "#{sudo} service nginx stop"
103
+ end
104
+
105
+ desc "Start nginx"
106
+ task :start, :roles => :app , :except => { :no_release => true } do
107
+ run "#{sudo} service nginx start"
108
+ end
109
+
110
+ desc "Show nginx status"
111
+ task :status, :roles => :app , :except => { :no_release => true } do
112
+ run "#{sudo} service nginx status"
113
+ end
114
+
115
+ end
116
+
117
+ after 'deploy:setup' do
118
+ puma.nginx.setup if Capistrano::CLI.ui.agree("Create nginx configuration file? [Yn]")
119
+ if Capistrano::CLI.ui.agree("Enable site in nginx? [Yn]")
120
+ puma.nginx.enable
121
+ nginx.restart # must restart after enable for nginx to pickup new site
122
+ end
123
+ end
124
+
125
+ end
@@ -0,0 +1,220 @@
1
+ # Nginx configuration
2
+ # <% c = Capistrano::BaseHelper::get_capistrano_instance %>
3
+ # <%= "#{c.fetch(:application)} running as #{c.fetch(:user)} in environment #{Capistrano::BaseHelper.environment}" %>
4
+ # <%
5
+ upstream_name = "#{c.fetch(:application)}_#{Capistrano::BaseHelper.environment}_app_server"
6
+ upstream_name_ssl = "#{c.fetch(:application)}_#{Capistrano::BaseHelper.environment}_app_server_ssl"
7
+ %>
8
+ #
9
+
10
+ upstream <%= upstream_name %> {
11
+ server unix:<%= File.join("#{c.fetch(:shared_path)}","sockets", "puma.sock") %> fail_timeout=0;
12
+ }
13
+
14
+ <% if c.fetch(:nginx_uses_http) %>
15
+ #
16
+ # HTTP server configuration
17
+ #
18
+ server {
19
+ listen <%= c.fetch(:nginx_port) %>;
20
+ client_max_body_size <%= c.fetch(:nginx_client_max_body_size) %>;
21
+ server_name <%= c.fetch(:server_names) %>;
22
+
23
+ # ~2 seconds is often enough for most folks to parse HTML/CSS and
24
+ # retrieve needed images/icons/frames, connections are cheap in
25
+ # nginx so increasing this is generally safe...
26
+ # 8 seconds might be needed for some mobile devs
27
+ keepalive_timeout 8;
28
+
29
+ # path for static files
30
+ root <%= c.fetch(:deploy_to) %>/current/public;
31
+ access_log <%= c.fetch(:nginx_log_path) %>/<%= Capistrano::BaseHelper.environment %>.access.log;
32
+ error_log <%= c.fetch(:nginx_log_path) %>/<%= Capistrano::BaseHelper.environment %>.error.log info;
33
+
34
+ # this rewrites all the requests to the maintenance.html
35
+ # page if it exists in the doc root. This is for capistrano's
36
+ # disable web task
37
+ if (-f $document_root/system/maintenance.html) {
38
+ rewrite ^(.*)$ /system/maintenance.html last;
39
+ break;
40
+ }
41
+
42
+ location / {
43
+ <% if c.fetch(:nginx_use_simple_auth) %>
44
+ auth_basic "<%= c.fetch(:nginx_simple_auth_message) %>";
45
+ auth_basic_user_file <%= c.fetch(:nginx_remote_htpasswd) %>;
46
+ <% end %>
47
+
48
+ # needed to forward user's IP address to rails
49
+ proxy_set_header X-Real-IP $remote_addr;
50
+
51
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
52
+ proxy_set_header Host $http_host;
53
+
54
+ # if the request is for a static resource, nginx should serve it directly
55
+ # and add a far future expires header to it, making the browser
56
+ # cache the resource and navigate faster over the website.
57
+ location ~ ^/(assets)/.+-([0-9a-zA-Z])+\. {
58
+ gzip_static on;
59
+ expires max;
60
+ add_header Cache-Control public;
61
+ }
62
+
63
+ # Serve images outside the asset path
64
+ # Now this supposedly should work as it gets the filenames with querystrings that Rails provides.
65
+ # BUT there's a chance it could break the ajax calls.
66
+ location ~* \.(ico|css|gif|jpe?g|png)(\?[0-9]+)?$ {
67
+ expires max;
68
+ }
69
+
70
+ # Serve javascript outside the asset path
71
+ location ~ ^/javascripts/.*\.js(\?[0-9]+)?$ {
72
+ expires max;
73
+ }
74
+
75
+ # If the file exists as a static file serve it directly without
76
+ # running all the other rewrite tests on it
77
+ if (-f $request_filename) {
78
+ break;
79
+ }
80
+
81
+ # check for index.html for directory index
82
+ # if its there on the filesystem then rewite
83
+ # the url to add /index.html to the end of it
84
+ # and then break to send it to the next config rules.
85
+ if (-f $request_filename/index.html) {
86
+ rewrite (.*) $1/index.html break;
87
+ }
88
+
89
+ # this is the meat of the rails page caching config
90
+ # it adds .html to the end of the url and then checks
91
+ # the filesystem for that file. If it exists, then we
92
+ # rewite the url to have explicit .html on the end
93
+ # and then send it on its way to the next config rule.
94
+ # if there is no file on the fs then it sets all the
95
+ # necessary headers and proxies to our upstream mongrels
96
+ if (-f $request_filename.html) {
97
+ rewrite (.*) $1.html break;
98
+ }
99
+
100
+ if (!-f $request_filename) {
101
+ proxy_pass http://<%= upstream_name %>;
102
+ break;
103
+ }
104
+ }
105
+
106
+ # Rails error pages
107
+ error_page 500 502 503 504 /500.html;
108
+ location = /500.html {
109
+ root <%= c.fetch(:deploy_to) %>/current/public;
110
+ }
111
+ }
112
+ <% end %>
113
+
114
+ <% if c.fetch(:nginx_uses_ssl) %>
115
+ #
116
+ # HTTPs server configuration
117
+ #
118
+ upstream <%= upstream_name_ssl %> {
119
+ server unix:<%= File.join("#{c.fetch(:shared_path)}","sockets", "puma.sock") %> fail_timeout=0;
120
+ }
121
+
122
+ # This server is setup for ssl. Uncomment if
123
+ # you are using ssl as well as port 80.
124
+ server {
125
+ listen <%= c.fetch(:nginx_ssl_port) %>;
126
+ client_max_body_size 500M;
127
+ server_name <%= c.fetch(:server_names) %>;
128
+ ssl on;
129
+ ssl_certificate <%= c.fetch(:nginx_ssl_public_crt) %>;
130
+ ssl_certificate_key <%= c.fetch(:nginx_ssl_private_key) %>;
131
+ ssl_session_timeout 5m;
132
+ client_max_body_size <%= c.fetch(:nginx_ssl_client_max_body_size) %>;
133
+
134
+ root <%= c.fetch(:deploy_to) %>/current/public;
135
+ access_log <%= c.fetch(:nginx_log_path) %>/<%= Capistrano::BaseHelper.environment %>_ssl.access.log;
136
+ error_log <%= c.fetch(:nginx_log_path) %>/<%= Capistrano::BaseHelper.environment %>_ssl.error.log info;
137
+
138
+ # this rewrites all the requests to the maintenance.html
139
+ # page if it exists in the doc root. This is for capistrano's
140
+ # disable web task
141
+ if (-f $document_root/system/maintenance.html) {
142
+ rewrite ^(.*)$ /system/maintenance.html last;
143
+ break;
144
+ }
145
+
146
+ location / {
147
+ <% if c.fetch(:nginx_ssl_use_simple_auth) %>
148
+ auth_basic "<%= c.fetch(:nginx_simple_auth_message) %>";
149
+ auth_basic_user_file <%= c.fetch(:nginx_remote_htpasswd) %>;
150
+ <% end %>
151
+
152
+ # needed to forward user's IP address to rails
153
+ proxy_set_header X-Real-IP $remote_addr;
154
+
155
+ # needed for HTTPS
156
+ proxy_set_header X_FORWARDED_PROTO https;
157
+
158
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
159
+ proxy_set_header Host $http_host;
160
+ proxy_redirect off;
161
+ proxy_max_temp_file_size 0;
162
+
163
+ # if the request is for a static resource, nginx should serve it directly
164
+ # and add a far future expires header to it, making the browser
165
+ # cache the resource and navigate faster over the website.
166
+ location ~ ^/(assets)/.+-([0-9a-zA-Z])+\. {
167
+ gzip_static on;
168
+ expires max;
169
+ add_header Cache-Control public;
170
+ }
171
+
172
+ # Serve images outside the asset path
173
+ # Now this supposedly should work as it gets the filenames with querystrings that Rails provides.
174
+ # BUT there's a chance it could break the ajax calls.
175
+ location ~* \.(ico|css|gif|jpe?g|png)(\?[0-9]+)?$ {
176
+ expires max;
177
+ }
178
+
179
+ # Serve javascript outside the asset path
180
+ location ~ ^/javascripts/.*\.js(\?[0-9]+)?$ {
181
+ expires max;
182
+ }
183
+
184
+ # If the file exists as a static file serve it directly without
185
+ # running all the other rewite tests on it
186
+ if (-f $request_filename) {
187
+ break;
188
+ }
189
+
190
+ # check for index.html for directory index
191
+ # if its there on the filesystem then rewite
192
+ # the url to add /index.html to the end of it
193
+ # and then break to send it to the next config rules.
194
+ if (-f $request_filename/index.html) {
195
+ rewrite (.*) $1/index.html break;
196
+ }
197
+
198
+ # this is the meat of the rails page caching config
199
+ # it adds .html to the end of the url and then checks
200
+ # the filesystem for that file. If it exists, then we
201
+ # rewite the url to have explicit .html on the end
202
+ # and then send it on its way to the next config rule.
203
+ # if there is no file on the fs then it sets all the
204
+ # necessary headers and proxies to our upstream mongrels
205
+ if (-f $request_filename.html) {
206
+ rewrite (.*) $1.html break;
207
+ }
208
+
209
+ if (!-f $request_filename) {
210
+ proxy_pass http://<%= upstream_name_ssl %>;
211
+ break;
212
+ }
213
+ }
214
+
215
+ error_page 500 502 503 504 /500.html;
216
+ location = /500.html {
217
+ root <%= c.fetch(:deploy_to) %>/current/public;
218
+ }
219
+ }
220
+ <% end %>
@@ -0,0 +1,7 @@
1
+ # Capistrano deployed htpasswd file
2
+ # <% c = Capistrano::BaseHelper::get_capistrano_instance %>
3
+ #
4
+ # Remember NOT to share your deployment file in case you have sensitive passwords stored in it.
5
+ # You probably shouldn't use this in production in case your deploy.rb is visible on public sites.
6
+
7
+ <%= c.fetch(:nginx_simple_auth_user) %>:<%= c.fetch(:nginx_simple_auth_password).crypt(c.fetch(:nginx_simple_auth_salt)) %>:Autogenerated user from capistrano deployment
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano-pumaio
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
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: 2013-07-29 00:00:00.000000000 Z
12
+ date: 2013-07-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: capistrano
@@ -93,8 +93,11 @@ files:
93
93
  - lib/capistrano/puma.rb
94
94
  - lib/capistrano/puma/config.rb
95
95
  - lib/capistrano/puma/monit.rb
96
+ - lib/capistrano/puma/nginx.rb
96
97
  - lib/capistrano/puma/runit.rb
97
98
  - templates/monit/puma.conf.erb
99
+ - templates/nginx/application.conf.erb
100
+ - templates/nginx/htpasswd.erb
98
101
  - templates/runit/config.rb.erb
99
102
  - templates/runit/control-q.erb
100
103
  - templates/runit/finish.erb
@@ -115,7 +118,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
115
118
  version: '0'
116
119
  segments:
117
120
  - 0
118
- hash: 4539601094556942037
121
+ hash: -3189334886428706099
119
122
  required_rubygems_version: !ruby/object:Gem::Requirement
120
123
  none: false
121
124
  requirements: