capistrano-generals 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +16 -10
- data/lib/capistrano/dsl/nginx_paths.rb +32 -0
- data/lib/capistrano/dsl/sidekiq_paths.rb +26 -0
- data/lib/capistrano/dsl/unicorn_paths.rb +34 -0
- data/lib/capistrano/generals/helpers.rb +48 -0
- data/lib/capistrano/generals/version.rb +1 -1
- data/lib/capistrano/tasks/defaults.rake +50 -0
- data/lib/capistrano/tasks/deploy/symlink.rake +1 -1
- data/lib/capistrano/tasks/git.rake +4 -4
- data/lib/capistrano/tasks/nginx.rake +42 -6
- data/lib/capistrano/tasks/setup.rake +39 -39
- data/lib/capistrano/tasks/sidekiq.rake +31 -0
- data/lib/capistrano/tasks/unicorn.rake +48 -4
- data/lib/generators/capistrano/generals/nginx_generator.rb +17 -0
- data/lib/generators/capistrano/generals/templates/_head.erb +3 -0
- data/lib/generators/capistrano/generals/templates/nginx.conf.erb +111 -0
- data/lib/generators/capistrano/generals/templates/sidekiq_init.sh.erb +96 -0
- data/lib/generators/capistrano/generals/templates/unicorn.rb.erb +50 -0
- data/lib/generators/capistrano/generals/templates/unicorn_init.sh.erb +88 -0
- data/lib/generators/capistrano/generals/unicorn_generator.rb +18 -0
- metadata +13 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24b9088cc96674dce692f1d35bbe6c7e402ef8d7
|
4
|
+
data.tar.gz: e0c51c91fbaa60908ec4fa6f28acad18d7145f2f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 908f1e6c07c640d16f262a68bde17787d54a7d3a4fc428bc6df889e291ebd0223da58d634f5c7b08faf28785a47e8a48167b33bf7b036af7070697c96e011c8d
|
7
|
+
data.tar.gz: d9333ace8a8bec85752d387168a89a065caa5b7e71adb5f1161a9965e00052d59fcc26be10a47424d699f66b2db42788538f013020826e67d980a3d386b96bfe
|
data/README.md
CHANGED
@@ -32,15 +32,14 @@ In your `config/deploy.rb` you can add the taks by adding them to the deploy nam
|
|
32
32
|
namespace :deploy do
|
33
33
|
before :deploy, 'git:push'
|
34
34
|
before :deploy, 'deploy:symlink:upload_linked_files'
|
35
|
-
|
36
|
-
|
37
|
-
after :deploy, '
|
38
|
-
after :
|
39
|
-
after :
|
40
|
-
after :
|
41
|
-
after :
|
42
|
-
after :
|
43
|
-
after :rollback, 'sidekiq:restart'
|
35
|
+
before :deploy, 'setup'
|
36
|
+
|
37
|
+
# after :deploy, 'unicorn:restart'
|
38
|
+
# after :rollback, 'unicorn:restart'
|
39
|
+
# after :deploy, 'nginx:restart'
|
40
|
+
# after :rollback, 'nginx:restart'
|
41
|
+
# after :deploy, 'sidekiq:restart'
|
42
|
+
# after :rollback, 'sidekiq:restart'
|
44
43
|
end
|
45
44
|
```
|
46
45
|
|
@@ -71,13 +70,20 @@ example you want to upload `database.yml` to the `staging` environment,
|
|
71
70
|
the system first searches for `database.staging.yml` and if it cannot find that
|
72
71
|
it will fall back to the original.
|
73
72
|
|
73
|
+
### Setup
|
74
|
+
TODO: Create docs. It creates config files and startup scripts for nginx, unicorn and sidekiq.
|
75
|
+
|
74
76
|
### Restart
|
75
77
|
This will upgrade the unicorn workers and restart nginx.
|
76
78
|
|
77
79
|
## Contributing
|
78
80
|
|
79
|
-
1. Fork it ( https://github.com/
|
81
|
+
1. Fork it ( https://github.com/StefSchenkelaars/capistrano-generals/fork )
|
80
82
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
81
83
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
82
84
|
4. Push to the branch (`git push origin my-new-feature`)
|
83
85
|
5. Create a new Pull Request
|
86
|
+
|
87
|
+
|
88
|
+
## Disclaimer
|
89
|
+
With ideas from: https://github.com/capistrano-plugins/capistrano-unicorn-nginx
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Capistrano
|
2
|
+
module DSL
|
3
|
+
module NginxPaths
|
4
|
+
|
5
|
+
def nginx_initd_file
|
6
|
+
'/etc/init.d/nginx'
|
7
|
+
end
|
8
|
+
|
9
|
+
def nginx_sites_available_file
|
10
|
+
"#{fetch(:nginx_location)}/sites-available/#{fetch(:app_config_name)}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def nginx_sites_enabled_file
|
14
|
+
"#{fetch(:nginx_location)}/sites-enabled/#{fetch(:app_config_name)}"
|
15
|
+
end
|
16
|
+
|
17
|
+
# ssl related files
|
18
|
+
def nginx_ssl_cert_file
|
19
|
+
"/etc/ssl/certs/#{fetch(:nginx_ssl_cert)}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def nginx_ssl_cert_key_file
|
23
|
+
"/etc/ssl/private/#{fetch(:nginx_ssl_cert_key)}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def nginx_ssl_dhparam_file
|
27
|
+
"/etc/ssl/certs/#{fetch(:nginx_ssl_dhparam)}"
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Capistrano
|
2
|
+
module DSL
|
3
|
+
module SidekiqPaths
|
4
|
+
|
5
|
+
def sidekiq_service
|
6
|
+
"sidekiq_#{fetch(:app_config_name)}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def sidekiq_initd_file
|
10
|
+
"/etc/init.d/#{sidekiq_service}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def sidekiq_default_pid_file
|
14
|
+
shared_path.join('tmp/pids/sidekiq.pid')
|
15
|
+
end
|
16
|
+
|
17
|
+
def sidekiq_log_dir
|
18
|
+
shared_path.join('log')
|
19
|
+
end
|
20
|
+
|
21
|
+
def sidekiq_log_file
|
22
|
+
sidekiq_log_dir.join(fetch(:sidekiq_log))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Capistrano
|
2
|
+
module DSL
|
3
|
+
module UnicornPaths
|
4
|
+
|
5
|
+
def unicorn_service
|
6
|
+
"unicorn_#{fetch(:app_config_name)}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def unicorn_initd_file
|
10
|
+
"/etc/init.d/#{unicorn_service}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def unicorn_default_config_file
|
14
|
+
shared_path.join('config/unicorn.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
def unicorn_default_pid_file
|
18
|
+
shared_path.join('tmp/pids/unicorn.pid')
|
19
|
+
end
|
20
|
+
|
21
|
+
def unicorn_log_dir
|
22
|
+
shared_path.join('log')
|
23
|
+
end
|
24
|
+
|
25
|
+
def unicorn_log_file
|
26
|
+
unicorn_log_dir.join(fetch(:unicorn_log))
|
27
|
+
end
|
28
|
+
|
29
|
+
def unicorn_error_log_file
|
30
|
+
unicorn_log_dir.join(fetch(:unicorn_error_log))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,6 +1,15 @@
|
|
1
1
|
module Capistrano
|
2
2
|
module Generals
|
3
3
|
module Helpers
|
4
|
+
|
5
|
+
def bundle_unicorn(*args)
|
6
|
+
SSHKit::Command.new(:bundle, :exec, :unicorn, args).to_command
|
7
|
+
end
|
8
|
+
|
9
|
+
def bundle_sidekiq(*args)
|
10
|
+
SSHKit::Command.new(:bundle, :exec, :sidekiq, args).to_command
|
11
|
+
end
|
12
|
+
|
4
13
|
def red text
|
5
14
|
"\033[31m#{text}\033[0m"
|
6
15
|
end
|
@@ -41,6 +50,45 @@ module Capistrano
|
|
41
50
|
local_path = File.join(path, local_file)
|
42
51
|
end
|
43
52
|
|
53
|
+
def sudo_upload!(from, to)
|
54
|
+
filename = File.basename(to)
|
55
|
+
to_dir = File.dirname(to)
|
56
|
+
execute :mkdir, '-pv', to_dir
|
57
|
+
tmp_file = "#{fetch(:tmp_dir)}/#{filename}"
|
58
|
+
upload! from, tmp_file
|
59
|
+
sudo :mv, tmp_file, to_dir
|
60
|
+
end
|
61
|
+
|
62
|
+
# renders the ERB template specified by template_name to string. Use the locals variable to pass locals to the
|
63
|
+
# ERB template
|
64
|
+
def template_to_s(template_name, locals = {})
|
65
|
+
config_file = "#{fetch(:templates_path)}/#{template_name}.erb"
|
66
|
+
# if no customized file, proceed with default
|
67
|
+
unless File.exists?(config_file)
|
68
|
+
config_file = File.join(File.dirname(__FILE__), "../../generators/capistrano/generals/templates/#{template_name}.erb")
|
69
|
+
end
|
70
|
+
|
71
|
+
ERB.new(File.read(config_file)).result(ERBNamespace.new(locals).get_binding)
|
72
|
+
end
|
73
|
+
|
74
|
+
# renders the ERB template specified by template_name to a StringIO buffer
|
75
|
+
def template(template_name, locals = {})
|
76
|
+
StringIO.new(template_to_s(template_name, locals))
|
77
|
+
end
|
78
|
+
|
79
|
+
# Helper class to pass local variables to an ERB template
|
80
|
+
class ERBNamespace
|
81
|
+
def initialize(hash)
|
82
|
+
hash.each do |key, value|
|
83
|
+
singleton_class.send(:define_method, key) { value }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_binding
|
88
|
+
binding
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
44
92
|
end
|
45
93
|
end
|
46
94
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
namespace :load do
|
2
|
+
task :defaults do
|
3
|
+
# Application runner
|
4
|
+
set :use_puma, false
|
5
|
+
set :use_unicorn, false
|
6
|
+
set :use_sidekiq, false
|
7
|
+
|
8
|
+
# Application settings
|
9
|
+
set :app_config_name, -> { "#{fetch(:application)}_#{fetch(:stage)}" }
|
10
|
+
set :server_domain, -> { fetch(:server_domain) }
|
11
|
+
|
12
|
+
# General Nginx settings
|
13
|
+
set :nginx_location, '/etc/nginx'
|
14
|
+
set :nginx_redirect_www, true
|
15
|
+
set :nginx_fail_timeout, 0
|
16
|
+
|
17
|
+
# SSL Settings
|
18
|
+
set :nginx_use_ssl, false
|
19
|
+
set :nginx_ssl_stapling, true
|
20
|
+
set :nginx_ssl_ciphers, 'AES128+EECDH:AES128+EDH:!aNULL'
|
21
|
+
set :nginx_ssl_protocols, 'TLSv1 TLSv1.1 TLSv1.2'
|
22
|
+
set :nginx_ssl_session_cache, 'shared:SSL:10m'
|
23
|
+
set :nginx_ssl_cert, -> { "#{fetch(:server_domain)}.crt" }
|
24
|
+
set :nginx_ssl_cert_key, -> { "#{fetch(:server_domain)}.key" }
|
25
|
+
set :nginx_ssl_dhparam, 'dhparam.pem'
|
26
|
+
set :nginx_server_ciphers, false
|
27
|
+
set :nginx_server_ciphers_path, '/etc/ssl/certs/dhparam.pem'
|
28
|
+
|
29
|
+
# General Unicorn settings
|
30
|
+
set :unicorn_pid, -> { unicorn_default_pid_file } # shared_path/tmp/pids/unicorn.pid
|
31
|
+
set :unicorn_config, -> { unicorn_default_config_file } # shared_path/config/unicorn.rb
|
32
|
+
set :unicorn_workers, 2
|
33
|
+
set :unicorn_worker_timeout, 30
|
34
|
+
set :unicorn_log, 'unicorn.stdout.log'
|
35
|
+
set :unicorn_error_log, 'unicorn.stderr.log'
|
36
|
+
set :unicorn_user, -> { fetch(:deploy_user) }
|
37
|
+
set :unicorn_env, ''
|
38
|
+
set :unicorn_app_env, -> { fetch(:rails_env) || fetch(:rack_env) || fetch(:stage) }
|
39
|
+
|
40
|
+
# General Sidekiq settings
|
41
|
+
set :sidekiq_workers, 3
|
42
|
+
set :sidekiq_user, -> { fetch(:deploy_user) }
|
43
|
+
set :sidekiq_pid, -> { sidekiq_default_pid_file }
|
44
|
+
set :sidekiq_log, 'sidekiq.log'
|
45
|
+
|
46
|
+
# Capistrano settings
|
47
|
+
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids')
|
48
|
+
set :templates_path, 'config/deploy/templates'
|
49
|
+
end
|
50
|
+
end
|
@@ -6,7 +6,7 @@ namespace :deploy do
|
|
6
6
|
|
7
7
|
# Abort if no linked files found
|
8
8
|
if fetch(:linked_files).nil?
|
9
|
-
abort red
|
9
|
+
abort red 'No linked files specified. Remove the upload_linked_files task or add linked_files.'
|
10
10
|
end
|
11
11
|
|
12
12
|
# Loop through all linked files
|
@@ -6,12 +6,12 @@ namespace :git do
|
|
6
6
|
# Use 'cap git:push IGNORE_DEPLOY_RB=1' to ignore changes to this file (for testing)
|
7
7
|
run_locally do
|
8
8
|
status = %x(git status --porcelain).chomp
|
9
|
-
if status !=
|
9
|
+
if status != ''
|
10
10
|
if status !~ %r{^[M ][M ] config/deploy.rb$}
|
11
|
-
abort
|
12
|
-
elsif !ENV[
|
11
|
+
abort 'Local git repository has uncommitted changes'
|
12
|
+
elsif !ENV['IGNORE_DEPLOY_RB']
|
13
13
|
# This is used for testing changes to this script without committing them first
|
14
|
-
abort red
|
14
|
+
abort red 'Local git repository has uncommitted changes (set IGNORE_DEPLOY_RB=1 to ignore changes to deploy.rb)'
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -1,25 +1,61 @@
|
|
1
|
+
require 'capistrano/dsl/nginx_paths'
|
2
|
+
include Capistrano::DSL::NginxPaths
|
3
|
+
|
1
4
|
namespace :nginx do
|
2
5
|
|
6
|
+
desc 'Test capistrano config setup'
|
7
|
+
task :capistrano_config_test do
|
8
|
+
if (fetch(:use_puma) && fetch(:use_unicorn)) || (!fetch(:use_puma) && !fetch(:use_unicorn))
|
9
|
+
raise 'Use puma or unicorn'
|
10
|
+
end
|
11
|
+
raise 'Set server_domain variable to setup nginx' unless fetch(:server_domain)
|
12
|
+
end
|
13
|
+
|
14
|
+
desc 'Setup nginx configuration'
|
15
|
+
task :setup do
|
16
|
+
on roles :web do
|
17
|
+
sudo_upload! template('nginx.conf'), nginx_sites_available_file
|
18
|
+
sudo :ln, '-fs', nginx_sites_available_file, nginx_sites_enabled_file
|
19
|
+
end
|
20
|
+
end
|
21
|
+
before :setup, :capistrano_config_test
|
22
|
+
|
3
23
|
desc 'Start nginx'
|
4
24
|
task :start do
|
5
|
-
on roles
|
6
|
-
execute '
|
25
|
+
on roles :web do
|
26
|
+
execute nginx_initd_file, 'start'
|
7
27
|
end
|
8
28
|
end
|
9
29
|
|
10
30
|
desc 'Stop nginx'
|
11
31
|
task :stop do
|
12
|
-
on roles
|
13
|
-
execute '
|
32
|
+
on roles :web do
|
33
|
+
execute nginx_initd_file, 'stop'
|
14
34
|
sleep 3
|
15
35
|
end
|
16
36
|
end
|
17
37
|
|
18
38
|
desc 'Restart nginx'
|
19
39
|
task :restart do
|
20
|
-
on roles
|
21
|
-
|
40
|
+
on roles :web do
|
41
|
+
sudo nginx_initd_file, 'restart'
|
22
42
|
end
|
23
43
|
end
|
24
44
|
|
45
|
+
desc 'Reload nginx'
|
46
|
+
task :reload do
|
47
|
+
on roles :web do
|
48
|
+
sudo nginx_initd_file, 'reload'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
namespace :deploy do
|
55
|
+
after :publishing, 'nginx:reload'
|
56
|
+
end
|
57
|
+
|
58
|
+
desc 'Server setup tasks'
|
59
|
+
task :setup do
|
60
|
+
invoke 'nginx:setup'
|
25
61
|
end
|
@@ -1,41 +1,41 @@
|
|
1
1
|
namespace :setup do
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
2
|
+
#
|
3
|
+
# namespace :symlink do
|
4
|
+
#
|
5
|
+
# desc 'Symlink config file for nginx'
|
6
|
+
# task :nginx do
|
7
|
+
# on roles :app do
|
8
|
+
# # Find stage specific config file
|
9
|
+
# file_name = File.join current_path, 'config/nginx.conf'
|
10
|
+
# file_name = get_config_file(file_name, fetch(:stage).to_s)
|
11
|
+
# execute "ln -nfs #{file_name} /etc/nginx/sites-enabled/#{fetch(:application)}_#{fetch(:stage)}"
|
12
|
+
# end
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# desc 'Symlink config file for unicorn'
|
16
|
+
# task :unicorn do
|
17
|
+
# on roles :app do
|
18
|
+
# # Find stage specific config file
|
19
|
+
# file_name = File.join current_path, 'config/unicorn_init.sh'
|
20
|
+
# file_name = get_config_file(file_name, fetch(:stage).to_s)
|
21
|
+
# execute "ln -nfs #{file_name} /etc/init.d/unicorn_#{fetch(:application)}_#{fetch(:stage)}"
|
22
|
+
# # Start unicorn at startup
|
23
|
+
# execute "sudo update-rc.d unicorn_#{fetch(:application)}_#{fetch(:stage)} defaults"
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# desc 'Symlink config file for sidekiq'
|
28
|
+
# task :sidekiq do
|
29
|
+
# on roles :app do
|
30
|
+
# # Find stage specific config file
|
31
|
+
# file_name = File.join current_path, 'config/sidekiq_init.sh'
|
32
|
+
# file_name = get_config_file(file_name, fetch(:stage).to_s)
|
33
|
+
# execute "ln -nfs #{file_name} /etc/init.d/sidekiq_#{fetch(:application)}_#{fetch(:stage)}"
|
34
|
+
# # Start unicorn at startup
|
35
|
+
# execute "sudo update-rc.d sidekiq_#{fetch(:application)}_#{fetch(:stage)} defaults"
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# end
|
40
|
+
#
|
41
41
|
end
|
@@ -1,5 +1,23 @@
|
|
1
|
+
require 'capistrano/dsl/sidekiq_paths'
|
2
|
+
include Capistrano::DSL::SidekiqPaths
|
3
|
+
|
1
4
|
namespace :sidekiq do
|
2
5
|
|
6
|
+
desc 'Test capistrano config setup'
|
7
|
+
task :capistrano_config_test do
|
8
|
+
raise 'Sidekiq is not on, use_sidekiq is false' unless fetch(:use_sidekiq)
|
9
|
+
end
|
10
|
+
|
11
|
+
desc 'Setup Sidekiq initializer'
|
12
|
+
task :setup_initializer do
|
13
|
+
on roles :app do
|
14
|
+
sudo_upload! template('sidekiq_init.sh'), sidekiq_initd_file
|
15
|
+
execute :chmod, '+x', sidekiq_initd_file
|
16
|
+
sudo 'update-rc.d', '-f', unicorn_service, 'defaults'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
before :setup_initializer, :capistrano_config_test
|
20
|
+
|
3
21
|
desc 'Start sidekiq'
|
4
22
|
task :start do
|
5
23
|
on roles(:app) do
|
@@ -22,3 +40,16 @@ namespace :sidekiq do
|
|
22
40
|
end
|
23
41
|
|
24
42
|
end
|
43
|
+
|
44
|
+
namespace :deploy do
|
45
|
+
if fetch(:use_sidekiq)
|
46
|
+
after :publishing, 'sidekiq:restart'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
desc 'Server setup tasks'
|
51
|
+
task :setup do
|
52
|
+
if fetch(:use_sidekiq)
|
53
|
+
invoke 'unicorn:setup_initializer'
|
54
|
+
end
|
55
|
+
end
|
@@ -1,16 +1,46 @@
|
|
1
|
+
require 'capistrano/dsl/unicorn_paths'
|
2
|
+
include Capistrano::DSL::UnicornPaths
|
3
|
+
|
1
4
|
namespace :unicorn do
|
2
5
|
|
6
|
+
desc 'Test capistrano config setup'
|
7
|
+
task :capistrano_config_test do
|
8
|
+
raise 'Use unicorn is not set as the application runner' unless fetch(:use_unicorn)
|
9
|
+
raise 'Puma is also set as application runner' if fetch(:use_puma)
|
10
|
+
raise 'Set the unicorn_user, which is default the deploy_user' unless fetch(:unicorn_user)
|
11
|
+
raise 'Set server_domain variable to setup nginx' unless fetch(:server_domain)
|
12
|
+
end
|
13
|
+
|
14
|
+
desc 'Setup Unicorn initializer'
|
15
|
+
task :setup_initializer do
|
16
|
+
on roles :app do
|
17
|
+
sudo_upload! template('unicorn_init.sh'), unicorn_initd_file
|
18
|
+
execute :chmod, '+x', unicorn_initd_file
|
19
|
+
sudo 'update-rc.d', '-f', unicorn_service, 'defaults'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
before :setup_initializer, :capistrano_config_test
|
23
|
+
|
24
|
+
desc 'Setup unicorn app configuration'
|
25
|
+
task :setup_app_config do
|
26
|
+
on roles :app do
|
27
|
+
execute :mkdir, '-pv', File.dirname(fetch(:unicorn_config).to_s)
|
28
|
+
upload! template('unicorn.rb'), fetch(:unicorn_config).to_s
|
29
|
+
end
|
30
|
+
end
|
31
|
+
before :setup_app_config, :capistrano_config_test
|
32
|
+
|
3
33
|
desc 'Start unicorn'
|
4
34
|
task :start do
|
5
|
-
on roles
|
6
|
-
|
35
|
+
on roles :app do
|
36
|
+
sudo unicorn_initd_file, 'start'
|
7
37
|
end
|
8
38
|
end
|
9
39
|
|
10
40
|
desc 'Stop unicorn'
|
11
41
|
task :stop do
|
12
|
-
on roles
|
13
|
-
execute
|
42
|
+
on roles :app do
|
43
|
+
execute unicorn_initd_file, 'stop'
|
14
44
|
sleep 3
|
15
45
|
end
|
16
46
|
end
|
@@ -22,3 +52,17 @@ namespace :unicorn do
|
|
22
52
|
end
|
23
53
|
|
24
54
|
end
|
55
|
+
|
56
|
+
namespace :deploy do
|
57
|
+
if fetch(:use_unicorn)
|
58
|
+
after :publishing, 'unicorn:restart'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
desc 'Server setup tasks'
|
63
|
+
task :setup do
|
64
|
+
if fetch(:use_unicorn)
|
65
|
+
invoke 'unicorn:setup_app_config'
|
66
|
+
invoke 'unicorn:setup_initializer'
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Capistrano
|
2
|
+
module Generals
|
3
|
+
module Generators
|
4
|
+
class NginxGenerator < Rails::Generators::Base
|
5
|
+
desc 'Create local nginx configuration file 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
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
<%= template_to_s('_head').to_s %>
|
2
|
+
# Upstreams
|
3
|
+
##############################
|
4
|
+
<% if fetch(:use_unicorn) %>
|
5
|
+
upstream unicorn_<%= fetch(:app_config_name) %> {
|
6
|
+
server unix:/tmp/unicorn.<%= fetch(:app_config_name) %>.sock fail_timeout=<%= fetch(:nginx_fail_timeout) %>;
|
7
|
+
}
|
8
|
+
<% end %>
|
9
|
+
<% if fetch(:use_puma) %>
|
10
|
+
upstream puma_<%= fetch(:app_config_name) %> {
|
11
|
+
server unix:/tmp/puma.<%= fetch(:app_config_name) %>.sock fail_timeout=<%= fetch(:nginx_fail_timeout) %>;
|
12
|
+
}
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
# Redirects
|
16
|
+
##############################
|
17
|
+
<% if fetch(:nginx_redirect_www) %>
|
18
|
+
server {
|
19
|
+
listen 80;
|
20
|
+
server_name www.<%= fetch(:server_domain) %>;
|
21
|
+
return 301 https://<%= fetch(:server_domain) %>$request_uri;
|
22
|
+
}
|
23
|
+
<% end %>
|
24
|
+
<% if fetch(:nginx_use_ssl) %>
|
25
|
+
server {
|
26
|
+
listen 80;
|
27
|
+
server_name <%= fetch(:server_domain) %>;
|
28
|
+
rewrite ^(.*) https://$host$1 permanent;
|
29
|
+
}
|
30
|
+
<% end %>
|
31
|
+
|
32
|
+
# Server
|
33
|
+
##############################
|
34
|
+
server {
|
35
|
+
server_name <%= fetch(:server_domain) %>;
|
36
|
+
root <%= current_path %>/public;
|
37
|
+
|
38
|
+
client_max_body_size 4G;
|
39
|
+
keepalive_timeout 10;
|
40
|
+
|
41
|
+
error_page 500 502 504 /500.html;
|
42
|
+
|
43
|
+
# SSL Settings
|
44
|
+
<% if fetch(:nginx_use_ssl) %>
|
45
|
+
listen 443 ssl;
|
46
|
+
ssl_certificate <%= nginx_ssl_cert_file %>;
|
47
|
+
ssl_certificate_key <%= nginx_ssl_cert_key_file %>;
|
48
|
+
|
49
|
+
ssl_ciphers <%= fetch(:nginx_ssl_ciphers) %>;
|
50
|
+
ssl_protocols <%= fetch(:nginx_ssl_protocols) %>;
|
51
|
+
ssl_session_cache <%= fetch(:nginx_ssl_session_cache) %>;
|
52
|
+
|
53
|
+
<% if fetch(:nginx_ssl_stapling) %>
|
54
|
+
ssl_stapling on;
|
55
|
+
ssl_stapling_verify on;
|
56
|
+
resolver 8.8.4.4 8.8.8.8 valid=300s;
|
57
|
+
resolver_timeout 10s;
|
58
|
+
<% end %>
|
59
|
+
|
60
|
+
<% if fetch(:nginx_server_ciphers) %>
|
61
|
+
ssl_prefer_server_ciphers on;
|
62
|
+
ssl_dhparam <%= nginx_ssl_dhparam_file %>;
|
63
|
+
<% end %>
|
64
|
+
|
65
|
+
<% else %>
|
66
|
+
listen 80;
|
67
|
+
<% end %>
|
68
|
+
|
69
|
+
<% # FILE HANDLING %>
|
70
|
+
<% if fetch(:use_unicorn) %>
|
71
|
+
try_files $uri/index.html $uri @unicorn_<%= fetch(:app_config_name) %>;
|
72
|
+
|
73
|
+
location @unicorn_<%= fetch(:app_config_name) %> {
|
74
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
75
|
+
proxy_set_header Host $http_host;
|
76
|
+
proxy_redirect off;
|
77
|
+
<% if fetch(:nginx_use_ssl) %>
|
78
|
+
proxy_set_header X-Forwarded-Proto https;
|
79
|
+
<% end %>
|
80
|
+
proxy_pass http://unicorn_<%= fetch(:app_config_name) %>;
|
81
|
+
}
|
82
|
+
<% end %>
|
83
|
+
|
84
|
+
<% if fetch(:use_puma) %>
|
85
|
+
try_files $uri/index.html $uri @puma_<%= fetch(:app_config_name) %>;
|
86
|
+
|
87
|
+
location @unicorn_<%= fetch(:app_config_name) %> {
|
88
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
89
|
+
proxy_set_header Host $http_host;
|
90
|
+
proxy_redirect off;
|
91
|
+
<% if fetch(:nginx_use_ssl) %>
|
92
|
+
proxy_set_header X-Forwarded-Proto https;
|
93
|
+
<% end %>
|
94
|
+
proxy_pass http://puma_<%= fetch(:app_config_name) %>;
|
95
|
+
}
|
96
|
+
<% end %>
|
97
|
+
|
98
|
+
location ~* ^/assets/ {
|
99
|
+
# Per RFC2616 - 1 year maximum expiry
|
100
|
+
expires 1y;
|
101
|
+
add_header Cache-Control public;
|
102
|
+
|
103
|
+
# Some browsers still send conditional-GET requests if there's a
|
104
|
+
# Last-Modified header or an ETag header even if they haven't
|
105
|
+
# reached the expiry date sent in the Expires header.
|
106
|
+
add_header Last-Modified "";
|
107
|
+
add_header ETag "";
|
108
|
+
break;
|
109
|
+
}
|
110
|
+
|
111
|
+
}
|
@@ -0,0 +1,96 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
<%= template_to_s('_head').to_s %>
|
3
|
+
### BEGIN INIT INFO
|
4
|
+
# Provides: sidekiq
|
5
|
+
# Required-Start: $remote_fs $syslog
|
6
|
+
# Required-Stop: $remote_fs $syslog
|
7
|
+
# Default-Start: 2 3 4 5
|
8
|
+
# Default-Stop: 0 1 6
|
9
|
+
# Short-Description: Manage sidekiq workers
|
10
|
+
# Description: tarts and Stops Sidekiq message processor for Stratus application.
|
11
|
+
### END INIT INFO
|
12
|
+
|
13
|
+
# User-specified exit parameters used in this script:
|
14
|
+
#
|
15
|
+
# Exit Code 5 - Incorrect User ID
|
16
|
+
# Exit Code 6 - Directory not found
|
17
|
+
|
18
|
+
# User variables
|
19
|
+
AS_USER=<%= fetch(:sidekiq_user) %>
|
20
|
+
APP_DIR=<%= current_path %>
|
21
|
+
|
22
|
+
# System variables
|
23
|
+
LOG_FILE=<%= sidekiq_log_file %>
|
24
|
+
START_CMD="<%= bundle_sidekiq('-P', fetch(:sidekiq_pid), '-c', fetch(:sidekiq_workers)) %>"
|
25
|
+
CMD="cd ${APP_DIR}; ${START_CMD} >> ${LOG_FILE} 2>&1 &"
|
26
|
+
RETVAL=0
|
27
|
+
|
28
|
+
start() {
|
29
|
+
status
|
30
|
+
if [ $? -eq 1 ]; then
|
31
|
+
echo "Starting sidekiq message processor .. "
|
32
|
+
[ `id -u` == '0' ] || (echo "sidekiq runs as root only .."; exit 5)
|
33
|
+
[ -d $APP_DIR ] || (echo "$APP_DIR not found!.. Exiting"; exit 6)
|
34
|
+
cd $APP_DIR
|
35
|
+
su -c "$CMD" - $AS_USER
|
36
|
+
RETVAL=$?
|
37
|
+
#Sleeping for 8 seconds for process to be precisely visible in process table - See status ()
|
38
|
+
sleep 8
|
39
|
+
return $RETVAL
|
40
|
+
else
|
41
|
+
echo "Sidekiq message processor is already running .. "
|
42
|
+
fi
|
43
|
+
}
|
44
|
+
|
45
|
+
stop() {
|
46
|
+
status
|
47
|
+
if [ $? -eq 0 ]; then
|
48
|
+
echo "Stopping sidekiq message processor .."
|
49
|
+
SIG="INT"
|
50
|
+
pid
|
51
|
+
kill -$SIG $PID
|
52
|
+
RETVAL=$?
|
53
|
+
return $RETVAL
|
54
|
+
else
|
55
|
+
echo "Sidekiq message processor is stopped already .."
|
56
|
+
fi
|
57
|
+
}
|
58
|
+
|
59
|
+
status() {
|
60
|
+
STATUS=$(ps -ef | grep "sidekiq [0-9]*.[0-9]*.[0-9]* ${APP}" | grep -v grep)
|
61
|
+
return $?
|
62
|
+
}
|
63
|
+
|
64
|
+
pid() {
|
65
|
+
status
|
66
|
+
PID=$(echo "$STATUS" | awk '{print $2}')
|
67
|
+
return $PID
|
68
|
+
}
|
69
|
+
|
70
|
+
case "$1" in
|
71
|
+
start)
|
72
|
+
start
|
73
|
+
;;
|
74
|
+
stop)
|
75
|
+
stop
|
76
|
+
;;
|
77
|
+
status)
|
78
|
+
status
|
79
|
+
if [ $? -eq 0 ]; then
|
80
|
+
echo "Sidekiq message processor is running .."
|
81
|
+
RETVAL=0
|
82
|
+
else
|
83
|
+
echo "Sidekiq message processor is stopped .."
|
84
|
+
RETVAL=1
|
85
|
+
fi
|
86
|
+
;;
|
87
|
+
pid)
|
88
|
+
pid
|
89
|
+
echo "$PID"
|
90
|
+
;;
|
91
|
+
*)
|
92
|
+
echo "Usage: $0 {start|stop|status|pid}"
|
93
|
+
exit 0
|
94
|
+
;;
|
95
|
+
esac
|
96
|
+
exit $RETVAL
|
@@ -0,0 +1,50 @@
|
|
1
|
+
<%= template_to_s('_head').to_s %>
|
2
|
+
working_directory "<%= current_path %>"
|
3
|
+
pid "<%= fetch(:unicorn_pid) %>"
|
4
|
+
stdout_path "<%= unicorn_log_file %>"
|
5
|
+
stderr_path "<%= unicorn_error_log_file %>"
|
6
|
+
|
7
|
+
listen "/tmp/unicorn.<%= fetch(:app_config_name) %>.sock"
|
8
|
+
|
9
|
+
worker_processes <%= fetch(:unicorn_workers) %>
|
10
|
+
timeout <%= fetch(:unicorn_worker_timeout) %>
|
11
|
+
|
12
|
+
preload_app true
|
13
|
+
|
14
|
+
before_exec do |server|
|
15
|
+
ENV["BUNDLE_GEMFILE"] = "<%= current_path %>/Gemfile"
|
16
|
+
end
|
17
|
+
|
18
|
+
before_fork do |server, worker|
|
19
|
+
# Disconnect since the database connection will not carry over
|
20
|
+
if defined? ActiveRecord::Base
|
21
|
+
ActiveRecord::Base.connection.disconnect!
|
22
|
+
end
|
23
|
+
|
24
|
+
# Quit the old unicorn process
|
25
|
+
old_pid = "#{server.config[:pid]}.oldbin"
|
26
|
+
if File.exists?(old_pid) && server.pid != old_pid
|
27
|
+
begin
|
28
|
+
Process.kill("QUIT", File.read(old_pid).to_i)
|
29
|
+
rescue Errno::ENOENT, Errno::ESRCH
|
30
|
+
# someone else did our job for us
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
if defined?(Resque)
|
35
|
+
Resque.redis.quit
|
36
|
+
end
|
37
|
+
|
38
|
+
sleep 1
|
39
|
+
end
|
40
|
+
|
41
|
+
after_fork do |server, worker|
|
42
|
+
# Start up the database connection again in the worker
|
43
|
+
if defined?(ActiveRecord::Base)
|
44
|
+
ActiveRecord::Base.establish_connection
|
45
|
+
end
|
46
|
+
|
47
|
+
if defined?(Resque)
|
48
|
+
Resque.redis = 'localhost:6379'
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
<%= template_to_s('_head').to_s %>
|
3
|
+
### BEGIN INIT INFO
|
4
|
+
# Provides: unicorn
|
5
|
+
# Required-Start: $remote_fs $syslog
|
6
|
+
# Required-Stop: $remote_fs $syslog
|
7
|
+
# Default-Start: 2 3 4 5
|
8
|
+
# Default-Stop: 0 1 6
|
9
|
+
# Short-Description: Manage unicorn server
|
10
|
+
# Description: Start, stop, restart unicorn server for a specific application.
|
11
|
+
### END INIT INFO
|
12
|
+
set -e
|
13
|
+
|
14
|
+
# Feel free to change any of the following variables for your app:
|
15
|
+
TIMEOUT=${TIMEOUT-60}
|
16
|
+
APP_ROOT=<%= current_path %>
|
17
|
+
PID=<%= fetch(:unicorn_pid) %>
|
18
|
+
AS_USER=<%= fetch(:unicorn_user) %>
|
19
|
+
UNICORN_ENV="<%= fetch(:unicorn_env) %>"
|
20
|
+
CMD="export HOME; true "${HOME:=$(getent passwd "$AS_USER" | cut -d: -f6;)}"; cd $APP_ROOT && $UNICORN_ENV <%= bundle_unicorn('-D -c', fetch(:unicorn_config), '-E', fetch(:unicorn_app_env)) %>"
|
21
|
+
|
22
|
+
set -u
|
23
|
+
|
24
|
+
|
25
|
+
OLD_PIN="$PID.oldbin"
|
26
|
+
|
27
|
+
sig () {
|
28
|
+
test -s "$PID" && kill -$1 `cat $PID`
|
29
|
+
}
|
30
|
+
|
31
|
+
oldsig () {
|
32
|
+
test -s $OLD_PIN && kill -$1 `cat $OLD_PIN`
|
33
|
+
}
|
34
|
+
|
35
|
+
run () {
|
36
|
+
if [ "$(id -un)" = "$AS_USER" ]; then
|
37
|
+
eval $1
|
38
|
+
else
|
39
|
+
su -c "$1" - $AS_USER
|
40
|
+
fi
|
41
|
+
}
|
42
|
+
|
43
|
+
case "$1" in
|
44
|
+
start)
|
45
|
+
sig 0 && echo >&2 "Already running" && exit 0
|
46
|
+
run "$CMD"
|
47
|
+
;;
|
48
|
+
stop)
|
49
|
+
sig QUIT && exit 0
|
50
|
+
echo >&2 "Not running"
|
51
|
+
;;
|
52
|
+
force-stop)
|
53
|
+
sig TERM && exit 0
|
54
|
+
echo >&2 "Not running"
|
55
|
+
;;
|
56
|
+
restart|reload)
|
57
|
+
sig HUP && echo reloaded OK && exit 0
|
58
|
+
echo >&2 "Couldn't reload, starting '$CMD' instead"
|
59
|
+
run "$CMD"
|
60
|
+
;;
|
61
|
+
upgrade)
|
62
|
+
if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
|
63
|
+
then
|
64
|
+
n=$TIMEOUT
|
65
|
+
while test -s $OLD_PIN && test $n -ge 0
|
66
|
+
do
|
67
|
+
printf '.' && sleep 1 && n=$(( $n - 1 ))
|
68
|
+
done
|
69
|
+
echo
|
70
|
+
|
71
|
+
if test $n -lt 0 && test -s $OLD_PIN
|
72
|
+
then
|
73
|
+
echo >&2 "$OLD_PIN still exists after $TIMEOUT seconds"
|
74
|
+
exit 1
|
75
|
+
fi
|
76
|
+
exit 0
|
77
|
+
fi
|
78
|
+
echo >&2 "Couldn't upgrade, starting '$CMD' instead"
|
79
|
+
run "$CMD"
|
80
|
+
;;
|
81
|
+
reopen-logs)
|
82
|
+
sig USR1
|
83
|
+
;;
|
84
|
+
*)
|
85
|
+
echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
|
86
|
+
exit 1
|
87
|
+
;;
|
88
|
+
esac
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Capistrano
|
2
|
+
module Generals
|
3
|
+
module Generators
|
4
|
+
class UnicornGenerator < Rails::Generators::Base
|
5
|
+
desc 'Create local unicorn configuration file 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 'unicorn.rb.erb', "#{templates_path}/unicorn.rb.erb"
|
13
|
+
copy_file 'unicorn_init.sh.erb', "#{templates_path}/unicorn_init.sh.erb"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano-generals
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stef Schenkelaars
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-06-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: capistrano
|
@@ -66,15 +66,26 @@ files:
|
|
66
66
|
- Rakefile
|
67
67
|
- capistrano-generals.gemspec
|
68
68
|
- lib/capistrano-generals.rb
|
69
|
+
- lib/capistrano/dsl/nginx_paths.rb
|
70
|
+
- lib/capistrano/dsl/sidekiq_paths.rb
|
71
|
+
- lib/capistrano/dsl/unicorn_paths.rb
|
69
72
|
- lib/capistrano/generals.rb
|
70
73
|
- lib/capistrano/generals/helpers.rb
|
71
74
|
- lib/capistrano/generals/version.rb
|
75
|
+
- lib/capistrano/tasks/defaults.rake
|
72
76
|
- lib/capistrano/tasks/deploy/symlink.rake
|
73
77
|
- lib/capistrano/tasks/git.rake
|
74
78
|
- lib/capistrano/tasks/nginx.rake
|
75
79
|
- lib/capistrano/tasks/setup.rake
|
76
80
|
- lib/capistrano/tasks/sidekiq.rake
|
77
81
|
- lib/capistrano/tasks/unicorn.rake
|
82
|
+
- lib/generators/capistrano/generals/nginx_generator.rb
|
83
|
+
- lib/generators/capistrano/generals/templates/_head.erb
|
84
|
+
- lib/generators/capistrano/generals/templates/nginx.conf.erb
|
85
|
+
- lib/generators/capistrano/generals/templates/sidekiq_init.sh.erb
|
86
|
+
- lib/generators/capistrano/generals/templates/unicorn.rb.erb
|
87
|
+
- lib/generators/capistrano/generals/templates/unicorn_init.sh.erb
|
88
|
+
- lib/generators/capistrano/generals/unicorn_generator.rb
|
78
89
|
homepage: ''
|
79
90
|
licenses:
|
80
91
|
- MIT
|