capistrano-generals 0.0.4 → 0.1.0
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 +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
|