passenger-recipes 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +14 -0
- data/Manifest.txt +8 -0
- data/README.txt +84 -0
- data/Rakefile +33 -0
- data/lib/passenger-recipes.rb +2 -0
- data/lib/passenger-recipes/passenger.rb +167 -0
- data/lib/passenger-recipes/version.rb +20 -0
- data/passenger-recipes.gemspec +35 -0
- metadata +82 -0
data/History.txt
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
=== v0.1.2
|
2
|
+
2008-09-12
|
3
|
+
|
4
|
+
* The 'adduser' command in deploy:setup had :centos and :ubuntu criss-crossed. Also, updated some of the task
|
5
|
+
descriptions, and cleaned up some unused variables.
|
6
|
+
|
7
|
+
* Started to recognize the :target_os property. It currently supports :centos and :ubuntu for values, and only affects
|
8
|
+
the output given by deploy:setup.
|
9
|
+
|
10
|
+
=== v0.1.1
|
11
|
+
2008-08-25
|
12
|
+
* Loosened the dependency on capistrano-extensions from =0.1.2 to >=0.1.2. capistrano-extensions jumped to 0.1.3 today.
|
13
|
+
|
14
|
+
|
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
= passenger-recipes
|
2
|
+
|
3
|
+
* http://github.com/jtrupiano/passenger-recipes/tree/master
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
This gem provides a set of recipes for deploying with Passenger. It's much
|
7
|
+
more restrictive than Capistrano in the sense that it 'locks down' some
|
8
|
+
aspects of what Capistrano actually allows. See the FEATURES section
|
9
|
+
below for more specific details.
|
10
|
+
|
11
|
+
== INCOMPLETE ==
|
12
|
+
* Missing a detailed sample config file
|
13
|
+
* This README is still quite sparse-- add in summaries for each new task
|
14
|
+
* Describe changes to default deploy recipes
|
15
|
+
* Discuss dependencies a bit more
|
16
|
+
* Implement OS-specific default values (Ubuntu and CentOS at a minimum)
|
17
|
+
|
18
|
+
== FEATURES/PROBLEMS:
|
19
|
+
|
20
|
+
* Enforces non-root deployment. The deploy:setup task does not actually
|
21
|
+
execute anything, but rather outputs a set of instructions for you
|
22
|
+
to manually execute. The reason for this is that certain aspects of
|
23
|
+
setting up a server require root access. Incremental deployment, by
|
24
|
+
contrast, does not require this level of privilege. As such, we
|
25
|
+
recommend that you take care of setting up your server by yourself.
|
26
|
+
|
27
|
+
Note: to "lift" this restriction, you can simply override the
|
28
|
+
:ensure_not_root function. However, this is not recommended,
|
29
|
+
considering Apache needs to own all of your files. e.g.
|
30
|
+
|
31
|
+
def ensure_not_root; end
|
32
|
+
|
33
|
+
* Sets up a symlink in the shared directory (passenger.conf) that is
|
34
|
+
updated on each successive deploy. This allows you to change your
|
35
|
+
apache config through a deployment. Note that you'll need sudoer
|
36
|
+
privilege to restart apache (deploy:with_restart) to restart apache.
|
37
|
+
|
38
|
+
* NEW PROPERTIES --> DEFAULTS
|
39
|
+
# Where is the apache config snippet
|
40
|
+
:apache_conf --> {"#{latest_release}/config/#{rails_env}/apache.conf"}
|
41
|
+
|
42
|
+
# Which group does apache run as
|
43
|
+
:apache_group --> www-data
|
44
|
+
|
45
|
+
# Full path to the graceful restart command of apache
|
46
|
+
:apache_restart_cmd --> /usr/sbin/apache2ctl
|
47
|
+
|
48
|
+
== SYNOPSIS:
|
49
|
+
|
50
|
+
FIX (code sample of usage)
|
51
|
+
|
52
|
+
== REQUIREMENTS:
|
53
|
+
|
54
|
+
* capistrano-extensions 0.1.1
|
55
|
+
|
56
|
+
== INSTALL:
|
57
|
+
|
58
|
+
* rake gem
|
59
|
+
* sudo gem install pkg/passenger-recipes-0.1.1.gem --local
|
60
|
+
|
61
|
+
== LICENSE:
|
62
|
+
|
63
|
+
(The MIT License)
|
64
|
+
|
65
|
+
Copyright (c) 2008 FIX
|
66
|
+
|
67
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
68
|
+
a copy of this software and associated documentation files (the
|
69
|
+
'Software'), to deal in the Software without restriction, including
|
70
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
71
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
72
|
+
permit persons to whom the Software is furnished to do so, subject to
|
73
|
+
the following conditions:
|
74
|
+
|
75
|
+
The above copyright notice and this permission notice shall be
|
76
|
+
included in all copies or substantial portions of the Software.
|
77
|
+
|
78
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
79
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
80
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
81
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
82
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
83
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
84
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
require './lib/passenger-recipes.rb'
|
6
|
+
require "./lib/passenger-recipes/version"
|
7
|
+
|
8
|
+
PKG_NAME = "passenger-recipes"
|
9
|
+
PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
|
10
|
+
version = PassengerRecipes::Version::STRING.dup
|
11
|
+
if ENV['SNAPSHOT'].to_i == 1
|
12
|
+
version << "." << Time.now.utc.strftime("%Y%m%d%H%M%S")
|
13
|
+
end
|
14
|
+
PKG_VERSION = version
|
15
|
+
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
16
|
+
|
17
|
+
Hoe.new(PKG_NAME, PKG_VERSION) do |p|
|
18
|
+
p.rubyforge_name = 'johntrupiano' # if different than lowercase project name
|
19
|
+
p.developer('John Trupiano', 'jtrupiano@gmail.com')
|
20
|
+
p.name = PKG_NAME
|
21
|
+
p.version = PKG_VERSION
|
22
|
+
p.author = "John Trupiano"
|
23
|
+
p.email = "jtrupiano@gmail.com"
|
24
|
+
p.description = %q(An opinionated set of capistrano recipes built on top of capistrano-extensions tailored for Phusion Passenger)
|
25
|
+
p.summary = p.description # More details later??
|
26
|
+
p.remote_rdoc_dir = PKG_NAME # Release to /PKG_NAME
|
27
|
+
# p.changes = p.paragraphs_of('CHANGELOG', 0..1).join("\n\n")
|
28
|
+
p.extra_deps << ["capistrano-extensions", ">= 0.1.4"]
|
29
|
+
p.need_zip = true
|
30
|
+
p.need_tar = false
|
31
|
+
end
|
32
|
+
|
33
|
+
# vim: syntax=Ruby
|
@@ -0,0 +1,167 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
abort "passenger-recipes is not compatible with Capistrano 1.x." unless respond_to?(:namespace)
|
3
|
+
|
4
|
+
# Load in the common stuff
|
5
|
+
require 'capistrano-extensions/deploy'
|
6
|
+
puts "Loading Passenger Recipes"
|
7
|
+
|
8
|
+
# Override these at your own discretion!
|
9
|
+
_cset(:apache_conf) {"#{latest_release}/config/#{rails_env}/apache.conf"}
|
10
|
+
_cset(:apache_group, "www-data")
|
11
|
+
#_cset(:apache_restart_cmd, "/usr/sbin/apache2ctl")
|
12
|
+
|
13
|
+
def ensure_not_root
|
14
|
+
raise "Do not deploy as root" if user == "root"
|
15
|
+
end
|
16
|
+
|
17
|
+
# Finally, our passenger-specific recipes.
|
18
|
+
namespace :deploy do
|
19
|
+
desc <<-DESC
|
20
|
+
[passenger]: Displays onscreen the set of privileged tasks you should manually
|
21
|
+
execute on your server. We advise you to manually execute these as root,
|
22
|
+
and then proceed with deployment using a non-privileged user. Execute this task
|
23
|
+
for specific instructions.
|
24
|
+
DESC
|
25
|
+
task :setup, :except => { :no_release => true } do
|
26
|
+
puts "\nBy default, passenger-recipes is configured such that deploy:setup does not execute any remote commands. All of these tasks should be executed manually on your server using an appropriately-privileged user account.\n\n"
|
27
|
+
puts "To get accurate values for the commands below, you should set the following variables: :apache_group, :deploy_to, :user, :application, and :target_os (only :ubuntu and :centos are supported)\n\n"
|
28
|
+
apache_grp = fetch(:apache_group, "<apache_group>")
|
29
|
+
|
30
|
+
case fetch(:target_os, :ubuntu).to_sym
|
31
|
+
when :ubuntu
|
32
|
+
adduser = "adduser --ingroup #{apache_grp} #{user}"
|
33
|
+
link_target = "/etc/apache2/sites-enabled/#{application}.conf"
|
34
|
+
when :centos
|
35
|
+
adduser = "useradd -G #{apache_grp} #{user}"
|
36
|
+
link_target = "/etc/httpd/conf.d/#{application}.conf"
|
37
|
+
end
|
38
|
+
puts <<-TEXT
|
39
|
+
1) $> #{adduser}
|
40
|
+
2) $> mkdir -p #{releases_path} #{content_path} #{log_path}
|
41
|
+
3) $> ln -fs #{shared_path}/passenger.conf #{link_target}
|
42
|
+
4) $> chown -R #{user}:#{apache_grp} #{deploy_to} #{log_path}
|
43
|
+
5) $> chmod 750 #{log_path} #{deploy_to}
|
44
|
+
6) mysql> CREATE DATABASE #{db['database']};
|
45
|
+
GRANT ALL PRIVILEGES ON #{db['database']}.* TO '#{db['username']}'@localhost IDENTIFIED BY '#{db['password']}';
|
46
|
+
TEXT
|
47
|
+
end
|
48
|
+
|
49
|
+
desc <<-DESC
|
50
|
+
[passenger]: Executes a cold deployment. Assumes that the steps detailed in deploy:setup have
|
51
|
+
been manually executed, and that no previous releases have been deployed (or that they have all
|
52
|
+
been removed). Note that this task runs deploy:check before allowing you to deploy.
|
53
|
+
DESC
|
54
|
+
task :cold do
|
55
|
+
ensure_not_root
|
56
|
+
check # let's not deploy if are dependencies aren't met
|
57
|
+
transaction do
|
58
|
+
update
|
59
|
+
load_schema
|
60
|
+
link_apache_config
|
61
|
+
restart_apache
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
desc <<-DESC
|
66
|
+
[passenger]: Executes an iterative deployment. Assumes the app is already up and running.
|
67
|
+
Invoke this task directly if there are no changes to your Apache config file. Otherwise,
|
68
|
+
invoke deploy:with_restart.
|
69
|
+
DESC
|
70
|
+
task :default do
|
71
|
+
ensure_not_root
|
72
|
+
check # let's not deploy if are dependencies aren't met
|
73
|
+
transaction do
|
74
|
+
update
|
75
|
+
migrate
|
76
|
+
link_apache_config
|
77
|
+
restart_app
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
desc <<-DESC
|
82
|
+
[passenger]: Just a regular deploy that also hard restarts apache. This task should be invoked
|
83
|
+
when the apache config file is changed. Otherwise deploy is sufficient.
|
84
|
+
DESC
|
85
|
+
task :with_restart do
|
86
|
+
default
|
87
|
+
restart_apache
|
88
|
+
end
|
89
|
+
|
90
|
+
desc <<-DESC
|
91
|
+
[internal] [passenger]: Drops a symlink into apache's sites-enabled directory. This task
|
92
|
+
should be followed by a restart of apache.
|
93
|
+
DESC
|
94
|
+
task :link_apache_config, :roles => :app do
|
95
|
+
server_file = "#{shared_path}/passenger.conf"
|
96
|
+
on_rollback { run "ln -fs #{previous_release}/config/#{rails_env}/apache.conf #{server_file}" }
|
97
|
+
run "ln -fs #{apache_conf} #{server_file}"
|
98
|
+
end
|
99
|
+
|
100
|
+
desc <<-DESC
|
101
|
+
[passenger]: Outputs a message to the user telling them to manually log in and restart apache.
|
102
|
+
Could potentially allow you to actually execute a command by checking to see if the user has exec
|
103
|
+
rights on the file (via a dependency), but I'm just not sure if we want to allow the deployment
|
104
|
+
user to restart apache.
|
105
|
+
DESC
|
106
|
+
# Hard restarts apache-- the command for this is configurable via the :apache_restart_cmd property.
|
107
|
+
task :restart_apache, :roles => :app do
|
108
|
+
puts "********** LOG INTO THE SERVER AND RESTART APACHE NOW SO THAT YOUR NEW PASSENGER SITE WILL BE SERVED UP ********"
|
109
|
+
#run "#{apache_restart_cmd} restart"
|
110
|
+
end
|
111
|
+
|
112
|
+
desc <<-DESC
|
113
|
+
[passenger]: Soft restarts Passenger by touching /tmp/restart.txt, forcing Apache to reload
|
114
|
+
the Rails context on the next request.
|
115
|
+
DESC
|
116
|
+
task :restart_app, :roles => :app do
|
117
|
+
run "touch #{latest_release}/tmp/restart.txt"
|
118
|
+
end
|
119
|
+
|
120
|
+
# Overwritten
|
121
|
+
desc <<-DESC
|
122
|
+
[internal] [passenger]: Touches up the released code. This is called by update_code \
|
123
|
+
after the basic deploy finishes. It assumes a Rails project was deployed, \
|
124
|
+
so if you are deploying something else, you may want to override this \
|
125
|
+
task with your own environment's requirements.
|
126
|
+
|
127
|
+
This task will make the release group-writable (if the :group_writable \
|
128
|
+
variable is set to true, which is the default). It will then set up \
|
129
|
+
symlinks to the shared directory for the log and tmp directories, and \
|
130
|
+
will lastly touch all assets in public/images, public/stylesheets, and \
|
131
|
+
public/javascripts so that the times are consistent (so that asset \
|
132
|
+
timestamping works). This touch process is only carried out if the \
|
133
|
+
:normalize_asset_timestamps variable is set to true, which is the default.
|
134
|
+
DESC
|
135
|
+
task :finalize_update, :except => { :no_release => true } do
|
136
|
+
run "chmod -R g+w #{latest_release}" if fetch(:group_writable, true)
|
137
|
+
|
138
|
+
# mkdir -p is making sure that the directories are there for some SCM's that don't
|
139
|
+
# save empty folders
|
140
|
+
run <<-CMD
|
141
|
+
rm -rf #{latest_release}/log &&
|
142
|
+
mkdir -p #{latest_release}/public &&
|
143
|
+
mkdir -p #{latest_release}/tmp &&
|
144
|
+
ln -s #{log_path} #{latest_release}/log
|
145
|
+
CMD
|
146
|
+
|
147
|
+
create_shared_file_column_dirs # defined in capistrano-extensions
|
148
|
+
|
149
|
+
if fetch(:normalize_asset_timestamps, true)
|
150
|
+
stamp = Time.now.utc.strftime("%Y%m%d%H%M.%S")
|
151
|
+
asset_paths = %w(images stylesheets javascripts).map { |p| "#{latest_release}/public/#{p}" }.join(" ")
|
152
|
+
run "find #{asset_paths} -exec touch -t #{stamp} {} ';'; true", :env => { "TZ" => "UTC" }
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
desc <<-DESC
|
159
|
+
[internal] [passenger]: Loads the schema.rb file using rake db:schema:load.
|
160
|
+
This task is invoked during deploy:cold. migrate is used in deploy:default.
|
161
|
+
DESC
|
162
|
+
task :load_schema, :roles => :db, :only => { :primary => true } do
|
163
|
+
rake = fetch(:rake, "rake")
|
164
|
+
|
165
|
+
run "cd #{release_path}; #{rake} RAILS_ENV=#{rails_env} db:schema:load"
|
166
|
+
end
|
167
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module PassengerRecipes
|
2
|
+
module Version #:nodoc:
|
3
|
+
# A method for comparing versions of required modules. It expects two
|
4
|
+
# arrays of integers as parameters, the first being the minimum version
|
5
|
+
# required, and the second being the actual version available. It returns
|
6
|
+
# true if the actual version is at least equal to the required version.
|
7
|
+
def self.check(required, actual) #:nodoc:
|
8
|
+
required = required.map { |v| "%06d" % v }.join(".")
|
9
|
+
actual = actual.map { |v| "%06d" % v }.join(".")
|
10
|
+
return actual >= required
|
11
|
+
end
|
12
|
+
|
13
|
+
MAJOR = 0
|
14
|
+
MINOR = 1
|
15
|
+
TINY = 2
|
16
|
+
|
17
|
+
STRING = [MAJOR, MINOR, TINY].join(".")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = %q{passenger-recipes}
|
3
|
+
s.version = "0.1.2"
|
4
|
+
|
5
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
6
|
+
s.authors = ["John Trupiano"]
|
7
|
+
s.date = %q{2008-09-12}
|
8
|
+
s.description = %q{An opinionated set of capistrano recipes built on top of capistrano-extensions tailored for Phusion Passenger}
|
9
|
+
s.email = %q{jtrupiano@gmail.com}
|
10
|
+
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
|
11
|
+
s.files = ["History.txt", "Manifest.txt", "README.txt", "Rakefile", "passenger-recipes.gemspec", "lib/passenger-recipes.rb", "lib/passenger-recipes/passenger.rb", "lib/passenger-recipes/version.rb"]
|
12
|
+
s.has_rdoc = true
|
13
|
+
s.homepage = %q{http://github.com/jtrupiano/passenger-recipes/tree/master}
|
14
|
+
s.rdoc_options = ["--main", "README.txt"]
|
15
|
+
s.require_paths = ["lib"]
|
16
|
+
s.rubyforge_project = %q{johntrupiano}
|
17
|
+
s.rubygems_version = %q{1.2.0}
|
18
|
+
s.summary = %q{An opinionated set of capistrano recipes built on top of capistrano-extensions tailored for Phusion Passenger}
|
19
|
+
|
20
|
+
if s.respond_to? :specification_version then
|
21
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
22
|
+
s.specification_version = 2
|
23
|
+
|
24
|
+
if current_version >= 3 then
|
25
|
+
s.add_runtime_dependency(%q<capistrano-extensions>, [">= 0.1.4"])
|
26
|
+
s.add_development_dependency(%q<hoe>, [">= 1.7.0"])
|
27
|
+
else
|
28
|
+
s.add_dependency(%q<capistrano-extensions>, [">= 0.1.4"])
|
29
|
+
s.add_dependency(%q<hoe>, [">= 1.7.0"])
|
30
|
+
end
|
31
|
+
else
|
32
|
+
s.add_dependency(%q<capistrano-extensions>, [">= 0.1.4"])
|
33
|
+
s.add_dependency(%q<hoe>, [">= 1.7.0"])
|
34
|
+
end
|
35
|
+
end
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: passenger-recipes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- John Trupiano
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-09-12 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: capistrano-extensions
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.1.4
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: hoe
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.7.0
|
34
|
+
version:
|
35
|
+
description: An opinionated set of capistrano recipes built on top of capistrano-extensions tailored for Phusion Passenger
|
36
|
+
email: jtrupiano@gmail.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- History.txt
|
43
|
+
- Manifest.txt
|
44
|
+
- README.txt
|
45
|
+
files:
|
46
|
+
- History.txt
|
47
|
+
- Manifest.txt
|
48
|
+
- README.txt
|
49
|
+
- Rakefile
|
50
|
+
- lib/passenger-recipes.rb
|
51
|
+
- lib/passenger-recipes/passenger.rb
|
52
|
+
- lib/passenger-recipes/version.rb
|
53
|
+
- passenger-recipes.gemspec
|
54
|
+
has_rdoc: true
|
55
|
+
homepage: http://github.com/jtrupiano/passenger-recipes/tree/master
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options:
|
58
|
+
- --main
|
59
|
+
- README.txt
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
version:
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "0"
|
73
|
+
version:
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project: johntrupiano
|
77
|
+
rubygems_version: 1.2.0
|
78
|
+
signing_key:
|
79
|
+
specification_version: 2
|
80
|
+
summary: An opinionated set of capistrano recipes built on top of capistrano-extensions tailored for Phusion Passenger
|
81
|
+
test_files: []
|
82
|
+
|