simple-capistrano-unicorn 0.0.3
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.
- data/.gitignore +6 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +4 -0
- data/README.md +64 -0
- data/Rakefile +2 -0
- data/lib/simple-capistrano-unicorn/namespace.rb +137 -0
- data/lib/simple-capistrano-unicorn/version.rb +7 -0
- data/lib/simple-capistrano-unicorn.rb +2 -0
- data/simple-capistrano-unicorn.gemspec +25 -0
- metadata +115 -0
data/.gitignore
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# Simple Capistrano Unicorn
|
2
|
+
|
3
|
+
Contains a namespace with methods for administrating the unicorn server through capistrano recipes.
|
4
|
+
|
5
|
+
## Setup
|
6
|
+
|
7
|
+
### 1. Require this gem in deploy.rb
|
8
|
+
|
9
|
+
You should add this line in the bottom of `RAILS_ROOT/config/deploy.rb`:
|
10
|
+
|
11
|
+
```
|
12
|
+
require 'simple-capistrano-unicorn'
|
13
|
+
```
|
14
|
+
|
15
|
+
### 2. Restart Unicorn on deploy
|
16
|
+
|
17
|
+
You should place this line in `RAILS_ROOT/config/deploy.rb`:
|
18
|
+
|
19
|
+
```
|
20
|
+
after :deploy, "unicorn:restart"
|
21
|
+
```
|
22
|
+
|
23
|
+
### 3. Extra step only for multi-stage setup
|
24
|
+
|
25
|
+
Make sure that you are using the multi-stage extension for Capistrano ( https://github.com/capistrano/capistrano/wiki/2.x-Multistage-Extension )
|
26
|
+
|
27
|
+
You should create different Unicorn files to use for each of your environments. The most common setup is to place the Unicorn files in `RAILS_ROOT/config/unicorn/{staging|beta|production}.rb`.
|
28
|
+
|
29
|
+
You can then override the `unicorn_config`-variable that this gem is listening for, by placing this in `RAILS_ROOT/config/deploy.rb`:
|
30
|
+
|
31
|
+
```
|
32
|
+
set(:unicorn_config) { "#{fetch(:current_path)}/config/unicorn/#{fetch(:stage)}.rb" }
|
33
|
+
```
|
34
|
+
|
35
|
+
## Usage
|
36
|
+
|
37
|
+
Go through the setup and run: `cap deploy` or `cap production deploy` (for multistage)
|
38
|
+
|
39
|
+
The gem gives you access to the following methods within the `unicorn.<method>` namespace.
|
40
|
+
|
41
|
+
* `unicorn.start` starts the Unicorn processes
|
42
|
+
* `unicorn.stop` stops the Unicorn processes
|
43
|
+
* `unicorn.restart` makes a seamless zero-downtime restart
|
44
|
+
* `unicorn.hard_restart` basically runs `unicorn.stop` followed with a `unicorn.start`
|
45
|
+
* `unicorn.log` prints out from the Unicorn log in `tail -f`-like fashion
|
46
|
+
* `unicorn.cleanup` removes the old running Unicorn master
|
47
|
+
|
48
|
+
## Requirements
|
49
|
+
|
50
|
+
* `unicorn`
|
51
|
+
* `capistrano`
|
52
|
+
|
53
|
+
## Customization
|
54
|
+
|
55
|
+
You can customize the gems behavior by setting any (or all) of the following options within capistrano's configuration:
|
56
|
+
|
57
|
+
* `unicorn_pid` indicates the path for the pid file. Defaults to `"#{shared_path}/pids/unicorn.pid"`.
|
58
|
+
* `unicorn_old_pid` indicates the path for the old pid file, which Unicorn creates when forking a new master. Defaults to `#{shared_path}/pids/unicorn.pid.oldbin`.
|
59
|
+
* `unicorn_config` the path to the unicorn config file. Defaults to `"#{current_path}/config/unicorn.rb"`.
|
60
|
+
* `unicorn_socket` indicates the place that Unicorn should place its socket file. Defaults to `"#{shared_path}/system/unicorn.sock"`.
|
61
|
+
* `unicorn_log` the path where unicorn places its STDERR-log. Defaults to `"#{shared_path}/log/unicorn.stderr.log"`.
|
62
|
+
* `unicorn_port` defines the port that unicorn should listen on. Defaults to `"3000"`.
|
63
|
+
* `use_bundler` defines whether Unicorn should start with `bundle exec` or not. Default to `true`.
|
64
|
+
* `rails_env` sets the environment that the server will run in. Defaults to `"production"`.
|
data/Rakefile
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'capistrano'
|
2
|
+
require 'capistrano/version'
|
3
|
+
|
4
|
+
module SimpleCapistranoUnicorn
|
5
|
+
class CapistranoIntegration
|
6
|
+
def self.load_into(capistrano_config)
|
7
|
+
capistrano_config.load do
|
8
|
+
# Defaulting these variables, because they could end up not being defined in deploy.rb.
|
9
|
+
_cset(:unicorn_pid) { "#{shared_path}/pids/unicorn.pid" }
|
10
|
+
_cset(:unicorn_old_pid) { "#{shared_path}/pids/unicorn.pid.oldbin" }
|
11
|
+
_cset(:unicorn_config) { "#{current_path}/config/unicorn.rb" }
|
12
|
+
_cset(:unicorn_socket) { "#{shared_path}/system/unicorn.sock" }
|
13
|
+
_cset(:unicorn_log) { "#{shared_path}/log/unicorn.stderr.log" }
|
14
|
+
_cset(:unicorn_port) { '3000' }
|
15
|
+
_cset(:use_bundler) { true }
|
16
|
+
_cset(:rails_env) { "production" }
|
17
|
+
|
18
|
+
def process_running?(server, pidfile)
|
19
|
+
cmd = "if [ -e #{unicorn_pid} ]; then ps cax | grep `cat #{pidfile}` > /dev/null; if [ $? -eq 0 ]; then echo -n running; fi; fi"
|
20
|
+
'running' == capture(cmd, :hosts => [server])
|
21
|
+
end
|
22
|
+
|
23
|
+
# Command to check if Unicorn is running.
|
24
|
+
#
|
25
|
+
def unicorn_is_running?(server)
|
26
|
+
process_running?(server, unicorn_pid)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Command to check if old Unicorn is running.
|
30
|
+
#
|
31
|
+
def old_unicorn_is_running?(server)
|
32
|
+
process_running?(server, unicorn_old_pid)
|
33
|
+
end
|
34
|
+
|
35
|
+
def nice_output(output, server = nil)
|
36
|
+
"#{server.to_s.ljust(20) if server} #{output}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def start_unicorn(server)
|
40
|
+
run "cd #{current_path}; #{'bundle exec' if use_bundler} unicorn -c #{unicorn_config} -E #{rails_env}#{" -p #{unicorn_port}" if unicorn_port} -D", :hosts => [server]
|
41
|
+
end
|
42
|
+
|
43
|
+
def clean_old_unicorn(server)
|
44
|
+
if old_unicorn_is_running?(server)
|
45
|
+
run "kill -s QUIT `cat #{unicorn_old_pid}`", :hosts => [server]
|
46
|
+
run "if [ -e #{unicorn_pid} ]; then rm #{unicorn_old_pid}; fi", :hosts => [server]
|
47
|
+
logger.info nice_output("Cleaned up old Unicorn", server)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
namespace :unicorn do
|
52
|
+
# Starts the unicorn process(es)
|
53
|
+
#
|
54
|
+
desc "Starts unicorn"
|
55
|
+
task :start, :roles => :app do
|
56
|
+
find_servers(:roles => :app).each do |server|
|
57
|
+
clean_old_unicorn(server)
|
58
|
+
|
59
|
+
if unicorn_is_running?(server)
|
60
|
+
logger.info("Unicorn already running on #{server}")
|
61
|
+
else
|
62
|
+
# Unicorn is not running, remove the pid-file if it exists
|
63
|
+
run "if [ -e #{unicorn_pid} ]; then rm #{unicorn_pid}; fi", :hosts => [server]
|
64
|
+
start_unicorn(server)
|
65
|
+
logger.info nice_output("Started Unicorn!", server)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# This will quit the unicorn process(es).
|
71
|
+
#
|
72
|
+
desc "Stop unicorn"
|
73
|
+
task :stop, :roles => :app do
|
74
|
+
find_servers(:roles => :app).each do |server|
|
75
|
+
if unicorn_is_running?(server)
|
76
|
+
run "kill -s QUIT `cat #{unicorn_pid}`", :hosts => [server]
|
77
|
+
run "rm #{unicorn_pid}", :hosts => [server]
|
78
|
+
logger.info nice_output("Stopped Unicorn!", server)
|
79
|
+
else
|
80
|
+
logger.info nice_output("Unicorn _not_ running, nothing to stop!", server)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Restarts the unicorn process(es) with the URS2 code, to gracefully
|
86
|
+
# create a new server, and kill of the old one, leaving *no* downtime.
|
87
|
+
#
|
88
|
+
desc "Zero-downtime restart of Unicorn"
|
89
|
+
task :restart do
|
90
|
+
find_servers(:roles => :app).each do |server|
|
91
|
+
if unicorn_is_running?(server)
|
92
|
+
pid = capture "cat #{unicorn_pid}", :hosts => [server]
|
93
|
+
run "kill -s USR2 #{pid.to_i}", :hosts => [server] if pid.to_i > 0
|
94
|
+
sleep(1)
|
95
|
+
clean_old_unicorn(server)
|
96
|
+
logger.info nice_output("Restarted Unicorn!", server)
|
97
|
+
else
|
98
|
+
start_unicorn(server)
|
99
|
+
logger.info nice_output("Unicorn wasn't running, starting it!", server)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
desc "Restart of Unicorn with downtime"
|
105
|
+
task :hard_restart do
|
106
|
+
unicorn.stop
|
107
|
+
sleep(1)
|
108
|
+
unicorn.start
|
109
|
+
end
|
110
|
+
|
111
|
+
# Displays the unicorn log.
|
112
|
+
#
|
113
|
+
desc "Displays the unicorn log"
|
114
|
+
task :log, :roles => :app do
|
115
|
+
run "tail -f #{shared_path}/log/unicorn.stderr.log" do |channel,stream,data|
|
116
|
+
logger.info nice_output(data, channel[:host])
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# This will clean up any old unicorn servers left behind by the USR2 kill
|
121
|
+
# command.
|
122
|
+
#
|
123
|
+
desc "Cleans up the old unicorn processes"
|
124
|
+
task :cleanup, :roles => :app do
|
125
|
+
find_servers(:roles => :app).each do |server|
|
126
|
+
clean_old_unicorn(server)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
if Capistrano::Configuration.instance
|
136
|
+
SimpleCapistranoUnicorn::CapistranoIntegration.load_into(Capistrano::Configuration.instance)
|
137
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "simple-capistrano-unicorn/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = "simple-capistrano-unicorn"
|
7
|
+
gem.version = Capistrano::Unicorn::Methods::VERSION
|
8
|
+
gem.authors = ["Kasper Grubbe"]
|
9
|
+
gem.email = ["kaspergrubbe@gmail.com"]
|
10
|
+
gem.homepage = "http://kaspergrubbe.dk"
|
11
|
+
gem.summary = %q{Contains a collection of simple tasks to manage Unicorn with Capistrano.}
|
12
|
+
gem.description = %q{Contains a collection of simple tasks to manage Unicorn with Capistrano.}
|
13
|
+
|
14
|
+
gem.rubyforge_project = "simple-capistrano-unicorn"
|
15
|
+
|
16
|
+
gem.files = `git ls-files`.split("\n")
|
17
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
gem.require_paths = ["lib"]
|
20
|
+
|
21
|
+
gem.add_development_dependency "rake"
|
22
|
+
|
23
|
+
gem.add_runtime_dependency "unicorn"
|
24
|
+
gem.add_runtime_dependency 'capistrano'
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simple-capistrano-unicorn
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 25
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Kasper Grubbe
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2013-01-10 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rake
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: unicorn
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
version: "0"
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: capistrano
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
type: :runtime
|
61
|
+
version_requirements: *id003
|
62
|
+
description: Contains a collection of simple tasks to manage Unicorn with Capistrano.
|
63
|
+
email:
|
64
|
+
- kaspergrubbe@gmail.com
|
65
|
+
executables: []
|
66
|
+
|
67
|
+
extensions: []
|
68
|
+
|
69
|
+
extra_rdoc_files: []
|
70
|
+
|
71
|
+
files:
|
72
|
+
- .gitignore
|
73
|
+
- CHANGELOG.md
|
74
|
+
- Gemfile
|
75
|
+
- README.md
|
76
|
+
- Rakefile
|
77
|
+
- lib/simple-capistrano-unicorn.rb
|
78
|
+
- lib/simple-capistrano-unicorn/namespace.rb
|
79
|
+
- lib/simple-capistrano-unicorn/version.rb
|
80
|
+
- simple-capistrano-unicorn.gemspec
|
81
|
+
homepage: http://kaspergrubbe.dk
|
82
|
+
licenses: []
|
83
|
+
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
hash: 3
|
95
|
+
segments:
|
96
|
+
- 0
|
97
|
+
version: "0"
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
hash: 3
|
104
|
+
segments:
|
105
|
+
- 0
|
106
|
+
version: "0"
|
107
|
+
requirements: []
|
108
|
+
|
109
|
+
rubyforge_project: simple-capistrano-unicorn
|
110
|
+
rubygems_version: 1.8.24
|
111
|
+
signing_key:
|
112
|
+
specification_version: 3
|
113
|
+
summary: Contains a collection of simple tasks to manage Unicorn with Capistrano.
|
114
|
+
test_files: []
|
115
|
+
|