1
0
Fork 0
mirror of https://github.com/capistrano/capistrano synced 2023-03-27 23:21:18 -04:00

Don't use Jekyll plugins

This commit is contained in:
Kir Shatrov 2014-01-03 22:41:22 +01:00
parent 0d09d38e70
commit 260eba996c
47 changed files with 1617 additions and 1743 deletions

View file

@ -1,5 +1,7 @@
name: Capistrano
pygments: true
safe: true
lsi: false
markdown: redcarpet
redcarpet:
extensions: ["no_intra_emphasis", "fenced_code_blocks", "autolink", "tables", "with_toc_data"]

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>

View file

@ -1,32 +0,0 @@
require 'git'
module Jekyll
class GitActivityTag < Liquid::Tag
def initialize(tag_name, text, tokens)
super
end
def render(context)
result = ""
g = Git.open(File.join(Dir.getwd, ".."))
index = 0
g.log.each do |log|
if(index < 10)
result << "<li>"
result << log.date.strftime("%d %b")
result << " - <a href='https://github.com/capistrano/capistrano-documentation/commit/"
result << log.sha
result << "/'>"
result << log.message
result << "</a></li>"
index += 1
end
end
"<ul>#{result}</ul>"
end
end
end
Liquid::Template.register_tag('gitactivity', Jekyll::GitActivityTag)

View file

@ -1,49 +0,0 @@
require 'unindent'
module Jekyll
class PrismBlock < Liquid::Block
include Liquid::StandardFilters
OPTIONS_SYNTAX = %r{^([a-zA-Z0-9.+#-]+)((\s+\w+(=[0-9,-]+)?)*)$}
def initialize(tag_name, markup, tokens)
super
if markup.strip =~ OPTIONS_SYNTAX
@lang = $1
if defined?($2) && $2 != ''
tmp_options = {}
$2.split.each do |opt|
key, value = opt.split('=')
if value.nil?
value = true
end
tmp_options[key] = value
end
@options = tmp_options
else
@options = { "linenos" => "" }
end
else
raise SyntaxError.new("Syntax Error in 'prism' - Valid syntax: prism <lang> [linenos(='1-5')]")
end
end
def render(context)
code = h(super.unindent!).strip
if @options["linenos"] == true
@options["linenos"] = "1-#{code.lines.count}"
end
<<-HTML
<div>
<pre data-line='#{@options["linenos"]}'><code class='language-#{@lang}'>#{code}</code></pre>
</div>
HTML
end
end
end
Liquid::Template.register_tag('prism', Jekyll::PrismBlock)

View file

@ -1,30 +0,0 @@
require 'git'
module Jekyll
class TableOfContentsTag < Liquid::Tag
def initialize(tag_name, text, tokens)
super
end
def render(context)
result = ""
g = Git.open(File.join(Dir.getwd, ".."))
index = 0
g.log.each do |log|
if(index < 10)
result << "<li>"
result << log.date.strftime("%d %b")
result << " - <a href='https://github.com/capistrano/capistrano-documentation/commit/"
result << log.sha
result << "/'>"
result << log.message
result << "</a></li>"
index += 1
end
end
"<ul>#{result}</ul>"
end
end
end
Liquid::Template.register_tag('table_of_contents', Jekyll::TableOfContentsTag)

View file

@ -111,7 +111,7 @@ acompanying documentation if you want to explore that any further.
The guiding principle is dependency resolution, and interoperability with
other tools, for example:
{% prism ruby %}
{% highlight ruby %}
# Capistrano 3.0.x
task :notify do
this_release_tag = sh("git describe --abbrev=0 --tags")
@ -126,7 +126,7 @@ other tools, for example:
namespace :deploy
task default: :notify
end
{% endprism %}
{% endhighlight %}
The last three lines rely on Rake's additive task declaration, by redefining the
`deploy:default` task by adding another dependency. Rake will automatically
@ -148,9 +148,9 @@ conventions established in the examples we created for you.
To create different stages at installation time, simply set the `STAGES`
environmental variable to a comma separated list of stages:
{% prism bash %}
{% highlight bash %}
$ cap install STAGES=staging,production,ci,qa
{% endprism %}
{% endhighlight %}
#### Parallelism
@ -158,7 +158,7 @@ In former versions of Capistrano there was a *parallel* option to run
different tasks differently on groups of servers, it looked something like
this:
{% prism ruby %}
{% highlight ruby %}
# Capistrano 2.0.x
task :restart do
parallel do |session|
@ -167,7 +167,7 @@ this:
session.else "echo nothing to do"
end
end
{% endprism %}
{% endhighlight %}
This always felt a little unclean, and indeed it's a hack that was originally
implemeted to facilitate rolling deployments at a large German firm by a
@ -176,7 +176,7 @@ went on to found Travis-CI!)
The equivalent code in under Capistrano v3 would look like this:
{% prism ruby %}
{% highlight ruby %}
# Capistrano 3.0.x
task :restart do
on :all, in: :parallel do |host|
@ -190,7 +190,7 @@ The equivalent code in under Capistrano v3 would look like this:
end
end
end
{% endprism %}
{% endhighlight %}
The second block of code, that representing the new Rake derived DSL and
demonstrating how to use the parallel execution mode is a little longer, but I
@ -200,7 +200,7 @@ built-in logging subsystem, keep reading to learn more.
Other modes for parallelism include:
{% prism ruby %}
{% highlight ruby %}
# Capistrano 3.0.x
on :all, in: :groups, max: 3, wait: 5 do
# Take all servers, in groups of three which execute in parallel
@ -220,7 +220,7 @@ Other modes for parallelism include:
# the block in parallel on all servers. This might be perfect for kicking
# off something like a Git checkout or similar.
end
{% endprism %}
{% endhighlight %}
The internal tasks, for standard deploy recipes make use of all of these as is
appropriate for the normal case, no need to be afraid of scary slow deploys
@ -276,7 +276,7 @@ both connections.
This cleanup routine can now be better implemented as follows (which is
actually more or less the actual implementation in the the new Gem):
{% prism ruby %}
{% highlight ruby %}
# Capistrano 3.0.x
desc "Cleanup all old releases (keeps #{fetch(:releases_to_keep_on_cleanup)}
old releases"
@ -288,7 +288,7 @@ actually more or less the actual implementation in the the new Gem):
execute :rm, fetch(:releases_directory).join(r)
end
end
{% endprism %}
{% endhighlight %}
Some handy things to note here are that both server one and server two in our
contrived example will both evaluate that independently, and when both servers
@ -315,16 +315,16 @@ your application.
An example of it's usage might be:
{% prism ruby %}
{% highlight ruby %}
h = SSHKit::Host.new 'example.com'
h.properties.roles ||= %i{wep app}
{% endprism %}
{% endhighlight %}
#### More Expressive Command Language
In Capistrano v2, it wasn't uncommon to find commands such as:
{% prism ruby %}
{% highlight ruby %}
# Capistrano 2.0.x
task :precompile, :roles => lambda { assets_role }, :except => { :no_release => true } do
run <<-CMD.compact
@ -332,11 +332,11 @@ In Capistrano v2, it wasn't uncommon to find commands such as:
RAILS_ENV=#{rails_env.to_s.shellescape} #{asset_env} #{rake} assets:precompile
CMD
end
{% endprism %}
{% endhighlight %}
In Capistrano v3 this looks more like this:
{% prism ruby %}
{% highlight ruby %}
# Capistrano 3.0.x
task :precompile do
on :sprockets_asset_host, reject: lambda { |h| h.properties.no_release } do
@ -347,7 +347,7 @@ In Capistrano v3 this looks more like this:
end
end
end
{% endprism %}
{% endhighlight %}
Again, with other examples this format is a little longer, but much more
expressive, and all the nightmare of shell escaping is handled interally for
@ -393,14 +393,14 @@ from Capistrano.
SSHkit is ideal for use if you need to just connect to a machine and run some
arbitrary command, for example:
{% prism ruby %}
{% highlight ruby %}
# Rakefile (even without Capistrano loaded)
require 'sshkit'
desc "Check the uptime of example.com"
task :uptime do |h|
execute :uptime
end
{% endprism %}
{% endhighlight %}
There is much more than can be done with SSHKit, and we have quite an
extensive [list of
@ -416,10 +416,10 @@ from preceedings, there is a so-called command map for commands.
When executing something like:
{% prism ruby %}
{% highlight ruby %}
# Capistrano 2.0.x
execute "git clone ........ ......."
{% endprism %}
{% endhighlight %}
The command is passed through to the remote server *completely unchanged*.
This includes the options which might be set, such as user, directory, and
@ -428,7 +428,7 @@ allow people to write non-trivial commands in
[heredocs](https://en.wikipedia.org/wiki/Here_document) when the need arises,
for example:
{% prism ruby %}
{% highlight ruby %}
# Capistrano 3.0.x
execute <<-EOBLOCK
# All of this block is interpreted as Bash script
@ -437,27 +437,27 @@ for example:
chmod 0644 /tmp/somefile
end
EOBLOCK
{% endprism %}
{% endhighlight %}
**Caveat:** The SSHKit multiline command sanitizing logic will remove line feeds and add an `;` after each line to separate the commands. So make sure you are not putting a newline between `then` and the following command.
The idiomatic way to write that command in Capistrano v3 is to use the
separated variadaric method to specify the command:
{% prism ruby %}
{% highlight ruby %}
# Capistrano 3.0.x
execute :git, :clone, "........", "......."
{% endprism %}
{% endhighlight %}
... or for the larger example
{% prism ruby %}
{% highlight ruby %}
# Capistrano 3.0.x
file = '/tmp/somefile'
unless test("-e #{file}")
execute :touch, file
end
{% endprism %}
{% endhighlight %}
In this way the *command map* is consulted, the command map maps all unknown
commands (which in this case is `git`, the rest of the line are *arguments* to
@ -469,14 +469,14 @@ indirectly) to determine which `git` to run.
Commands such as `rake` and `rails` are often better prefixed by `bundle
exec`, and in this case could be mapped to:
{% prism ruby %}
{% highlight ruby %}
SSHKit.config.command_map[:rake] = "bundle exec rake"
SSHKit.config.command_map[:rails] = "bundle exec rails"
{% endprism %}
{% endhighlight %}
There can also be a `lambda` or `Proc` applied in place of the mapping like so:
{% prism ruby %}
{% highlight ruby %}
SSHKit.config.command_map = Hash.new do |hash, key|
if %i{rails rake bundle clockwork heroku}.include?(key.to_sym)
hash[key] = "/usr/bin/env bundle exec #{key}"
@ -484,7 +484,7 @@ There can also be a `lambda` or `Proc` applied in place of the mapping like so:
hash[key] = "/usr/bin/env #{key}"
end
end
{% endprism %}
{% endhighlight %}
Between these two options there should be quite powerful options to map
commands in your environment without having to override internal tasks from
@ -493,7 +493,7 @@ Capistrano just because a path is different, or a binary has a different name.
This can also be *slightly* abused in environments where *shim* executables
are used, for example `rbenv` *wrappers*:
{% prism ruby %}
{% highlight ruby %}
SSHKit.config.command_map = Hash.new do |hash, key|
if %i{rails rake bundle clockwork heroku}.include?(key.to_sym)
hash[key] = "/usr/bin/env myproject_bundle exec myproject_#{key}"
@ -501,7 +501,7 @@ are used, for example `rbenv` *wrappers*:
hash[key] = "/usr/bin/env #{key}"
end
end
{% endprism %}
{% endhighlight %}
The above assumes that you have done something like `rbenv wrapper default
myproject` which creates wrapper binaries which correctly set up the Ruby
@ -534,7 +534,7 @@ Capistrano exposes the methods `debug()`, `info()`, `warn()`, `error()` and
`fatal()` inside of `on()` blocks which can be used to log using the existing
logging infrastructure and streaming IO formatters:
{% prism ruby %}
{% highlight ruby %}
# Capistrano 3.0.x
on hosts do |host|
f = '/some/file'
@ -544,7 +544,7 @@ logging infrastructure and streaming IO formatters:
info "#{f} already exists on #{host}!"
end
end
{% endprism %}
{% endhighlight %}
### Upgrading

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>
@ -232,22 +233,21 @@ acompanying documentation if you want to explore that any further.</p>
<p>The guiding principle is dependency resolution, and interoperability with
other tools, for example:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
task :notify do
this_release_tag = sh(&quot;git describe --abbrev=0 --tags&quot;)
last_ten_commits = sh(&quot;git log #{this_release_tag}~10..#{this_release_tag}&quot;)
Mail.deliver do
to &quot;team@example.com&quot;
subject &quot;Releasing #{this_release_tag} Now!&quot;
body last_ten_commits
end
end
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">task</span> <span class="ss">:notify</span> <span class="k">do</span>
<span class="n">this_release_tag</span> <span class="o">=</span> <span class="n">sh</span><span class="p">(</span><span class="s2">&quot;git describe --abbrev=0 --tags&quot;</span><span class="p">)</span>
<span class="n">last_ten_commits</span> <span class="o">=</span> <span class="n">sh</span><span class="p">(</span><span class="s2">&quot;git log </span><span class="si">#{</span><span class="n">this_release_tag</span><span class="si">}</span><span class="s2">~10..</span><span class="si">#{</span><span class="n">this_release_tag</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="no">Mail</span><span class="o">.</span><span class="n">deliver</span> <span class="k">do</span>
<span class="n">to</span> <span class="s2">&quot;team@example.com&quot;</span>
<span class="n">subject</span> <span class="s2">&quot;Releasing </span><span class="si">#{</span><span class="n">this_release_tag</span><span class="si">}</span><span class="s2"> Now!&quot;</span>
<span class="n">body</span> <span class="n">last_ten_commits</span>
<span class="k">end</span>
<span class="k">end</span>
namespace :deploy
task default: :notify
end</code></pre>
</div>
<span class="n">namespace</span> <span class="ss">:deploy</span>
<span class="n">task</span> <span class="ss">default</span><span class="p">:</span> <span class="ss">:notify</span>
<span class="k">end</span>
</code></pre></div>
<p>The last three lines rely on Rake&#39;s additive task declaration, by redefining the
<code>deploy:default</code> task by adding another dependency. Rake will automatically
@ -269,9 +269,8 @@ conventions established in the examples we created for you.</p>
<p>To create different stages at installation time, simply set the <code>STAGES</code>
environmental variable to a comma separated list of stages:</p>
<div>
<pre data-line=''><code class='language-bash'>$ cap install STAGES=staging,production,ci,qa</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> <span class="nv">$ </span>cap install <span class="nv">STAGES</span><span class="o">=</span>staging,production,ci,qa
</code></pre></div>
<h4 id="toc_5">Parallelism</h4>
@ -279,16 +278,15 @@ environmental variable to a comma separated list of stages:</p>
different tasks differently on groups of servers, it looked something like
this:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 2.0.x
task :restart do
parallel do |session|
session.when &quot;in?(:app)&quot;, &quot;/u/apps/social/script/restart-mongrel&quot;
session.when &quot;in?(:web)&quot;, &quot;/u/apps/social/script/restart-apache&quot;
session.else &quot;echo nothing to do&quot;
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 2.0.x</span>
<span class="n">task</span> <span class="ss">:restart</span> <span class="k">do</span>
<span class="n">parallel</span> <span class="k">do</span> <span class="o">|</span><span class="n">session</span><span class="o">|</span>
<span class="n">session</span><span class="o">.</span><span class="n">when</span> <span class="s2">&quot;in?(:app)&quot;</span><span class="p">,</span> <span class="s2">&quot;/u/apps/social/script/restart-mongrel&quot;</span>
<span class="n">session</span><span class="o">.</span><span class="n">when</span> <span class="s2">&quot;in?(:web)&quot;</span><span class="p">,</span> <span class="s2">&quot;/u/apps/social/script/restart-apache&quot;</span>
<span class="n">session</span><span class="o">.</span><span class="n">else</span> <span class="s2">&quot;echo nothing to do&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>This always felt a little unclean, and indeed it&#39;s a hack that was originally
implemeted to facilitate rolling deployments at a large German firm by a
@ -297,21 +295,20 @@ went on to found Travis-CI!)</p>
<p>The equivalent code in under Capistrano v3 would look like this:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
task :restart do
on :all, in: :parallel do |host|
if host.roles.include?(:app)
execute &quot;/u/apps/social/script/restart-mongrel&quot;
elsif host.roles.include?(:web)
execute &quot;/u/apps/social/script/restart-web&quot;
else
info sprintf(&quot;Nothing to do for %s with roles %s&quot;, host,
host.properties.roles)
end
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">task</span> <span class="ss">:restart</span> <span class="k">do</span>
<span class="n">on</span> <span class="ss">:all</span><span class="p">,</span> <span class="k">in</span><span class="p">:</span> <span class="ss">:parallel</span> <span class="k">do</span> <span class="o">|</span><span class="n">host</span><span class="o">|</span>
<span class="k">if</span> <span class="n">host</span><span class="o">.</span><span class="n">roles</span><span class="o">.</span><span class="n">include?</span><span class="p">(</span><span class="ss">:app</span><span class="p">)</span>
<span class="n">execute</span> <span class="s2">&quot;/u/apps/social/script/restart-mongrel&quot;</span>
<span class="k">elsif</span> <span class="n">host</span><span class="o">.</span><span class="n">roles</span><span class="o">.</span><span class="n">include?</span><span class="p">(</span><span class="ss">:web</span><span class="p">)</span>
<span class="n">execute</span> <span class="s2">&quot;/u/apps/social/script/restart-web&quot;</span>
<span class="k">else</span>
<span class="n">info</span> <span class="nb">sprintf</span><span class="p">(</span><span class="s2">&quot;Nothing to do for %s with roles %s&quot;</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span>
<span class="n">host</span><span class="o">.</span><span class="n">properties</span><span class="o">.</span><span class="n">roles</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>The second block of code, that representing the new Rake derived DSL and
demonstrating how to use the parallel execution mode is a little longer, but I
@ -321,27 +318,26 @@ built-in logging subsystem, keep reading to learn more.</p>
<p>Other modes for parallelism include:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
on :all, in: :groups, max: 3, wait: 5 do
# Take all servers, in groups of three which execute in parallel
# wait five seconds between groups of servers.
# This is perfect for rolling restarts
end
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">on</span> <span class="ss">:all</span><span class="p">,</span> <span class="k">in</span><span class="p">:</span> <span class="ss">:groups</span><span class="p">,</span> <span class="ss">max</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="ss">wait</span><span class="p">:</span> <span class="mi">5</span> <span class="k">do</span>
<span class="c1"># Take all servers, in groups of three which execute in parallel</span>
<span class="c1"># wait five seconds between groups of servers.</span>
<span class="c1"># This is perfect for rolling restarts</span>
<span class="k">end</span>
on :all, in: :sequence, wait: 15 do
# This takes all servers, in sequence and waits 15 seconds between
# each server, this might be perfect if you are afraid about
# overloading a shared resource, or want to defer the asset compilation
# over your cluster owing to worries about load
end
<span class="n">on</span> <span class="ss">:all</span><span class="p">,</span> <span class="k">in</span><span class="p">:</span> <span class="ss">:sequence</span><span class="p">,</span> <span class="ss">wait</span><span class="p">:</span> <span class="mi">15</span> <span class="k">do</span>
<span class="c1"># This takes all servers, in sequence and waits 15 seconds between</span>
<span class="c1"># each server, this might be perfect if you are afraid about</span>
<span class="c1"># overloading a shared resource, or want to defer the asset compilation</span>
<span class="c1"># over your cluster owing to worries about load</span>
<span class="k">end</span>
on :all, in: :parallel do
# This will simply try and execute the commands contained within
# the block in parallel on all servers. This might be perfect for kicking
# off something like a Git checkout or similar.
end</code></pre>
</div>
<span class="n">on</span> <span class="ss">:all</span><span class="p">,</span> <span class="k">in</span><span class="p">:</span> <span class="ss">:parallel</span> <span class="k">do</span>
<span class="c1"># This will simply try and execute the commands contained within</span>
<span class="c1"># the block in parallel on all servers. This might be perfect for kicking</span>
<span class="c1"># off something like a Git checkout or similar.</span>
<span class="k">end</span>
</code></pre></div>
<p>The internal tasks, for standard deploy recipes make use of all of these as is
appropriate for the normal case, no need to be afraid of scary slow deploys
@ -399,19 +395,18 @@ both connections.</p>
<p>This cleanup routine can now be better implemented as follows (which is
actually more or less the actual implementation in the the new Gem):</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
desc &quot;Cleanup all old releases (keeps #{fetch(:releases_to_keep_on_cleanup)}
old releases&quot;
task :cleanup do
keep_releases = fetch(:releases_to_keep_on_cleanup)
releases = capture(:ls, fetch(:releases_directory))
release_to_delete = releases.sort_by { |r| rn.to_i }.slice(1..-(keep_releases + 1))
releases_to_delete.each do |r|
execute :rm, fetch(:releases_directory).join(r)
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">desc</span> <span class="s2">&quot;Cleanup all old releases (keeps </span><span class="si">#{</span><span class="n">fetch</span><span class="p">(</span><span class="ss">:releases_to_keep_on_cleanup</span><span class="p">)</span><span class="si">}</span><span class="s2"></span>
<span class="s2"> old releases&quot;</span>
<span class="n">task</span> <span class="ss">:cleanup</span> <span class="k">do</span>
<span class="n">keep_releases</span> <span class="o">=</span> <span class="n">fetch</span><span class="p">(</span><span class="ss">:releases_to_keep_on_cleanup</span><span class="p">)</span>
<span class="n">releases</span> <span class="o">=</span> <span class="n">capture</span><span class="p">(</span><span class="ss">:ls</span><span class="p">,</span> <span class="n">fetch</span><span class="p">(</span><span class="ss">:releases_directory</span><span class="p">))</span>
<span class="n">release_to_delete</span> <span class="o">=</span> <span class="n">releases</span><span class="o">.</span><span class="n">sort_by</span> <span class="p">{</span> <span class="o">|</span><span class="n">r</span><span class="o">|</span> <span class="n">rn</span><span class="o">.</span><span class="n">to_i</span> <span class="p">}</span><span class="o">.</span><span class="n">slice</span><span class="p">(</span><span class="mi">1</span><span class="o">.</span><span class="n">.</span><span class="o">-</span><span class="p">(</span><span class="n">keep_releases</span> <span class="o">+</span> <span class="mi">1</span><span class="p">))</span>
<span class="n">releases_to_delete</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">r</span><span class="o">|</span>
<span class="n">execute</span> <span class="ss">:rm</span><span class="p">,</span> <span class="n">fetch</span><span class="p">(</span><span class="ss">:releases_directory</span><span class="p">)</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>Some handy things to note here are that both server one and server two in our
contrived example will both evaluate that independently, and when both servers
@ -438,39 +433,36 @@ your application.</p>
<p>An example of it&#39;s usage might be:</p>
<div>
<pre data-line=''><code class='language-ruby'>h = SSHKit::Host.new &#39;example.com&#39;
h.properties.roles ||= %i{wep app}</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">h</span> <span class="o">=</span> <span class="no">SSHKit</span><span class="o">::</span><span class="no">Host</span><span class="o">.</span><span class="n">new</span> <span class="s1">&#39;example.com&#39;</span>
<span class="n">h</span><span class="o">.</span><span class="n">properties</span><span class="o">.</span><span class="n">roles</span> <span class="o">||=</span> <span class="o">%</span><span class="n">i</span><span class="p">{</span><span class="n">wep</span> <span class="n">app</span><span class="p">}</span>
</code></pre></div>
<h4 id="toc_9">More Expressive Command Language</h4>
<p>In Capistrano v2, it wasn&#39;t uncommon to find commands such as:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 2.0.x
task :precompile, :roles =&gt; lambda { assets_role }, :except =&gt; { :no_release =&gt; true } do
run &lt;&lt;-CMD.compact
cd -- #{latest_release} &amp;&amp;
RAILS_ENV=#{rails_env.to_s.shellescape} #{asset_env} #{rake} assets:precompile
CMD
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 2.0.x</span>
<span class="n">task</span> <span class="ss">:precompile</span><span class="p">,</span> <span class="ss">:roles</span> <span class="o">=&gt;</span> <span class="nb">lambda</span> <span class="p">{</span> <span class="n">assets_role</span> <span class="p">},</span> <span class="ss">:except</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="ss">:no_release</span> <span class="o">=&gt;</span> <span class="kp">true</span> <span class="p">}</span> <span class="k">do</span>
<span class="n">run</span> <span class="o">&lt;&lt;-</span><span class="no">CMD</span><span class="o">.</span><span class="n">compact</span>
<span class="sh"> cd -- #{latest_release} &amp;&amp;</span>
<span class="sh"> RAILS_ENV=#{rails_env.to_s.shellescape} #{asset_env} #{rake} assets:precompile</span>
<span class="no"> CMD</span>
<span class="k">end</span>
</code></pre></div>
<p>In Capistrano v3 this looks more like this:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
task :precompile do
on :sprockets_asset_host, reject: lambda { |h| h.properties.no_release } do
within fetch(:latest_release_directory)
with rails_env: fetch(:rails_env) do
execute :rake, &#39;assets:precompile&#39;
end
end
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">task</span> <span class="ss">:precompile</span> <span class="k">do</span>
<span class="n">on</span> <span class="ss">:sprockets_asset_host</span><span class="p">,</span> <span class="ss">reject</span><span class="p">:</span> <span class="nb">lambda</span> <span class="p">{</span> <span class="o">|</span><span class="n">h</span><span class="o">|</span> <span class="n">h</span><span class="o">.</span><span class="n">properties</span><span class="o">.</span><span class="n">no_release</span> <span class="p">}</span> <span class="k">do</span>
<span class="n">within</span> <span class="n">fetch</span><span class="p">(</span><span class="ss">:latest_release_directory</span><span class="p">)</span>
<span class="n">with</span> <span class="n">rails_env</span><span class="p">:</span> <span class="n">fetch</span><span class="p">(</span><span class="ss">:rails_env</span><span class="p">)</span> <span class="k">do</span>
<span class="n">execute</span> <span class="ss">:rake</span><span class="p">,</span> <span class="s1">&#39;assets:precompile&#39;</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>Again, with other examples this format is a little longer, but much more
expressive, and all the nightmare of shell escaping is handled interally for
@ -516,14 +508,13 @@ from Capistrano.</p>
<p>SSHkit is ideal for use if you need to just connect to a machine and run some
arbitrary command, for example:</p>
<div>
<pre data-line=''><code class='language-ruby'># Rakefile (even without Capistrano loaded)
require &#39;sshkit&#39;
desc &quot;Check the uptime of example.com&quot;
task :uptime do |h|
execute :uptime
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Rakefile (even without Capistrano loaded)</span>
<span class="nb">require</span> <span class="s1">&#39;sshkit&#39;</span>
<span class="n">desc</span> <span class="s2">&quot;Check the uptime of example.com&quot;</span>
<span class="n">task</span> <span class="ss">:uptime</span> <span class="k">do</span> <span class="o">|</span><span class="n">h</span><span class="o">|</span>
<span class="n">execute</span> <span class="ss">:uptime</span>
<span class="k">end</span>
</code></pre></div>
<p>There is much more than can be done with SSHKit, and we have quite an
extensive <a href="https://github.com/leehambley/sshkit/blob/master/EXAMPLES.md">list of
@ -539,10 +530,9 @@ from preceedings, there is a so-called command map for commands.</p>
<p>When executing something like:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 2.0.x
execute &quot;git clone ........ .......&quot;</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 2.0.x</span>
<span class="n">execute</span> <span class="s2">&quot;git clone ........ .......&quot;</span>
</code></pre></div>
<p>The command is passed through to the remote server <em>completely unchanged</em>.
This includes the options which might be set, such as user, directory, and
@ -551,36 +541,33 @@ allow people to write non-trivial commands in
<a href="https://en.wikipedia.org/wiki/Here_document">heredocs</a> when the need arises,
for example:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
execute &lt;&lt;-EOBLOCK
# All of this block is interpreted as Bash script
if ! [ -e /tmp/somefile ]
then touch /tmp/somefile
chmod 0644 /tmp/somefile
end
EOBLOCK</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">execute</span> <span class="o">&lt;&lt;-</span><span class="no">EOBLOCK</span>
<span class="sh"> # All of this block is interpreted as Bash script</span>
<span class="sh"> if ! [ -e /tmp/somefile ]</span>
<span class="sh"> then touch /tmp/somefile</span>
<span class="sh"> chmod 0644 /tmp/somefile</span>
<span class="sh"> end</span>
<span class="no"> EOBLOCK</span>
</code></pre></div>
<p><strong>Caveat:</strong> The SSHKit multiline command sanitizing logic will remove line feeds and add an <code>;</code> after each line to separate the commands. So make sure you are not putting a newline between <code>then</code> and the following command.</p>
<p>The idiomatic way to write that command in Capistrano v3 is to use the
separated variadaric method to specify the command:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
execute :git, :clone, &quot;........&quot;, &quot;.......&quot;</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">execute</span> <span class="ss">:git</span><span class="p">,</span> <span class="ss">:clone</span><span class="p">,</span> <span class="s2">&quot;........&quot;</span><span class="p">,</span> <span class="s2">&quot;.......&quot;</span>
</code></pre></div>
<p>... or for the larger example</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
file = &#39;/tmp/somefile&#39;
unless test(&quot;-e #{file}&quot;)
execute :touch, file
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">file</span> <span class="o">=</span> <span class="s1">&#39;/tmp/somefile&#39;</span>
<span class="k">unless</span> <span class="nb">test</span><span class="p">(</span><span class="s2">&quot;-e </span><span class="si">#{</span><span class="n">file</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">execute</span> <span class="ss">:touch</span><span class="p">,</span> <span class="n">file</span>
<span class="k">end</span>
</code></pre></div>
<p>In this way the <em>command map</em> is consulted, the command map maps all unknown
commands (which in this case is <code>git</code>, the rest of the line are <em>arguments</em> to
@ -592,22 +579,20 @@ indirectly) to determine which <code>git</code> to run.</p>
<p>Commands such as <code>rake</code> and <code>rails</code> are often better prefixed by <code>bundle
exec</code>, and in this case could be mapped to:</p>
<div>
<pre data-line=''><code class='language-ruby'>SSHKit.config.command_map[:rake] = &quot;bundle exec rake&quot;
SSHKit.config.command_map[:rails] = &quot;bundle exec rails&quot;</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="no">SSHKit</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">command_map</span><span class="o">[</span><span class="ss">:rake</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;bundle exec rake&quot;</span>
<span class="no">SSHKit</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">command_map</span><span class="o">[</span><span class="ss">:rails</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;bundle exec rails&quot;</span>
</code></pre></div>
<p>There can also be a <code>lambda</code> or <code>Proc</code> applied in place of the mapping like so:</p>
<div>
<pre data-line=''><code class='language-ruby'>SSHKit.config.command_map = Hash.new do |hash, key|
if %i{rails rake bundle clockwork heroku}.include?(key.to_sym)
hash[key] = &quot;/usr/bin/env bundle exec #{key}&quot;
else
hash[key] = &quot;/usr/bin/env #{key}&quot;
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="no">SSHKit</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">command_map</span> <span class="o">=</span> <span class="no">Hash</span><span class="o">.</span><span class="n">new</span> <span class="k">do</span> <span class="o">|</span><span class="nb">hash</span><span class="p">,</span> <span class="n">key</span><span class="o">|</span>
<span class="k">if</span> <span class="o">%</span><span class="n">i</span><span class="p">{</span><span class="n">rails</span> <span class="n">rake</span> <span class="n">bundle</span> <span class="n">clockwork</span> <span class="n">heroku</span><span class="p">}</span><span class="o">.</span><span class="n">include?</span><span class="p">(</span><span class="n">key</span><span class="o">.</span><span class="n">to_sym</span><span class="p">)</span>
<span class="nb">hash</span><span class="o">[</span><span class="n">key</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;/usr/bin/env bundle exec </span><span class="si">#{</span><span class="n">key</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">else</span>
<span class="nb">hash</span><span class="o">[</span><span class="n">key</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;/usr/bin/env </span><span class="si">#{</span><span class="n">key</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>Between these two options there should be quite powerful options to map
commands in your environment without having to override internal tasks from
@ -616,15 +601,14 @@ Capistrano just because a path is different, or a binary has a different name.</
<p>This can also be <em>slightly</em> abused in environments where <em>shim</em> executables
are used, for example <code>rbenv</code> <em>wrappers</em>:</p>
<div>
<pre data-line=''><code class='language-ruby'>SSHKit.config.command_map = Hash.new do |hash, key|
if %i{rails rake bundle clockwork heroku}.include?(key.to_sym)
hash[key] = &quot;/usr/bin/env myproject_bundle exec myproject_#{key}&quot;
else
hash[key] = &quot;/usr/bin/env #{key}&quot;
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="no">SSHKit</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">command_map</span> <span class="o">=</span> <span class="no">Hash</span><span class="o">.</span><span class="n">new</span> <span class="k">do</span> <span class="o">|</span><span class="nb">hash</span><span class="p">,</span> <span class="n">key</span><span class="o">|</span>
<span class="k">if</span> <span class="o">%</span><span class="n">i</span><span class="p">{</span><span class="n">rails</span> <span class="n">rake</span> <span class="n">bundle</span> <span class="n">clockwork</span> <span class="n">heroku</span><span class="p">}</span><span class="o">.</span><span class="n">include?</span><span class="p">(</span><span class="n">key</span><span class="o">.</span><span class="n">to_sym</span><span class="p">)</span>
<span class="nb">hash</span><span class="o">[</span><span class="n">key</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;/usr/bin/env myproject_bundle exec myproject_</span><span class="si">#{</span><span class="n">key</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">else</span>
<span class="nb">hash</span><span class="o">[</span><span class="n">key</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;/usr/bin/env </span><span class="si">#{</span><span class="n">key</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>The above assumes that you have done something like <code>rbenv wrapper default
myproject</code> which creates wrapper binaries which correctly set up the Ruby
@ -657,17 +641,16 @@ made, or not made as expected.</p>
<code>fatal()</code> inside of <code>on()</code> blocks which can be used to log using the existing
logging infrastructure and streaming IO formatters:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
on hosts do |host|
f = &#39;/some/file&#39;
if test(&quot;[ -d #{f} ]&quot;)
execute :touch, f
else
info &quot;#{f} already exists on #{host}!&quot;
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">on</span> <span class="n">hosts</span> <span class="k">do</span> <span class="o">|</span><span class="n">host</span><span class="o">|</span>
<span class="n">f</span> <span class="o">=</span> <span class="s1">&#39;/some/file&#39;</span>
<span class="k">if</span> <span class="nb">test</span><span class="p">(</span><span class="s2">&quot;[ -d </span><span class="si">#{</span><span class="n">f</span><span class="si">}</span><span class="s2"> ]&quot;</span><span class="p">)</span>
<span class="n">execute</span> <span class="ss">:touch</span><span class="p">,</span> <span class="n">f</span>
<span class="k">else</span>
<span class="n">info</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">f</span><span class="si">}</span><span class="s2"> already exists on </span><span class="si">#{</span><span class="n">host</span><span class="si">}</span><span class="s2">!&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<h3 id="toc_15"> Upgrading</h3>
@ -822,22 +805,21 @@ acompanying documentation if you want to explore that any further.</p>
<p>The guiding principle is dependency resolution, and interoperability with
other tools, for example:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
task :notify do
this_release_tag = sh(&quot;git describe --abbrev=0 --tags&quot;)
last_ten_commits = sh(&quot;git log #{this_release_tag}~10..#{this_release_tag}&quot;)
Mail.deliver do
to &quot;team@example.com&quot;
subject &quot;Releasing #{this_release_tag} Now!&quot;
body last_ten_commits
end
end
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">task</span> <span class="ss">:notify</span> <span class="k">do</span>
<span class="n">this_release_tag</span> <span class="o">=</span> <span class="n">sh</span><span class="p">(</span><span class="s2">&quot;git describe --abbrev=0 --tags&quot;</span><span class="p">)</span>
<span class="n">last_ten_commits</span> <span class="o">=</span> <span class="n">sh</span><span class="p">(</span><span class="s2">&quot;git log </span><span class="si">#{</span><span class="n">this_release_tag</span><span class="si">}</span><span class="s2">~10..</span><span class="si">#{</span><span class="n">this_release_tag</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="no">Mail</span><span class="o">.</span><span class="n">deliver</span> <span class="k">do</span>
<span class="n">to</span> <span class="s2">&quot;team@example.com&quot;</span>
<span class="n">subject</span> <span class="s2">&quot;Releasing </span><span class="si">#{</span><span class="n">this_release_tag</span><span class="si">}</span><span class="s2"> Now!&quot;</span>
<span class="n">body</span> <span class="n">last_ten_commits</span>
<span class="k">end</span>
<span class="k">end</span>
namespace :deploy
task default: :notify
end</code></pre>
</div>
<span class="n">namespace</span> <span class="ss">:deploy</span>
<span class="n">task</span> <span class="ss">default</span><span class="p">:</span> <span class="ss">:notify</span>
<span class="k">end</span>
</code></pre></div>
<p>The last three lines rely on Rake&#39;s additive task declaration, by redefining the
<code>deploy:default</code> task by adding another dependency. Rake will automatically
@ -859,9 +841,8 @@ conventions established in the examples we created for you.</p>
<p>To create different stages at installation time, simply set the <code>STAGES</code>
environmental variable to a comma separated list of stages:</p>
<div>
<pre data-line=''><code class='language-bash'>$ cap install STAGES=staging,production,ci,qa</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> <span class="nv">$ </span>cap install <span class="nv">STAGES</span><span class="o">=</span>staging,production,ci,qa
</code></pre></div>
<h4 id="toc_5">Parallelism</h4>
@ -869,16 +850,15 @@ environmental variable to a comma separated list of stages:</p>
different tasks differently on groups of servers, it looked something like
this:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 2.0.x
task :restart do
parallel do |session|
session.when &quot;in?(:app)&quot;, &quot;/u/apps/social/script/restart-mongrel&quot;
session.when &quot;in?(:web)&quot;, &quot;/u/apps/social/script/restart-apache&quot;
session.else &quot;echo nothing to do&quot;
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 2.0.x</span>
<span class="n">task</span> <span class="ss">:restart</span> <span class="k">do</span>
<span class="n">parallel</span> <span class="k">do</span> <span class="o">|</span><span class="n">session</span><span class="o">|</span>
<span class="n">session</span><span class="o">.</span><span class="n">when</span> <span class="s2">&quot;in?(:app)&quot;</span><span class="p">,</span> <span class="s2">&quot;/u/apps/social/script/restart-mongrel&quot;</span>
<span class="n">session</span><span class="o">.</span><span class="n">when</span> <span class="s2">&quot;in?(:web)&quot;</span><span class="p">,</span> <span class="s2">&quot;/u/apps/social/script/restart-apache&quot;</span>
<span class="n">session</span><span class="o">.</span><span class="n">else</span> <span class="s2">&quot;echo nothing to do&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>This always felt a little unclean, and indeed it&#39;s a hack that was originally
implemeted to facilitate rolling deployments at a large German firm by a
@ -887,21 +867,20 @@ went on to found Travis-CI!)</p>
<p>The equivalent code in under Capistrano v3 would look like this:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
task :restart do
on :all, in: :parallel do |host|
if host.roles.include?(:app)
execute &quot;/u/apps/social/script/restart-mongrel&quot;
elsif host.roles.include?(:web)
execute &quot;/u/apps/social/script/restart-web&quot;
else
info sprintf(&quot;Nothing to do for %s with roles %s&quot;, host,
host.properties.roles)
end
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">task</span> <span class="ss">:restart</span> <span class="k">do</span>
<span class="n">on</span> <span class="ss">:all</span><span class="p">,</span> <span class="k">in</span><span class="p">:</span> <span class="ss">:parallel</span> <span class="k">do</span> <span class="o">|</span><span class="n">host</span><span class="o">|</span>
<span class="k">if</span> <span class="n">host</span><span class="o">.</span><span class="n">roles</span><span class="o">.</span><span class="n">include?</span><span class="p">(</span><span class="ss">:app</span><span class="p">)</span>
<span class="n">execute</span> <span class="s2">&quot;/u/apps/social/script/restart-mongrel&quot;</span>
<span class="k">elsif</span> <span class="n">host</span><span class="o">.</span><span class="n">roles</span><span class="o">.</span><span class="n">include?</span><span class="p">(</span><span class="ss">:web</span><span class="p">)</span>
<span class="n">execute</span> <span class="s2">&quot;/u/apps/social/script/restart-web&quot;</span>
<span class="k">else</span>
<span class="n">info</span> <span class="nb">sprintf</span><span class="p">(</span><span class="s2">&quot;Nothing to do for %s with roles %s&quot;</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span>
<span class="n">host</span><span class="o">.</span><span class="n">properties</span><span class="o">.</span><span class="n">roles</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>The second block of code, that representing the new Rake derived DSL and
demonstrating how to use the parallel execution mode is a little longer, but I
@ -911,27 +890,26 @@ built-in logging subsystem, keep reading to learn more.</p>
<p>Other modes for parallelism include:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
on :all, in: :groups, max: 3, wait: 5 do
# Take all servers, in groups of three which execute in parallel
# wait five seconds between groups of servers.
# This is perfect for rolling restarts
end
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">on</span> <span class="ss">:all</span><span class="p">,</span> <span class="k">in</span><span class="p">:</span> <span class="ss">:groups</span><span class="p">,</span> <span class="ss">max</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="ss">wait</span><span class="p">:</span> <span class="mi">5</span> <span class="k">do</span>
<span class="c1"># Take all servers, in groups of three which execute in parallel</span>
<span class="c1"># wait five seconds between groups of servers.</span>
<span class="c1"># This is perfect for rolling restarts</span>
<span class="k">end</span>
on :all, in: :sequence, wait: 15 do
# This takes all servers, in sequence and waits 15 seconds between
# each server, this might be perfect if you are afraid about
# overloading a shared resource, or want to defer the asset compilation
# over your cluster owing to worries about load
end
<span class="n">on</span> <span class="ss">:all</span><span class="p">,</span> <span class="k">in</span><span class="p">:</span> <span class="ss">:sequence</span><span class="p">,</span> <span class="ss">wait</span><span class="p">:</span> <span class="mi">15</span> <span class="k">do</span>
<span class="c1"># This takes all servers, in sequence and waits 15 seconds between</span>
<span class="c1"># each server, this might be perfect if you are afraid about</span>
<span class="c1"># overloading a shared resource, or want to defer the asset compilation</span>
<span class="c1"># over your cluster owing to worries about load</span>
<span class="k">end</span>
on :all, in: :parallel do
# This will simply try and execute the commands contained within
# the block in parallel on all servers. This might be perfect for kicking
# off something like a Git checkout or similar.
end</code></pre>
</div>
<span class="n">on</span> <span class="ss">:all</span><span class="p">,</span> <span class="k">in</span><span class="p">:</span> <span class="ss">:parallel</span> <span class="k">do</span>
<span class="c1"># This will simply try and execute the commands contained within</span>
<span class="c1"># the block in parallel on all servers. This might be perfect for kicking</span>
<span class="c1"># off something like a Git checkout or similar.</span>
<span class="k">end</span>
</code></pre></div>
<p>The internal tasks, for standard deploy recipes make use of all of these as is
appropriate for the normal case, no need to be afraid of scary slow deploys
@ -989,19 +967,18 @@ both connections.</p>
<p>This cleanup routine can now be better implemented as follows (which is
actually more or less the actual implementation in the the new Gem):</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
desc &quot;Cleanup all old releases (keeps #{fetch(:releases_to_keep_on_cleanup)}
old releases&quot;
task :cleanup do
keep_releases = fetch(:releases_to_keep_on_cleanup)
releases = capture(:ls, fetch(:releases_directory))
release_to_delete = releases.sort_by { |r| rn.to_i }.slice(1..-(keep_releases + 1))
releases_to_delete.each do |r|
execute :rm, fetch(:releases_directory).join(r)
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">desc</span> <span class="s2">&quot;Cleanup all old releases (keeps </span><span class="si">#{</span><span class="n">fetch</span><span class="p">(</span><span class="ss">:releases_to_keep_on_cleanup</span><span class="p">)</span><span class="si">}</span><span class="s2"></span>
<span class="s2"> old releases&quot;</span>
<span class="n">task</span> <span class="ss">:cleanup</span> <span class="k">do</span>
<span class="n">keep_releases</span> <span class="o">=</span> <span class="n">fetch</span><span class="p">(</span><span class="ss">:releases_to_keep_on_cleanup</span><span class="p">)</span>
<span class="n">releases</span> <span class="o">=</span> <span class="n">capture</span><span class="p">(</span><span class="ss">:ls</span><span class="p">,</span> <span class="n">fetch</span><span class="p">(</span><span class="ss">:releases_directory</span><span class="p">))</span>
<span class="n">release_to_delete</span> <span class="o">=</span> <span class="n">releases</span><span class="o">.</span><span class="n">sort_by</span> <span class="p">{</span> <span class="o">|</span><span class="n">r</span><span class="o">|</span> <span class="n">rn</span><span class="o">.</span><span class="n">to_i</span> <span class="p">}</span><span class="o">.</span><span class="n">slice</span><span class="p">(</span><span class="mi">1</span><span class="o">.</span><span class="n">.</span><span class="o">-</span><span class="p">(</span><span class="n">keep_releases</span> <span class="o">+</span> <span class="mi">1</span><span class="p">))</span>
<span class="n">releases_to_delete</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">r</span><span class="o">|</span>
<span class="n">execute</span> <span class="ss">:rm</span><span class="p">,</span> <span class="n">fetch</span><span class="p">(</span><span class="ss">:releases_directory</span><span class="p">)</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>Some handy things to note here are that both server one and server two in our
contrived example will both evaluate that independently, and when both servers
@ -1028,39 +1005,36 @@ your application.</p>
<p>An example of it&#39;s usage might be:</p>
<div>
<pre data-line=''><code class='language-ruby'>h = SSHKit::Host.new &#39;example.com&#39;
h.properties.roles ||= %i{wep app}</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">h</span> <span class="o">=</span> <span class="no">SSHKit</span><span class="o">::</span><span class="no">Host</span><span class="o">.</span><span class="n">new</span> <span class="s1">&#39;example.com&#39;</span>
<span class="n">h</span><span class="o">.</span><span class="n">properties</span><span class="o">.</span><span class="n">roles</span> <span class="o">||=</span> <span class="o">%</span><span class="n">i</span><span class="p">{</span><span class="n">wep</span> <span class="n">app</span><span class="p">}</span>
</code></pre></div>
<h4 id="toc_9">More Expressive Command Language</h4>
<p>In Capistrano v2, it wasn&#39;t uncommon to find commands such as:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 2.0.x
task :precompile, :roles =&gt; lambda { assets_role }, :except =&gt; { :no_release =&gt; true } do
run &lt;&lt;-CMD.compact
cd -- #{latest_release} &amp;&amp;
RAILS_ENV=#{rails_env.to_s.shellescape} #{asset_env} #{rake} assets:precompile
CMD
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 2.0.x</span>
<span class="n">task</span> <span class="ss">:precompile</span><span class="p">,</span> <span class="ss">:roles</span> <span class="o">=&gt;</span> <span class="nb">lambda</span> <span class="p">{</span> <span class="n">assets_role</span> <span class="p">},</span> <span class="ss">:except</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="ss">:no_release</span> <span class="o">=&gt;</span> <span class="kp">true</span> <span class="p">}</span> <span class="k">do</span>
<span class="n">run</span> <span class="o">&lt;&lt;-</span><span class="no">CMD</span><span class="o">.</span><span class="n">compact</span>
<span class="sh"> cd -- #{latest_release} &amp;&amp;</span>
<span class="sh"> RAILS_ENV=#{rails_env.to_s.shellescape} #{asset_env} #{rake} assets:precompile</span>
<span class="no"> CMD</span>
<span class="k">end</span>
</code></pre></div>
<p>In Capistrano v3 this looks more like this:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
task :precompile do
on :sprockets_asset_host, reject: lambda { |h| h.properties.no_release } do
within fetch(:latest_release_directory)
with rails_env: fetch(:rails_env) do
execute :rake, &#39;assets:precompile&#39;
end
end
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">task</span> <span class="ss">:precompile</span> <span class="k">do</span>
<span class="n">on</span> <span class="ss">:sprockets_asset_host</span><span class="p">,</span> <span class="ss">reject</span><span class="p">:</span> <span class="nb">lambda</span> <span class="p">{</span> <span class="o">|</span><span class="n">h</span><span class="o">|</span> <span class="n">h</span><span class="o">.</span><span class="n">properties</span><span class="o">.</span><span class="n">no_release</span> <span class="p">}</span> <span class="k">do</span>
<span class="n">within</span> <span class="n">fetch</span><span class="p">(</span><span class="ss">:latest_release_directory</span><span class="p">)</span>
<span class="n">with</span> <span class="n">rails_env</span><span class="p">:</span> <span class="n">fetch</span><span class="p">(</span><span class="ss">:rails_env</span><span class="p">)</span> <span class="k">do</span>
<span class="n">execute</span> <span class="ss">:rake</span><span class="p">,</span> <span class="s1">&#39;assets:precompile&#39;</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>Again, with other examples this format is a little longer, but much more
expressive, and all the nightmare of shell escaping is handled interally for
@ -1106,14 +1080,13 @@ from Capistrano.</p>
<p>SSHkit is ideal for use if you need to just connect to a machine and run some
arbitrary command, for example:</p>
<div>
<pre data-line=''><code class='language-ruby'># Rakefile (even without Capistrano loaded)
require &#39;sshkit&#39;
desc &quot;Check the uptime of example.com&quot;
task :uptime do |h|
execute :uptime
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Rakefile (even without Capistrano loaded)</span>
<span class="nb">require</span> <span class="s1">&#39;sshkit&#39;</span>
<span class="n">desc</span> <span class="s2">&quot;Check the uptime of example.com&quot;</span>
<span class="n">task</span> <span class="ss">:uptime</span> <span class="k">do</span> <span class="o">|</span><span class="n">h</span><span class="o">|</span>
<span class="n">execute</span> <span class="ss">:uptime</span>
<span class="k">end</span>
</code></pre></div>
<p>There is much more than can be done with SSHKit, and we have quite an
extensive <a href="https://github.com/leehambley/sshkit/blob/master/EXAMPLES.md">list of
@ -1129,10 +1102,9 @@ from preceedings, there is a so-called command map for commands.</p>
<p>When executing something like:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 2.0.x
execute &quot;git clone ........ .......&quot;</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 2.0.x</span>
<span class="n">execute</span> <span class="s2">&quot;git clone ........ .......&quot;</span>
</code></pre></div>
<p>The command is passed through to the remote server <em>completely unchanged</em>.
This includes the options which might be set, such as user, directory, and
@ -1141,36 +1113,33 @@ allow people to write non-trivial commands in
<a href="https://en.wikipedia.org/wiki/Here_document">heredocs</a> when the need arises,
for example:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
execute &lt;&lt;-EOBLOCK
# All of this block is interpreted as Bash script
if ! [ -e /tmp/somefile ]
then touch /tmp/somefile
chmod 0644 /tmp/somefile
end
EOBLOCK</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">execute</span> <span class="o">&lt;&lt;-</span><span class="no">EOBLOCK</span>
<span class="sh"> # All of this block is interpreted as Bash script</span>
<span class="sh"> if ! [ -e /tmp/somefile ]</span>
<span class="sh"> then touch /tmp/somefile</span>
<span class="sh"> chmod 0644 /tmp/somefile</span>
<span class="sh"> end</span>
<span class="no"> EOBLOCK</span>
</code></pre></div>
<p><strong>Caveat:</strong> The SSHKit multiline command sanitizing logic will remove line feeds and add an <code>;</code> after each line to separate the commands. So make sure you are not putting a newline between <code>then</code> and the following command.</p>
<p>The idiomatic way to write that command in Capistrano v3 is to use the
separated variadaric method to specify the command:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
execute :git, :clone, &quot;........&quot;, &quot;.......&quot;</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">execute</span> <span class="ss">:git</span><span class="p">,</span> <span class="ss">:clone</span><span class="p">,</span> <span class="s2">&quot;........&quot;</span><span class="p">,</span> <span class="s2">&quot;.......&quot;</span>
</code></pre></div>
<p>... or for the larger example</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
file = &#39;/tmp/somefile&#39;
unless test(&quot;-e #{file}&quot;)
execute :touch, file
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">file</span> <span class="o">=</span> <span class="s1">&#39;/tmp/somefile&#39;</span>
<span class="k">unless</span> <span class="nb">test</span><span class="p">(</span><span class="s2">&quot;-e </span><span class="si">#{</span><span class="n">file</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">execute</span> <span class="ss">:touch</span><span class="p">,</span> <span class="n">file</span>
<span class="k">end</span>
</code></pre></div>
<p>In this way the <em>command map</em> is consulted, the command map maps all unknown
commands (which in this case is <code>git</code>, the rest of the line are <em>arguments</em> to
@ -1182,22 +1151,20 @@ indirectly) to determine which <code>git</code> to run.</p>
<p>Commands such as <code>rake</code> and <code>rails</code> are often better prefixed by <code>bundle
exec</code>, and in this case could be mapped to:</p>
<div>
<pre data-line=''><code class='language-ruby'>SSHKit.config.command_map[:rake] = &quot;bundle exec rake&quot;
SSHKit.config.command_map[:rails] = &quot;bundle exec rails&quot;</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="no">SSHKit</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">command_map</span><span class="o">[</span><span class="ss">:rake</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;bundle exec rake&quot;</span>
<span class="no">SSHKit</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">command_map</span><span class="o">[</span><span class="ss">:rails</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;bundle exec rails&quot;</span>
</code></pre></div>
<p>There can also be a <code>lambda</code> or <code>Proc</code> applied in place of the mapping like so:</p>
<div>
<pre data-line=''><code class='language-ruby'>SSHKit.config.command_map = Hash.new do |hash, key|
if %i{rails rake bundle clockwork heroku}.include?(key.to_sym)
hash[key] = &quot;/usr/bin/env bundle exec #{key}&quot;
else
hash[key] = &quot;/usr/bin/env #{key}&quot;
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="no">SSHKit</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">command_map</span> <span class="o">=</span> <span class="no">Hash</span><span class="o">.</span><span class="n">new</span> <span class="k">do</span> <span class="o">|</span><span class="nb">hash</span><span class="p">,</span> <span class="n">key</span><span class="o">|</span>
<span class="k">if</span> <span class="o">%</span><span class="n">i</span><span class="p">{</span><span class="n">rails</span> <span class="n">rake</span> <span class="n">bundle</span> <span class="n">clockwork</span> <span class="n">heroku</span><span class="p">}</span><span class="o">.</span><span class="n">include?</span><span class="p">(</span><span class="n">key</span><span class="o">.</span><span class="n">to_sym</span><span class="p">)</span>
<span class="nb">hash</span><span class="o">[</span><span class="n">key</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;/usr/bin/env bundle exec </span><span class="si">#{</span><span class="n">key</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">else</span>
<span class="nb">hash</span><span class="o">[</span><span class="n">key</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;/usr/bin/env </span><span class="si">#{</span><span class="n">key</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>Between these two options there should be quite powerful options to map
commands in your environment without having to override internal tasks from
@ -1206,15 +1173,14 @@ Capistrano just because a path is different, or a binary has a different name.</
<p>This can also be <em>slightly</em> abused in environments where <em>shim</em> executables
are used, for example <code>rbenv</code> <em>wrappers</em>:</p>
<div>
<pre data-line=''><code class='language-ruby'>SSHKit.config.command_map = Hash.new do |hash, key|
if %i{rails rake bundle clockwork heroku}.include?(key.to_sym)
hash[key] = &quot;/usr/bin/env myproject_bundle exec myproject_#{key}&quot;
else
hash[key] = &quot;/usr/bin/env #{key}&quot;
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="no">SSHKit</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">command_map</span> <span class="o">=</span> <span class="no">Hash</span><span class="o">.</span><span class="n">new</span> <span class="k">do</span> <span class="o">|</span><span class="nb">hash</span><span class="p">,</span> <span class="n">key</span><span class="o">|</span>
<span class="k">if</span> <span class="o">%</span><span class="n">i</span><span class="p">{</span><span class="n">rails</span> <span class="n">rake</span> <span class="n">bundle</span> <span class="n">clockwork</span> <span class="n">heroku</span><span class="p">}</span><span class="o">.</span><span class="n">include?</span><span class="p">(</span><span class="n">key</span><span class="o">.</span><span class="n">to_sym</span><span class="p">)</span>
<span class="nb">hash</span><span class="o">[</span><span class="n">key</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;/usr/bin/env myproject_bundle exec myproject_</span><span class="si">#{</span><span class="n">key</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">else</span>
<span class="nb">hash</span><span class="o">[</span><span class="n">key</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;/usr/bin/env </span><span class="si">#{</span><span class="n">key</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>The above assumes that you have done something like <code>rbenv wrapper default
myproject</code> which creates wrapper binaries which correctly set up the Ruby
@ -1247,17 +1213,16 @@ made, or not made as expected.</p>
<code>fatal()</code> inside of <code>on()</code> blocks which can be used to log using the existing
logging infrastructure and streaming IO formatters:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
on hosts do |host|
f = &#39;/some/file&#39;
if test(&quot;[ -d #{f} ]&quot;)
execute :touch, f
else
info &quot;#{f} already exists on #{host}!&quot;
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">on</span> <span class="n">hosts</span> <span class="k">do</span> <span class="o">|</span><span class="n">host</span><span class="o">|</span>
<span class="n">f</span> <span class="o">=</span> <span class="s1">&#39;/some/file&#39;</span>
<span class="k">if</span> <span class="nb">test</span><span class="p">(</span><span class="s2">&quot;[ -d </span><span class="si">#{</span><span class="n">f</span><span class="si">}</span><span class="s2"> ]&quot;</span><span class="p">)</span>
<span class="n">execute</span> <span class="ss">:touch</span><span class="p">,</span> <span class="n">f</span>
<span class="k">else</span>
<span class="n">info</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">f</span><span class="si">}</span><span class="s2"> already exists on </span><span class="si">#{</span><span class="n">host</span><span class="si">}</span><span class="s2">!&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<h3 id="toc_15"> Upgrading</h3>

View file

@ -3,5 +3,5 @@ source "https://rubygems.org"
gem "jekyll"
gem "redcarpet"
gem "unindent"
gem 'github-pages', github: 'github/pages-gem'
# gem 'github-pages', github: 'github/pages-gem'
gem "git"

View file

@ -1,20 +1,6 @@
GIT
remote: git://github.com/github/pages-gem.git
revision: a73cbe4d6b683e0ef1bbeefc01e10daac1498a65
specs:
github-pages (12)
RedCloth (= 4.2.9)
jekyll (= 1.4.2)
kramdown (= 1.2.0)
liquid (= 2.5.4)
maruku (= 0.7.0)
rdiscount (= 2.1.7)
redcarpet (= 2.3.0)
GEM
remote: https://rubygems.org/
specs:
RedCloth (4.2.9)
blankslate (2.1.2.4)
classifier (1.3.4)
fast-stemmer (>= 1.0.0)
@ -36,7 +22,6 @@ GEM
redcarpet (~> 2.3.0)
safe_yaml (~> 0.9.7)
toml (~> 0.1.0)
kramdown (1.2.0)
liquid (2.5.4)
listen (1.3.1)
rb-fsevent (>= 0.9.3)
@ -54,7 +39,6 @@ GEM
ffi (>= 0.5.0)
rb-kqueue (0.2.0)
ffi (>= 0.5.0)
rdiscount (2.1.7)
redcarpet (2.3.0)
safe_yaml (0.9.7)
toml (0.1.0)
@ -67,7 +51,6 @@ PLATFORMS
DEPENDENCIES
git
github-pages!
jekyll
redcarpet
unindent

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>

View file

@ -14,14 +14,14 @@ h1, h2, h3, h4, h5, h6 {
font-family: 'Enriqueta', serif;
}
p code, li code {
/*p code, li code {
padding: 3px;
background-color: #E6E6E6;
font-family: "droid-sans-mono", Consolas, Monaco, 'Andale Mono', monospace;
font-size: 0.9em;
color: #222;
border-radius: 3px;
}
}*/
footer {
padding: 1em;
@ -52,6 +52,6 @@ footer ul.social.icons li {
height: 44px !important;
}
pre code {
/*pre code {
color: #fff;
}
}*/

60
_site/css/syntax.css Normal file
View file

@ -0,0 +1,60 @@
.highlight { background: #ffffff; padding: 10px; }
.highlight .c { color: #999988; font-style: italic } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { font-weight: bold } /* Keyword */
.highlight .o { font-weight: bold } /* Operator */
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #999999 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { font-weight: bold } /* Keyword.Constant */
.highlight .kd { font-weight: bold } /* Keyword.Declaration */
.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #009999 } /* Literal.Number */
.highlight .s { color: #d14 } /* Literal.String */
.highlight .na { color: #008080 } /* Name.Attribute */
.highlight .nb { color: #0086B3 } /* Name.Builtin */
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
.highlight .no { color: #008080 } /* Name.Constant */
.highlight .ni { color: #800080 } /* Name.Entity */
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
.highlight .nn { color: #555555 } /* Name.Namespace */
.highlight .nt { color: #000080 } /* Name.Tag */
.highlight .nv { color: #008080 } /* Name.Variable */
.highlight .ow { font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #009999 } /* Literal.Number.Float */
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
.highlight .sb { color: #d14 } /* Literal.String.Backtick */
.highlight .sc { color: #d14 } /* Literal.String.Char */
.highlight .sd { color: #d14 } /* Literal.String.Doc */
.highlight .s2 { color: #d14 } /* Literal.String.Double */
.highlight .se { color: #d14 } /* Literal.String.Escape */
.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
.highlight .si { color: #d14 } /* Literal.String.Interpol */
.highlight .sx { color: #d14 } /* Literal.String.Other */
.highlight .sr { color: #009926 } /* Literal.String.Regex */
.highlight .s1 { color: #d14 } /* Literal.String.Single */
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #008080 } /* Name.Variable.Class */
.highlight .vg { color: #008080 } /* Name.Variable.Global */
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>
@ -118,24 +119,24 @@
<div class="large-8 column">
<div class="content">
<h2>Capistrano in ruby script</h2>
<p>Instead of building a config folder and deploy, you may want to programmatically set everything in a single ruby script. This could be done as follows:
<div>
<pre data-line=''><code class='language-ruby'>require &#39;capistrano/all&#39;</p>
<p>Instead of building a config folder and deploy, you may want to programmatically set everything in a single ruby script. This could be done as follows:</p>
<p>stages = &quot;production&quot;
set :application, &#39;my_app_name&#39;
set :repo_url, &#39;<a href="mailto:git@github.com">git@github.com</a>:capistrano/capistrano.git&#39;
set :deploy_to, &#39;/var/www/&#39;
set :stage, :production
role :app, %w{}</p>
<div class="highlight"><pre><code class="ruby"> <span class="nb">require</span> <span class="s1">&#39;capistrano/all&#39;</span>
<p>require &#39;capistrano/setup&#39;
require &#39;capistrano/deploy&#39;
Dir.glob(&#39;capistrano/tasks/*.cap&#39;).each { |r| import r }</p>
<span class="n">stages</span> <span class="o">=</span> <span class="s2">&quot;production&quot;</span>
<span class="n">set</span> <span class="ss">:application</span><span class="p">,</span> <span class="s1">&#39;my_app_name&#39;</span>
<span class="n">set</span> <span class="ss">:repo_url</span><span class="p">,</span> <span class="s1">&#39;git@github.com:capistrano/capistrano.git&#39;</span>
<span class="n">set</span> <span class="ss">:deploy_to</span><span class="p">,</span> <span class="s1">&#39;/var/www/&#39;</span>
<span class="n">set</span> <span class="ss">:stage</span><span class="p">,</span> <span class="ss">:production</span>
<span class="n">role</span> <span class="ss">:app</span><span class="p">,</span> <span class="sx">%w{}</span>
<p>Capistrano::Application.invoke(&quot;production&quot;)
Capistrano::Application.invoke(&quot;deploy&quot;)</code></pre>
</div></p>
<span class="nb">require</span> <span class="s1">&#39;capistrano/setup&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;capistrano/deploy&#39;</span>
<span class="no">Dir</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="s1">&#39;capistrano/tasks/*.cap&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">r</span><span class="o">|</span> <span class="n">import</span> <span class="n">r</span> <span class="p">}</span>
<span class="no">Capistrano</span><span class="o">::</span><span class="no">Application</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span><span class="s2">&quot;production&quot;</span><span class="p">)</span>
<span class="no">Capistrano</span><span class="o">::</span><span class="no">Application</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span><span class="s2">&quot;deploy&quot;</span><span class="p">)</span>
</code></pre></div>
<p>Note that the require order is important as the stage needs to be set before you load setup and deploy.</p>
@ -148,24 +149,24 @@ Capistrano::Application.invoke(&quot;deploy&quot;)</code></pre>
<!-- <a class="extra" href="/">home</a> -->
<!-- </div> -->
<!-- <p>Instead of building a config folder and deploy, you may want to programmatically set everything in a single ruby script. This could be done as follows:
<div>
<pre data-line=''><code class='language-ruby'>require &#39;capistrano/all&#39;</p>
<!-- <p>Instead of building a config folder and deploy, you may want to programmatically set everything in a single ruby script. This could be done as follows:</p>
<p>stages = &quot;production&quot;
set :application, &#39;my_app_name&#39;
set :repo_url, &#39;<a href="mailto:git@github.com">git@github.com</a>:capistrano/capistrano.git&#39;
set :deploy_to, &#39;/var/www/&#39;
set :stage, :production
role :app, %w{}</p>
<div class="highlight"><pre><code class="ruby"> <span class="nb">require</span> <span class="s1">&#39;capistrano/all&#39;</span>
<p>require &#39;capistrano/setup&#39;
require &#39;capistrano/deploy&#39;
Dir.glob(&#39;capistrano/tasks/*.cap&#39;).each { |r| import r }</p>
<span class="n">stages</span> <span class="o">=</span> <span class="s2">&quot;production&quot;</span>
<span class="n">set</span> <span class="ss">:application</span><span class="p">,</span> <span class="s1">&#39;my_app_name&#39;</span>
<span class="n">set</span> <span class="ss">:repo_url</span><span class="p">,</span> <span class="s1">&#39;git@github.com:capistrano/capistrano.git&#39;</span>
<span class="n">set</span> <span class="ss">:deploy_to</span><span class="p">,</span> <span class="s1">&#39;/var/www/&#39;</span>
<span class="n">set</span> <span class="ss">:stage</span><span class="p">,</span> <span class="ss">:production</span>
<span class="n">role</span> <span class="ss">:app</span><span class="p">,</span> <span class="sx">%w{}</span>
<p>Capistrano::Application.invoke(&quot;production&quot;)
Capistrano::Application.invoke(&quot;deploy&quot;)</code></pre>
</div></p>
<span class="nb">require</span> <span class="s1">&#39;capistrano/setup&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;capistrano/deploy&#39;</span>
<span class="no">Dir</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="s1">&#39;capistrano/tasks/*.cap&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">r</span><span class="o">|</span> <span class="n">import</span> <span class="n">r</span> <span class="p">}</span>
<span class="no">Capistrano</span><span class="o">::</span><span class="no">Application</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span><span class="s2">&quot;production&quot;</span><span class="p">)</span>
<span class="no">Capistrano</span><span class="o">::</span><span class="no">Application</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span><span class="s2">&quot;deploy&quot;</span><span class="p">)</span>
</code></pre></div>
<p>Note that the require order is important as the stage needs to be set before you load setup and deploy.</p>
-->

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>
@ -128,14 +129,14 @@ that match a given set of hostnames.</p>
<p>If the filter matches no servers, no actions will be taken.</p>
<p>If you specify a filter, it will match servers that have the listed hostnames,
<p>If you specify a filter, it will match servers that have the listed hostnames,
and it will run <em>all</em> the roles for each server. In other words, it only affects
the servers the task runs on, not what tasks are run on a server. </p>
the servers the task runs on, not what tasks are run on a server.</p>
<p>You can limit by role and by host; if you do this, the role filtering will
apply first. For example, lets say you filtered by the role <code>app</code>, then by
the hostnames <code>server1</code> and <code>server2</code>. Capistrano would first filter the
available servers to only those with the role <code>app</code>, then filter them
available servers to only those with the role <code>app</code>, then filter them
to look for servers with the hostname <code>server1</code> or <code>server2</code>. If only <code>server2</code>
had the role <code>app</code> (<code>server1</code> has some other role), then in this situation your
task would only run on <code>server2</code>.</p>
@ -149,9 +150,8 @@ task would only run on <code>server2</code>.</p>
<p>Capistrano will read the host filter from the environment variable <code>HOSTS</code>
if it is set. You can set it inline:</p>
<div>
<pre data-line=''><code class='language-bash'>HOSTS=server1,server2 cap production deploy</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> <span class="nv">HOSTS</span><span class="o">=</span>server1,server2 cap production deploy
</code></pre></div>
<p>Specify multiple hosts by separating them with a comma.</p>
@ -160,9 +160,8 @@ if it is set. You can set it inline:</p>
<p>You can set the host filter inside your deploy configuration. For example,
you can set the following inside <code>config/deploy.rb</code>:</p>
<div>
<pre data-line=''><code class='language-ruby'>set :filter, :hosts =&gt; %w{server1 server2}</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">set</span> <span class="ss">:filter</span><span class="p">,</span> <span class="ss">:hosts</span> <span class="o">=&gt;</span> <span class="sx">%w{server1 server2}</span>
</code></pre></div>
<p>Note that you specify the filter as an array rather than as a comma-separated
list of servers when using this method.</p>
@ -172,11 +171,10 @@ list of servers when using this method.</p>
<p>In a similar way to using the environment variable, you can set the role
filter by specifying it as a command line argument to <code>cap</code>:</p>
<div>
<pre data-line=''><code class='language-bash'>cap --hosts=server1,server2 production deploy</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> cap --hosts<span class="o">=</span>server1,server2 production deploy
</code></pre></div>
<p>Like the environment variable method, specify multiple servers by separating
<p>Like the environment variable method, specify multiple servers by separating
them with a comma.</p>
</div>
@ -198,14 +196,14 @@ that match a given set of hostnames.</p>
<p>If the filter matches no servers, no actions will be taken.</p>
<p>If you specify a filter, it will match servers that have the listed hostnames,
<p>If you specify a filter, it will match servers that have the listed hostnames,
and it will run <em>all</em> the roles for each server. In other words, it only affects
the servers the task runs on, not what tasks are run on a server. </p>
the servers the task runs on, not what tasks are run on a server.</p>
<p>You can limit by role and by host; if you do this, the role filtering will
apply first. For example, lets say you filtered by the role <code>app</code>, then by
the hostnames <code>server1</code> and <code>server2</code>. Capistrano would first filter the
available servers to only those with the role <code>app</code>, then filter them
available servers to only those with the role <code>app</code>, then filter them
to look for servers with the hostname <code>server1</code> or <code>server2</code>. If only <code>server2</code>
had the role <code>app</code> (<code>server1</code> has some other role), then in this situation your
task would only run on <code>server2</code>.</p>
@ -219,9 +217,8 @@ task would only run on <code>server2</code>.</p>
<p>Capistrano will read the host filter from the environment variable <code>HOSTS</code>
if it is set. You can set it inline:</p>
<div>
<pre data-line=''><code class='language-bash'>HOSTS=server1,server2 cap production deploy</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> <span class="nv">HOSTS</span><span class="o">=</span>server1,server2 cap production deploy
</code></pre></div>
<p>Specify multiple hosts by separating them with a comma.</p>
@ -230,9 +227,8 @@ if it is set. You can set it inline:</p>
<p>You can set the host filter inside your deploy configuration. For example,
you can set the following inside <code>config/deploy.rb</code>:</p>
<div>
<pre data-line=''><code class='language-ruby'>set :filter, :hosts =&gt; %w{server1 server2}</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">set</span> <span class="ss">:filter</span><span class="p">,</span> <span class="ss">:hosts</span> <span class="o">=&gt;</span> <span class="sx">%w{server1 server2}</span>
</code></pre></div>
<p>Note that you specify the filter as an array rather than as a comma-separated
list of servers when using this method.</p>
@ -242,11 +238,10 @@ list of servers when using this method.</p>
<p>In a similar way to using the environment variable, you can set the role
filter by specifying it as a command line argument to <code>cap</code>:</p>
<div>
<pre data-line=''><code class='language-bash'>cap --hosts=server1,server2 production deploy</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> cap --hosts<span class="o">=</span>server1,server2 production deploy
</code></pre></div>
<p>Like the environment variable method, specify multiple servers by separating
<p>Like the environment variable method, specify multiple servers by separating
them with a comma.</p>
-->

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>
@ -123,19 +124,18 @@
<p>As as example, this task can be used to ensure that files to be linked exist
before running the check:linked_files task:</p>
<div>
<pre data-line=''><code class='language-ruby'>namespace :deploy do
namespace :check do
task :linked_files =&gt; &#39;config/newrelic.yml&#39;
end
end
<div class="highlight"><pre><code class="ruby"> <span class="n">namespace</span> <span class="ss">:deploy</span> <span class="k">do</span>
<span class="n">namespace</span> <span class="ss">:check</span> <span class="k">do</span>
<span class="n">task</span> <span class="ss">:linked_files</span> <span class="o">=&gt;</span> <span class="s1">&#39;config/newrelic.yml&#39;</span>
<span class="k">end</span>
<span class="k">end</span>
remote_file &#39;config/newrelic.yml&#39; =&gt; &#39;/tmp/newrelic.yml&#39;, roles: :app
<span class="n">remote_file</span> <span class="s1">&#39;config/newrelic.yml&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;/tmp/newrelic.yml&#39;</span><span class="p">,</span> <span class="ss">roles</span><span class="p">:</span> <span class="ss">:app</span>
file &#39;/tmp/newrelic.yml&#39; do |t|
sh &quot;curl -o #{t.name} https://rpm.newrelic.com/accounts/xx/newrelic.yml&quot;
end</code></pre>
</div>
<span class="n">file</span> <span class="s1">&#39;/tmp/newrelic.yml&#39;</span> <span class="k">do</span> <span class="o">|</span><span class="n">t</span><span class="o">|</span>
<span class="n">sh</span> <span class="s2">&quot;curl -o </span><span class="si">#{</span><span class="n">t</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2"> https://rpm.newrelic.com/accounts/xx/newrelic.yml&quot;</span>
<span class="k">end</span>
</code></pre></div>
</div>
</div>
@ -151,19 +151,18 @@ end</code></pre>
<p>As as example, this task can be used to ensure that files to be linked exist
before running the check:linked_files task:</p>
<div>
<pre data-line=''><code class='language-ruby'>namespace :deploy do
namespace :check do
task :linked_files =&gt; &#39;config/newrelic.yml&#39;
end
end
<div class="highlight"><pre><code class="ruby"> <span class="n">namespace</span> <span class="ss">:deploy</span> <span class="k">do</span>
<span class="n">namespace</span> <span class="ss">:check</span> <span class="k">do</span>
<span class="n">task</span> <span class="ss">:linked_files</span> <span class="o">=&gt;</span> <span class="s1">&#39;config/newrelic.yml&#39;</span>
<span class="k">end</span>
<span class="k">end</span>
remote_file &#39;config/newrelic.yml&#39; =&gt; &#39;/tmp/newrelic.yml&#39;, roles: :app
<span class="n">remote_file</span> <span class="s1">&#39;config/newrelic.yml&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;/tmp/newrelic.yml&#39;</span><span class="p">,</span> <span class="ss">roles</span><span class="p">:</span> <span class="ss">:app</span>
file &#39;/tmp/newrelic.yml&#39; do |t|
sh &quot;curl -o #{t.name} https://rpm.newrelic.com/accounts/xx/newrelic.yml&quot;
end</code></pre>
</div>
<span class="n">file</span> <span class="s1">&#39;/tmp/newrelic.yml&#39;</span> <span class="k">do</span> <span class="o">|</span><span class="n">t</span><span class="o">|</span>
<span class="n">sh</span> <span class="s2">&quot;curl -o </span><span class="si">#{</span><span class="n">t</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2"> https://rpm.newrelic.com/accounts/xx/newrelic.yml&quot;</span>
<span class="k">end</span>
</code></pre></div>
-->
<!--</div> [> /container <] -->

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>
@ -127,7 +128,7 @@ match a given role or roles.</p>
<p>If the filter matches no servers, no actions will be taken.</p>
<p>If you specify a filter, it will match any servers that have that role, but
<p>If you specify a filter, it will match any servers that have that role, but
it will <em>only</em> run the tasks for that role, not for any other roles that
server may have. For example, if you filtered for servers with the <code>web</code> role,
and a server had both the <code>web</code> and <code>db</code> role, only the <code>web</code> role would
@ -142,9 +143,8 @@ be executed on it.</p>
<p>Capistrano will read the role filter from the environment variable <code>ROLES</code>
if it is set. You can set it inline:</p>
<div>
<pre data-line=''><code class='language-bash'>ROLES=app,web cap production deploy</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> <span class="nv">ROLES</span><span class="o">=</span>app,web cap production deploy
</code></pre></div>
<p>Specify multiple roles by separating them with a comma.</p>
@ -153,9 +153,8 @@ if it is set. You can set it inline:</p>
<p>You can set the role filter inside your deploy configuration. For example,
you can set the following inside <code>config/deploy.rb</code>:</p>
<div>
<pre data-line=''><code class='language-ruby'>set :filter, :roles =&gt; %w{app web}</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">set</span> <span class="ss">:filter</span><span class="p">,</span> <span class="ss">:roles</span> <span class="o">=&gt;</span> <span class="sx">%w{app web}</span>
</code></pre></div>
<p>Note that you specify the filter as an array rather than as a comma-separated
list of roles when using this method.</p>
@ -165,9 +164,8 @@ list of roles when using this method.</p>
<p>In a similar way to using the environment variable, you can set the role
filter by specifying it as a command line argument to <code>cap</code>:</p>
<div>
<pre data-line=''><code class='language-bash'>cap --roles=app,web production deploy</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> cap --roles<span class="o">=</span>app,web production deploy
</code></pre></div>
<p>Like the environment variable method, specify multiple roles by separating them
with a comma.</p>
@ -190,7 +188,7 @@ match a given role or roles.</p>
<p>If the filter matches no servers, no actions will be taken.</p>
<p>If you specify a filter, it will match any servers that have that role, but
<p>If you specify a filter, it will match any servers that have that role, but
it will <em>only</em> run the tasks for that role, not for any other roles that
server may have. For example, if you filtered for servers with the <code>web</code> role,
and a server had both the <code>web</code> and <code>db</code> role, only the <code>web</code> role would
@ -205,9 +203,8 @@ be executed on it.</p>
<p>Capistrano will read the role filter from the environment variable <code>ROLES</code>
if it is set. You can set it inline:</p>
<div>
<pre data-line=''><code class='language-bash'>ROLES=app,web cap production deploy</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> <span class="nv">ROLES</span><span class="o">=</span>app,web cap production deploy
</code></pre></div>
<p>Specify multiple roles by separating them with a comma.</p>
@ -216,9 +213,8 @@ if it is set. You can set it inline:</p>
<p>You can set the role filter inside your deploy configuration. For example,
you can set the following inside <code>config/deploy.rb</code>:</p>
<div>
<pre data-line=''><code class='language-ruby'>set :filter, :roles =&gt; %w{app web}</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">set</span> <span class="ss">:filter</span><span class="p">,</span> <span class="ss">:roles</span> <span class="o">=&gt;</span> <span class="sx">%w{app web}</span>
</code></pre></div>
<p>Note that you specify the filter as an array rather than as a comma-separated
list of roles when using this method.</p>
@ -228,9 +224,8 @@ list of roles when using this method.</p>
<p>In a similar way to using the environment variable, you can set the role
filter by specifying it as a command line argument to <code>cap</code>:</p>
<div>
<pre data-line=''><code class='language-bash'>cap --roles=app,web production deploy</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> cap --roles<span class="o">=</span>app,web production deploy
</code></pre></div>
<p>Like the environment variable method, specify multiple roles by separating them
with a comma.</p>

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>
@ -122,23 +123,22 @@
<p>An example setting a working directory, user and environment variable:</p>
<div>
<pre data-line=''><code class='language-ruby'>on roles(:app), in: :sequence, wait: 5 do
within &quot;/opt/sites/example.com&quot; do
# commands in this block execute in the
# directory: /opt/sites/example.com
as :deploy do
# commands in this block execute as the &quot;deploy&quot; user.
with rails_env: :production do
# commands in this block execute with the environment
# variable RAILS_ENV=production
rake &quot;assets:precompile&quot;
runner &quot;S3::Sync.notify&quot;
end
end
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"><span class="n">on</span> <span class="n">roles</span><span class="p">(</span><span class="ss">:app</span><span class="p">),</span> <span class="k">in</span><span class="p">:</span> <span class="ss">:sequence</span><span class="p">,</span> <span class="ss">wait</span><span class="p">:</span> <span class="mi">5</span> <span class="k">do</span>
<span class="n">within</span> <span class="s2">&quot;/opt/sites/example.com&quot;</span> <span class="k">do</span>
<span class="c1"># commands in this block execute in the</span>
<span class="c1"># directory: /opt/sites/example.com</span>
<span class="n">as</span> <span class="ss">:deploy</span> <span class="k">do</span>
<span class="c1"># commands in this block execute as the &quot;deploy&quot; user.</span>
<span class="n">with</span> <span class="n">rails_env</span><span class="p">:</span> <span class="ss">:production</span> <span class="k">do</span>
<span class="c1"># commands in this block execute with the environment</span>
<span class="c1"># variable RAILS_ENV=production</span>
<span class="n">rake</span> <span class="s2">&quot;assets:precompile&quot;</span>
<span class="n">runner</span> <span class="s2">&quot;S3::Sync.notify&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>For more examples, see the EXAMPLES.md file in the <a href="https://github.com/capistrano/sshkit"><strong>SSHKit</strong></a> project:</p>
@ -157,23 +157,22 @@ end</code></pre>
<p>An example setting a working directory, user and environment variable:</p>
<div>
<pre data-line=''><code class='language-ruby'>on roles(:app), in: :sequence, wait: 5 do
within &quot;/opt/sites/example.com&quot; do
# commands in this block execute in the
# directory: /opt/sites/example.com
as :deploy do
# commands in this block execute as the &quot;deploy&quot; user.
with rails_env: :production do
# commands in this block execute with the environment
# variable RAILS_ENV=production
rake &quot;assets:precompile&quot;
runner &quot;S3::Sync.notify&quot;
end
end
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"><span class="n">on</span> <span class="n">roles</span><span class="p">(</span><span class="ss">:app</span><span class="p">),</span> <span class="k">in</span><span class="p">:</span> <span class="ss">:sequence</span><span class="p">,</span> <span class="ss">wait</span><span class="p">:</span> <span class="mi">5</span> <span class="k">do</span>
<span class="n">within</span> <span class="s2">&quot;/opt/sites/example.com&quot;</span> <span class="k">do</span>
<span class="c1"># commands in this block execute in the</span>
<span class="c1"># directory: /opt/sites/example.com</span>
<span class="n">as</span> <span class="ss">:deploy</span> <span class="k">do</span>
<span class="c1"># commands in this block execute as the &quot;deploy&quot; user.</span>
<span class="n">with</span> <span class="n">rails_env</span><span class="p">:</span> <span class="ss">:production</span> <span class="k">do</span>
<span class="c1"># commands in this block execute with the environment</span>
<span class="c1"># variable RAILS_ENV=production</span>
<span class="n">rake</span> <span class="s2">&quot;assets:precompile&quot;</span>
<span class="n">runner</span> <span class="s2">&quot;S3::Sync.notify&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>For more examples, see the EXAMPLES.md file in the <a href="https://github.com/capistrano/sshkit"><strong>SSHKit</strong></a> project:</p>

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>
@ -177,23 +178,21 @@ figure this out!</p>
<p>First, we&#39;ll try a <em>real</em> SSH session, logging in via our terminal, and seeing
what happens:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh me@remote
me@remote $ [[ $- == *i* ]] &amp;&amp; echo &#39;Interactive&#39; || echo &#39;Not interactive&#39;
Interactive
me@remote $ shopt -q login_shell &amp;&amp; echo &#39;Login shell&#39; || echo &#39;Not login shell&#39;
Login shell</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh me@remote
me@remote <span class="nv">$ </span><span class="o">[[</span> <span class="nv">$-</span> <span class="o">==</span> *i* <span class="o">]]</span> <span class="o">&amp;&amp;</span> <span class="nb">echo</span> <span class="s1">&#39;Interactive&#39;</span> <span class="o">||</span> <span class="nb">echo</span> <span class="s1">&#39;Not interactive&#39;</span>
Interactive
me@remote <span class="nv">$ </span><span class="nb">shopt</span> -q login_shell <span class="o">&amp;&amp;</span> <span class="nb">echo</span> <span class="s1">&#39;Login shell&#39;</span> <span class="o">||</span> <span class="nb">echo</span> <span class="s1">&#39;Not login shell&#39;</span>
Login shell
</code></pre></div>
<p>Contrast that with what happens when we hand the command to run to the SSH
command line without logging in first...</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh me@remote &quot;[[ $- == *i* ]] &amp;&amp; echo &#39;Interactive&#39; || echo &#39;Not interactive&#39;&quot;
Interactive
me@localhost $ ssh me@remote &quot;shopt -q login_shell &amp;&amp; echo &#39;Login shell&#39; || echo &#39;Not login shell&#39;&quot;
Not login shell</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh me@remote <span class="s2">&quot;[[ $- == *i* ]] &amp;&amp; echo &#39;Interactive&#39; || echo &#39;Not interactive&#39;&quot;</span>
Interactive
me@localhost <span class="nv">$ </span>ssh me@remote <span class="s2">&quot;shopt -q login_shell &amp;&amp; echo &#39;Login shell&#39; || echo &#39;Not login shell&#39;&quot;</span>
Not login shell
</code></pre></div>
<p>Here we can see that Bash is still starting in <strong>interactive</strong> mode when we&#39;re
just running a single command, that&#39;s because the terminal we are using is
@ -203,28 +202,26 @@ interactive, and SSH inherits that and passes that on to the remote server.</p>
can have a very simple, Capfile, we don&#39;t even need to load the default
recipes to test this:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
task :query_interactive do
on &#39;me@remote&#39; do
info capture(&quot;[[ $- == *i* ]] &amp;&amp; echo &#39;Interactive&#39; || echo &#39;Not interactive&#39;&quot;)
end
end
task :query_login do
on &#39;me@remote&#39; do
info capture(&quot;shopt -q login_shell &amp;&amp; echo &#39;Login shell&#39; || echo &#39;Not login shell&#39;&quot;)
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">task</span> <span class="ss">:query_interactive</span> <span class="k">do</span>
<span class="n">on</span> <span class="s1">&#39;me@remote&#39;</span> <span class="k">do</span>
<span class="n">info</span> <span class="n">capture</span><span class="p">(</span><span class="s2">&quot;[[ $- == *i* ]] &amp;&amp; echo &#39;Interactive&#39; || echo &#39;Not interactive&#39;&quot;</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">task</span> <span class="ss">:query_login</span> <span class="k">do</span>
<span class="n">on</span> <span class="s1">&#39;me@remote&#39;</span> <span class="k">do</span>
<span class="n">info</span> <span class="n">capture</span><span class="p">(</span><span class="s2">&quot;shopt -q login_shell &amp;&amp; echo &#39;Login shell&#39; || echo &#39;Not login shell&#39;&quot;</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>Gives us the following:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ cap query_login
INFO Not login shell
me@localhost $ cap query_interactive
INFO Not interactive</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>cap query_login
INFO Not login shell
me@localhost <span class="nv">$ </span>cap query_interactive
INFO Not interactive
</code></pre></div>
<h2 id="toc_4"><a id="which_startup_files_loaded"></a>Which shell startup files do get loaded?</h2>
@ -305,23 +302,21 @@ figure this out!</p>
<p>First, we&#39;ll try a <em>real</em> SSH session, logging in via our terminal, and seeing
what happens:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh me@remote
me@remote $ [[ $- == *i* ]] &amp;&amp; echo &#39;Interactive&#39; || echo &#39;Not interactive&#39;
Interactive
me@remote $ shopt -q login_shell &amp;&amp; echo &#39;Login shell&#39; || echo &#39;Not login shell&#39;
Login shell</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh me@remote
me@remote <span class="nv">$ </span><span class="o">[[</span> <span class="nv">$-</span> <span class="o">==</span> *i* <span class="o">]]</span> <span class="o">&amp;&amp;</span> <span class="nb">echo</span> <span class="s1">&#39;Interactive&#39;</span> <span class="o">||</span> <span class="nb">echo</span> <span class="s1">&#39;Not interactive&#39;</span>
Interactive
me@remote <span class="nv">$ </span><span class="nb">shopt</span> -q login_shell <span class="o">&amp;&amp;</span> <span class="nb">echo</span> <span class="s1">&#39;Login shell&#39;</span> <span class="o">||</span> <span class="nb">echo</span> <span class="s1">&#39;Not login shell&#39;</span>
Login shell
</code></pre></div>
<p>Contrast that with what happens when we hand the command to run to the SSH
command line without logging in first...</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh me@remote &quot;[[ $- == *i* ]] &amp;&amp; echo &#39;Interactive&#39; || echo &#39;Not interactive&#39;&quot;
Interactive
me@localhost $ ssh me@remote &quot;shopt -q login_shell &amp;&amp; echo &#39;Login shell&#39; || echo &#39;Not login shell&#39;&quot;
Not login shell</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh me@remote <span class="s2">&quot;[[ $- == *i* ]] &amp;&amp; echo &#39;Interactive&#39; || echo &#39;Not interactive&#39;&quot;</span>
Interactive
me@localhost <span class="nv">$ </span>ssh me@remote <span class="s2">&quot;shopt -q login_shell &amp;&amp; echo &#39;Login shell&#39; || echo &#39;Not login shell&#39;&quot;</span>
Not login shell
</code></pre></div>
<p>Here we can see that Bash is still starting in <strong>interactive</strong> mode when we&#39;re
just running a single command, that&#39;s because the terminal we are using is
@ -331,28 +326,26 @@ interactive, and SSH inherits that and passes that on to the remote server.</p>
can have a very simple, Capfile, we don&#39;t even need to load the default
recipes to test this:</p>
<div>
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
task :query_interactive do
on &#39;me@remote&#39; do
info capture(&quot;[[ $- == *i* ]] &amp;&amp; echo &#39;Interactive&#39; || echo &#39;Not interactive&#39;&quot;)
end
end
task :query_login do
on &#39;me@remote&#39; do
info capture(&quot;shopt -q login_shell &amp;&amp; echo &#39;Login shell&#39; || echo &#39;Not login shell&#39;&quot;)
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># Capistrano 3.0.x</span>
<span class="n">task</span> <span class="ss">:query_interactive</span> <span class="k">do</span>
<span class="n">on</span> <span class="s1">&#39;me@remote&#39;</span> <span class="k">do</span>
<span class="n">info</span> <span class="n">capture</span><span class="p">(</span><span class="s2">&quot;[[ $- == *i* ]] &amp;&amp; echo &#39;Interactive&#39; || echo &#39;Not interactive&#39;&quot;</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">task</span> <span class="ss">:query_login</span> <span class="k">do</span>
<span class="n">on</span> <span class="s1">&#39;me@remote&#39;</span> <span class="k">do</span>
<span class="n">info</span> <span class="n">capture</span><span class="p">(</span><span class="s2">&quot;shopt -q login_shell &amp;&amp; echo &#39;Login shell&#39; || echo &#39;Not login shell&#39;&quot;</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>Gives us the following:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ cap query_login
INFO Not login shell
me@localhost $ cap query_interactive
INFO Not interactive</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>cap query_login
INFO Not login shell
me@localhost <span class="nv">$ </span>cap query_interactive
INFO Not interactive
</code></pre></div>
<h2 id="toc_4"><a id="which_startup_files_loaded"></a>Which shell startup files do get loaded?</h2>

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>
@ -127,10 +128,9 @@ to make this work reliably for unique logins across team members)</p>
<p>To create this deploy user we&#39;ll assume something like the following has been
done:</p>
<div>
<pre data-line=''><code class='language-bash'>root@remote $ adduser deploy
root@remote $ passwd -l deploy</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> root@remote <span class="nv">$ </span>adduser deploy
root@remote <span class="nv">$ </span>passwd -l deploy
</code></pre></div>
<p>The first line creates a completely standard user, it has a home directory,
which we&#39;ll need in a moment, and has a shell, so it may log in. This needs to
@ -170,9 +170,8 @@ public key to the <code>deploy</code> user&#39;s <code>authorized_keys</code> fi
quits or gets fired, you can remove their key from that file, and the rest of
you can keep on shipping!</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh-keygen -t rsa -C &#39;me@my_email_address.com&#39;</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh-keygen -t rsa -C <span class="s1">&#39;me@my_email_address.com&#39;</span>
</code></pre></div>
<p>You&#39;ll be prompted for a passphrase, that&#39;s fine. Type one and keep it safe.
This passphrase ensures that if your computer is stolen, people still need a
@ -188,17 +187,15 @@ minutes upwards.)</p>
<p>We can see which keys are loaded in the SSH agent by running <code>ssh-add -l</code></p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh-add -l
2048 af:ce:7e:c5:93:18:39:ff:54:20:7a:2d:ec:05:7c:a5 /Users/me/.ssh/id_rsa (RSA)</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh-add -l
2048 af:ce:7e:c5:93:18:39:ff:54:20:7a:2d:ec:05:7c:a5 /Users/me/.ssh/id_rsa <span class="o">(</span>RSA<span class="o">)</span>
</code></pre></div>
<p>If you don&#39;t see any keys listed, you can simply run <code>ssh-add</code>:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh-add
Identity added: /Users/me/.ssh/id_rsa (/Users/me/.ssh/id_rsa)</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh-add
Identity added: /Users/me/.ssh/id_rsa <span class="o">(</span>/Users/me/.ssh/id_rsa<span class="o">)</span>
</code></pre></div>
<p>Typically, ssh-add will ask you for the passphrase when you add a key.</p>
@ -214,10 +211,9 @@ additional identity.</p>
<code>/home/users/deploy/.ssh/authorized_keys</code>, to get the contents of that file,
we can ask our local key agent for the public parts of the keys it has loaded:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh-add -L
ssh-rsa jccXJ/JRfGxnkh/8iL........dbfCH/9cDiKa0Dw8XGAo01mU/w== /Users/me/.ssh/id_rsa</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh-add -L
ssh-rsa jccXJ/JRfGxnkh/8iL........dbfCH/9cDiKa0Dw8XGAo01mU/w<span class="o">==</span> /Users/me/.ssh/id_rsa
</code></pre></div>
<p>This will be a lot longer when you run it, I snipped the output because it
looked bad.</p>
@ -232,15 +228,14 @@ none, other none), in the <code>~/.ssh</code> directory which needs the permissi
<a href="http://linux.die.net/man/1/ssh-copy-id"><code>ssh-copy-id</code></a> which streamlines this
process, otherwise the workflow is something like:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh root@remote
root@remote $ su - deploy
deploy@remote $ cd ~
deploy@remote $ mkdir .ssh
deploy@remote $ echo &quot;ssh-rsa jccXJ/JRfGxnkh/8iL........dbfCH/9cDiKa0Dw8XGAo01mU/w== /Users/me/.ssh/id_rsa&quot; &gt;&gt; .ssh/authorized_keys
deploy@remote $ chmod 700 .ssh
deploy@remote $ chmod 600 .ssh/authorized_keys</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh root@remote
root@remote <span class="nv">$ </span>su - deploy
deploy@remote <span class="nv">$ </span><span class="nb">cd</span> ~
deploy@remote <span class="nv">$ </span>mkdir .ssh
deploy@remote <span class="nv">$ </span><span class="nb">echo</span> <span class="s2">&quot;ssh-rsa jccXJ/JRfGxnkh/8iL........dbfCH/9cDiKa0Dw8XGAo01mU/w== /Users/me/.ssh/id_rsa&quot;</span> &gt;&gt; .ssh/authorized_keys
deploy@remote <span class="nv">$ </span>chmod 700 .ssh
deploy@remote <span class="nv">$ </span>chmod 600 .ssh/authorized_keys
</code></pre></div>
<p><strong>Remember:</strong> This needs to be done on every server you want to use, you can
use the same key for each one, but only one key per developer is recommended.
@ -248,11 +243,10 @@ use the same key for each one, but only one key per developer is recommended.
<p>If we did all that correctly, we should now be able to do something like this:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh deploy@one-of-my-servers.com &#39;hostname; uptime&#39;
one-of-my-servers.com
19:23:32 up 62 days, 44 min, 1 user, load average: 0.00, 0.01, 0.05</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh deploy@one-of-my-servers.com <span class="s1">&#39;hostname; uptime&#39;</span>
one-of-my-servers.com
19:23:32 up 62 days, 44 min, 1 user, load average: 0.00, 0.01, 0.05
</code></pre></div>
<p>That should happen without having to enter a passphrase for your SSH key, or
prompting you for an SSH password (which the deploy user doesn&#39;t have anyway).</p>
@ -283,18 +277,17 @@ charset="utf-8"></script>
<p>If your server isn&#39;t accessible directly and you need to use the SSH
ProxyCommand option, you should do</p>
<div>
<pre data-line=''><code class='language-ruby'>require &#39;net/ssh/proxy/command&#39;
<div class="highlight"><pre><code class="ruby"><span class="nb">require</span> <span class="s1">&#39;net/ssh/proxy/command&#39;</span>
set :ssh_options, proxy: Net::SSH::Proxy::Command.new(&#39;ssh mygateway.com -W %h:%p&#39;)
<span class="n">set</span> <span class="ss">:ssh_options</span><span class="p">,</span> <span class="ss">proxy</span><span class="p">:</span> <span class="no">Net</span><span class="o">::</span><span class="no">SSH</span><span class="o">::</span><span class="no">Proxy</span><span class="o">::</span><span class="no">Command</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">&#39;ssh mygateway.com -W %h:%p&#39;</span><span class="p">)</span>
# OR
<span class="c1"># OR</span>
server &#39;internal-hostname&#39;,
ssh_options: {
proxy: Net::SSH::Proxy::Command.new(&#39;ssh mygateway.com -W %h:%p&#39;),
}</code></pre>
</div>
<span class="n">server</span> <span class="s1">&#39;internal-hostname&#39;</span><span class="p">,</span>
<span class="n">ssh_options</span><span class="p">:</span> <span class="p">{</span>
<span class="ss">proxy</span><span class="p">:</span> <span class="no">Net</span><span class="o">::</span><span class="no">SSH</span><span class="o">::</span><span class="no">Proxy</span><span class="o">::</span><span class="no">Command</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">&#39;ssh mygateway.com -W %h:%p&#39;</span><span class="p">),</span>
<span class="p">}</span>
</code></pre></div>
<h4 id="toc_2">1.2 From our servers to the repository host</h4>
@ -311,10 +304,9 @@ Github.</p>
<p>Here&#39;s how we can check if that works, first get the URL of the repository:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ git config remote.origin.url
git@github.com:capistrano/rails3-bootstrap-devise-cancan.git</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>git config remote.origin.url
git@github.com:capistrano/rails3-bootstrap-devise-cancan.git
</code></pre></div>
<p>Here we&#39;re listing our private (for testing purposes) fork of the
rails3-bootstrap-devise-cancan repository forked from the Rails Examples and
@ -322,13 +314,12 @@ Tutorials project.</p>
<p>We can try to access the repository via our server by doing the following:</p>
<div>
<pre data-line=''><code class='language-bash'># List SSH keys that are loaded into the agent
me@localhost $ ssh-add -l
# Make sure they key is loaded if &#39;ssh-add -l&#39; didn&#39;t show anything
me@localhost $ ssh-add
me@localhost $ ssh -A deploy@one-of-my-servers.com &#39;git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> <span class="c"># List SSH keys that are loaded into the agent</span>
me@localhost <span class="nv">$ </span>ssh-add -l
<span class="c"># Make sure they key is loaded if &#39;ssh-add -l&#39; didn&#39;t show anything</span>
me@localhost <span class="nv">$ </span>ssh-add
me@localhost <span class="nv">$ </span>ssh -A deploy@one-of-my-servers.com <span class="err">&#39;</span>git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git
</code></pre></div>
<p>We first check that the agent has the keys loaded. If not we simply load it
and enter the passphrase when prompted.</p>
@ -344,17 +335,16 @@ to the list of known hosts.</p>
<p>From the SSH documentation:</p>
<div>
<pre data-line=''><code class='language-bash'>-A Enables forwarding of the authentication agent connection. This can also be
specified on a per-host basis in a configuration file.
<div class="highlight"><pre><code class="bash"> -A Enables forwarding of the authentication agent connection. This can also be
specified on a per-host basis in a configuration file.
Agent forwarding should be enabled with caution. Users with the ability to
bypass file permissions on the remote host (for the agent&#39;s UNIX-domain
socket) can access the local agent through the forwarded connection. An
attacker cannot obtain key material from the agent, however they can perform
operations on the keys that enable them to authenticate using the identities
loaded into the agent.</code></pre>
</div>
Agent forwarding should be enabled with caution. Users with the ability to
bypass file permissions on the remote host <span class="o">(</span><span class="k">for </span>the agent<span class="err">&#39;</span>s UNIX-domain
socket<span class="o">)</span> can access the <span class="nb">local </span>agent through the forwarded connection. An
attacker cannot obtain key material from the agent, however they can perform
operations on the keys that <span class="nb">enable </span>them to authenticate using the identities
loaded into the agent.
</code></pre></div>
<p>In layman&#39;s terms, you shouldn&#39;t use SSH agent forwarding to machines where you
don&#39;t trust the administrators, as they can can override the permissions on
@ -373,11 +363,10 @@ Github, we&#39;ll be prompted for a username and password:</p>
<h5 id="toc_5">1.2.2.1 With a regular username/password</h5>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ git ls-remote https://github.com/capistrano/rails3-bootstrap-devise-cancan.git
Username for &#39;https://github.com&#39;: myownusername
Password for &#39;https://capistrano@github.com&#39;:</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>git ls-remote https://github.com/capistrano/rails3-bootstrap-devise-cancan.git
Username <span class="k">for</span> <span class="s1">&#39;https://github.com&#39;</span>: myownusername
Password <span class="k">for</span> <span class="s1">&#39;https://capistrano@github.com&#39;</span>:
</code></pre></div>
<p>This challenge response prompt doesn&#39;t work well for automating things, so
there are two ways to get around this depending on your server&#39;s host
@ -388,11 +377,10 @@ because the netrc is a global file that doesn&#39;t lend itself well to security
HTTPS not plain ol&#39; HTTP is to embed the username and password in the URL,
note this won&#39;t work well if your password has special characters:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ git ls-remote https://capistrano:ourverysecretpassword@github.com/capistrano/rails3-bootstrap-devise-cancan.git
3419812c9f146d9a84b44bcc2c3caef94da54758HEAD
3419812c9f146d9a84b44bcc2c3caef94da54758HEADrefs/heads/master</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>git ls-remote https://capistrano:ourverysecretpassword@github.com/capistrano/rails3-bootstrap-devise-cancan.git
3419812c9f146d9a84b44bcc2c3caef94da54758HEAD
3419812c9f146d9a84b44bcc2c3caef94da54758HEADrefs/heads/master
</code></pre></div>
<p>The bigger problem with passwords, whether inlined into the URL, or entered
into a <code>netrc</code> file, is that the password gives access to <strong>your entire Github
@ -405,11 +393,10 @@ at Github, they recently rolled out a feature called <a href="https://github.com
Tokens</a> which allow you to
do something like this:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ git ls-remote https://.....................@github.com/capistrano/rails3-bootstrap-devise-cancan.git
3419812c9f146d9a84b44bcc2c3caef94da54758HEAD
3419812c9f146d9a84b44bcc2c3caef94da54758HEADrefs/heads/master</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>git ls-remote https://.....................@github.com/capistrano/rails3-bootstrap-devise-cancan.git
3419812c9f146d9a84b44bcc2c3caef94da54758HEAD
3419812c9f146d9a84b44bcc2c3caef94da54758HEADrefs/heads/master
</code></pre></div>
<p>Where <code>....</code> is a personal API token, as such:</p>
@ -442,9 +429,8 @@ have configured <em>passwordless</em> <code>sudo</code>. Configuring <code>sudo<
access to come commands under some circumstances is beyond the scope of this
documentation, but sufficed to say something like:</p>
<div>
<pre data-line=''><code class='language-bash'>deploy ALL=NOPASSWD:/etc/init.d/mysqld, /etc/init.d/apache2</code></pre>
</div>
<div class="highlight"><pre><code class="bash">deploy <span class="nv">ALL</span><span class="o">=</span>NOPASSWD:/etc/init.d/mysqld, /etc/init.d/apache2
</code></pre></div>
<p>This example would give the user named <code>deploy</code> access to call <code>sudo
/etc/init.d/mysql _________</code> and the same for the <code>apache2</code> control script.</p>
@ -459,17 +445,16 @@ notice a change.</p>
<p>To configure this hierarchy, ignoring for the moment the passwordless <code>sudo</code>
access that you may or may not need depending how well your servers are setup:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh root@remote
# Capistrano will use /var/www/....... where ... is the value set in
# :application, you can override this by setting the &#39;:deploy_to&#39; variable
root@remote $ deploy_to=/var/www/rails3-bootstrap-devise-cancan-demo
root@remote $ mkdir -p ${deploy_to}
root@remote $ chown deploy:deploy ${deploy_to}
root@remote $ umask 0002
root@remote $ chmod g+s ${deploy_to}
root@remote $ mkdir ${deploy_to}/{releases,shared}</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh root@remote
<span class="c"># Capistrano will use /var/www/....... where ... is the value set in</span>
<span class="c"># :application, you can override this by setting the &#39;:deploy_to&#39; variable</span>
root@remote <span class="nv">$ deploy_to</span><span class="o">=</span>/var/www/rails3-bootstrap-devise-cancan-demo
root@remote <span class="nv">$ </span>mkdir -p <span class="k">${</span><span class="nv">deploy_to</span><span class="k">}</span>
root@remote <span class="nv">$ </span>chown deploy:deploy <span class="k">${</span><span class="nv">deploy_to</span><span class="k">}</span>
root@remote <span class="nv">$ </span><span class="nb">umask </span>0002
root@remote <span class="nv">$ </span>chmod g+s <span class="k">${</span><span class="nv">deploy_to</span><span class="k">}</span>
root@remote <span class="nv">$ </span>mkdir <span class="k">${</span><span class="nv">deploy_to</span><span class="k">}</span>/<span class="o">{</span>releases,shared<span class="o">}</span>
</code></pre></div>
<p><strong>Note:</strong> The <code>chmod g+s</code> is a really handy, and little known Unix feature, it
means that at the operating system level, without having to pay much attention
@ -482,14 +467,13 @@ group: read/write, other: none</em>. This means that we&#39;ll be able to read t
files from Apache, or our web server by running the web server in the <code>deploy</code>
group namespace.</p>
<div>
<pre data-line=''><code class='language-bash'>root@remote # stat -c &quot;%A (%a) %n&quot; ${deploy_to}/
drwx--S--- (2700) /var/www/rails3-bootstrap-devise-cancan-demo
<div class="highlight"><pre><code class="bash"> root@remote <span class="c"># stat -c &quot;%A (%a) %n&quot; ${deploy_to}/</span>
drwx--S--- <span class="o">(</span>2700<span class="o">)</span> /var/www/rails3-bootstrap-devise-cancan-demo
root@remote # stat -c &quot;%A (%a) %n&quot; ${deploy_to}/*
drwxrwsr-x (2775) /var/www/rails3-bootstrap-devise-cancan-demo/releases
drwxrwsr-x (2775) /var/www/rails3-bootstrap-devise-cancan-demo/shared</code></pre>
</div>
root@remote <span class="c"># stat -c &quot;%A (%a) %n&quot; ${deploy_to}/*</span>
drwxrwsr-x <span class="o">(</span>2775<span class="o">)</span> /var/www/rails3-bootstrap-devise-cancan-demo/releases
drwxrwsr-x <span class="o">(</span>2775<span class="o">)</span> /var/www/rails3-bootstrap-devise-cancan-demo/shared
</code></pre></div>
</div>
</div>
@ -509,10 +493,9 @@ to make this work reliably for unique logins across team members)</p>
<p>To create this deploy user we&#39;ll assume something like the following has been
done:</p>
<div>
<pre data-line=''><code class='language-bash'>root@remote $ adduser deploy
root@remote $ passwd -l deploy</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> root@remote <span class="nv">$ </span>adduser deploy
root@remote <span class="nv">$ </span>passwd -l deploy
</code></pre></div>
<p>The first line creates a completely standard user, it has a home directory,
which we&#39;ll need in a moment, and has a shell, so it may log in. This needs to
@ -552,9 +535,8 @@ public key to the <code>deploy</code> user&#39;s <code>authorized_keys</code> fi
quits or gets fired, you can remove their key from that file, and the rest of
you can keep on shipping!</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh-keygen -t rsa -C &#39;me@my_email_address.com&#39;</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh-keygen -t rsa -C <span class="s1">&#39;me@my_email_address.com&#39;</span>
</code></pre></div>
<p>You&#39;ll be prompted for a passphrase, that&#39;s fine. Type one and keep it safe.
This passphrase ensures that if your computer is stolen, people still need a
@ -570,17 +552,15 @@ minutes upwards.)</p>
<p>We can see which keys are loaded in the SSH agent by running <code>ssh-add -l</code></p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh-add -l
2048 af:ce:7e:c5:93:18:39:ff:54:20:7a:2d:ec:05:7c:a5 /Users/me/.ssh/id_rsa (RSA)</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh-add -l
2048 af:ce:7e:c5:93:18:39:ff:54:20:7a:2d:ec:05:7c:a5 /Users/me/.ssh/id_rsa <span class="o">(</span>RSA<span class="o">)</span>
</code></pre></div>
<p>If you don&#39;t see any keys listed, you can simply run <code>ssh-add</code>:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh-add
Identity added: /Users/me/.ssh/id_rsa (/Users/me/.ssh/id_rsa)</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh-add
Identity added: /Users/me/.ssh/id_rsa <span class="o">(</span>/Users/me/.ssh/id_rsa<span class="o">)</span>
</code></pre></div>
<p>Typically, ssh-add will ask you for the passphrase when you add a key.</p>
@ -596,10 +576,9 @@ additional identity.</p>
<code>/home/users/deploy/.ssh/authorized_keys</code>, to get the contents of that file,
we can ask our local key agent for the public parts of the keys it has loaded:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh-add -L
ssh-rsa jccXJ/JRfGxnkh/8iL........dbfCH/9cDiKa0Dw8XGAo01mU/w== /Users/me/.ssh/id_rsa</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh-add -L
ssh-rsa jccXJ/JRfGxnkh/8iL........dbfCH/9cDiKa0Dw8XGAo01mU/w<span class="o">==</span> /Users/me/.ssh/id_rsa
</code></pre></div>
<p>This will be a lot longer when you run it, I snipped the output because it
looked bad.</p>
@ -614,15 +593,14 @@ none, other none), in the <code>~/.ssh</code> directory which needs the permissi
<a href="http://linux.die.net/man/1/ssh-copy-id"><code>ssh-copy-id</code></a> which streamlines this
process, otherwise the workflow is something like:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh root@remote
root@remote $ su - deploy
deploy@remote $ cd ~
deploy@remote $ mkdir .ssh
deploy@remote $ echo &quot;ssh-rsa jccXJ/JRfGxnkh/8iL........dbfCH/9cDiKa0Dw8XGAo01mU/w== /Users/me/.ssh/id_rsa&quot; &gt;&gt; .ssh/authorized_keys
deploy@remote $ chmod 700 .ssh
deploy@remote $ chmod 600 .ssh/authorized_keys</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh root@remote
root@remote <span class="nv">$ </span>su - deploy
deploy@remote <span class="nv">$ </span><span class="nb">cd</span> ~
deploy@remote <span class="nv">$ </span>mkdir .ssh
deploy@remote <span class="nv">$ </span><span class="nb">echo</span> <span class="s2">&quot;ssh-rsa jccXJ/JRfGxnkh/8iL........dbfCH/9cDiKa0Dw8XGAo01mU/w== /Users/me/.ssh/id_rsa&quot;</span> &gt;&gt; .ssh/authorized_keys
deploy@remote <span class="nv">$ </span>chmod 700 .ssh
deploy@remote <span class="nv">$ </span>chmod 600 .ssh/authorized_keys
</code></pre></div>
<p><strong>Remember:</strong> This needs to be done on every server you want to use, you can
use the same key for each one, but only one key per developer is recommended.
@ -630,11 +608,10 @@ use the same key for each one, but only one key per developer is recommended.
<p>If we did all that correctly, we should now be able to do something like this:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh deploy@one-of-my-servers.com &#39;hostname; uptime&#39;
one-of-my-servers.com
19:23:32 up 62 days, 44 min, 1 user, load average: 0.00, 0.01, 0.05</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh deploy@one-of-my-servers.com <span class="s1">&#39;hostname; uptime&#39;</span>
one-of-my-servers.com
19:23:32 up 62 days, 44 min, 1 user, load average: 0.00, 0.01, 0.05
</code></pre></div>
<p>That should happen without having to enter a passphrase for your SSH key, or
prompting you for an SSH password (which the deploy user doesn&#39;t have anyway).</p>
@ -665,18 +642,17 @@ charset="utf-8"></script>
<p>If your server isn&#39;t accessible directly and you need to use the SSH
ProxyCommand option, you should do</p>
<div>
<pre data-line=''><code class='language-ruby'>require &#39;net/ssh/proxy/command&#39;
<div class="highlight"><pre><code class="ruby"><span class="nb">require</span> <span class="s1">&#39;net/ssh/proxy/command&#39;</span>
set :ssh_options, proxy: Net::SSH::Proxy::Command.new(&#39;ssh mygateway.com -W %h:%p&#39;)
<span class="n">set</span> <span class="ss">:ssh_options</span><span class="p">,</span> <span class="ss">proxy</span><span class="p">:</span> <span class="no">Net</span><span class="o">::</span><span class="no">SSH</span><span class="o">::</span><span class="no">Proxy</span><span class="o">::</span><span class="no">Command</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">&#39;ssh mygateway.com -W %h:%p&#39;</span><span class="p">)</span>
# OR
<span class="c1"># OR</span>
server &#39;internal-hostname&#39;,
ssh_options: {
proxy: Net::SSH::Proxy::Command.new(&#39;ssh mygateway.com -W %h:%p&#39;),
}</code></pre>
</div>
<span class="n">server</span> <span class="s1">&#39;internal-hostname&#39;</span><span class="p">,</span>
<span class="n">ssh_options</span><span class="p">:</span> <span class="p">{</span>
<span class="ss">proxy</span><span class="p">:</span> <span class="no">Net</span><span class="o">::</span><span class="no">SSH</span><span class="o">::</span><span class="no">Proxy</span><span class="o">::</span><span class="no">Command</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">&#39;ssh mygateway.com -W %h:%p&#39;</span><span class="p">),</span>
<span class="p">}</span>
</code></pre></div>
<h4 id="toc_2">1.2 From our servers to the repository host</h4>
@ -693,10 +669,9 @@ Github.</p>
<p>Here&#39;s how we can check if that works, first get the URL of the repository:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ git config remote.origin.url
git@github.com:capistrano/rails3-bootstrap-devise-cancan.git</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>git config remote.origin.url
git@github.com:capistrano/rails3-bootstrap-devise-cancan.git
</code></pre></div>
<p>Here we&#39;re listing our private (for testing purposes) fork of the
rails3-bootstrap-devise-cancan repository forked from the Rails Examples and
@ -704,13 +679,12 @@ Tutorials project.</p>
<p>We can try to access the repository via our server by doing the following:</p>
<div>
<pre data-line=''><code class='language-bash'># List SSH keys that are loaded into the agent
me@localhost $ ssh-add -l
# Make sure they key is loaded if &#39;ssh-add -l&#39; didn&#39;t show anything
me@localhost $ ssh-add
me@localhost $ ssh -A deploy@one-of-my-servers.com &#39;git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> <span class="c"># List SSH keys that are loaded into the agent</span>
me@localhost <span class="nv">$ </span>ssh-add -l
<span class="c"># Make sure they key is loaded if &#39;ssh-add -l&#39; didn&#39;t show anything</span>
me@localhost <span class="nv">$ </span>ssh-add
me@localhost <span class="nv">$ </span>ssh -A deploy@one-of-my-servers.com <span class="err">&#39;</span>git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git
</code></pre></div>
<p>We first check that the agent has the keys loaded. If not we simply load it
and enter the passphrase when prompted.</p>
@ -726,17 +700,16 @@ to the list of known hosts.</p>
<p>From the SSH documentation:</p>
<div>
<pre data-line=''><code class='language-bash'>-A Enables forwarding of the authentication agent connection. This can also be
specified on a per-host basis in a configuration file.
<div class="highlight"><pre><code class="bash"> -A Enables forwarding of the authentication agent connection. This can also be
specified on a per-host basis in a configuration file.
Agent forwarding should be enabled with caution. Users with the ability to
bypass file permissions on the remote host (for the agent&#39;s UNIX-domain
socket) can access the local agent through the forwarded connection. An
attacker cannot obtain key material from the agent, however they can perform
operations on the keys that enable them to authenticate using the identities
loaded into the agent.</code></pre>
</div>
Agent forwarding should be enabled with caution. Users with the ability to
bypass file permissions on the remote host <span class="o">(</span><span class="k">for </span>the agent<span class="err">&#39;</span>s UNIX-domain
socket<span class="o">)</span> can access the <span class="nb">local </span>agent through the forwarded connection. An
attacker cannot obtain key material from the agent, however they can perform
operations on the keys that <span class="nb">enable </span>them to authenticate using the identities
loaded into the agent.
</code></pre></div>
<p>In layman&#39;s terms, you shouldn&#39;t use SSH agent forwarding to machines where you
don&#39;t trust the administrators, as they can can override the permissions on
@ -755,11 +728,10 @@ Github, we&#39;ll be prompted for a username and password:</p>
<h5 id="toc_5">1.2.2.1 With a regular username/password</h5>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ git ls-remote https://github.com/capistrano/rails3-bootstrap-devise-cancan.git
Username for &#39;https://github.com&#39;: myownusername
Password for &#39;https://capistrano@github.com&#39;:</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>git ls-remote https://github.com/capistrano/rails3-bootstrap-devise-cancan.git
Username <span class="k">for</span> <span class="s1">&#39;https://github.com&#39;</span>: myownusername
Password <span class="k">for</span> <span class="s1">&#39;https://capistrano@github.com&#39;</span>:
</code></pre></div>
<p>This challenge response prompt doesn&#39;t work well for automating things, so
there are two ways to get around this depending on your server&#39;s host
@ -770,11 +742,10 @@ because the netrc is a global file that doesn&#39;t lend itself well to security
HTTPS not plain ol&#39; HTTP is to embed the username and password in the URL,
note this won&#39;t work well if your password has special characters:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ git ls-remote https://capistrano:ourverysecretpassword@github.com/capistrano/rails3-bootstrap-devise-cancan.git
3419812c9f146d9a84b44bcc2c3caef94da54758HEAD
3419812c9f146d9a84b44bcc2c3caef94da54758HEADrefs/heads/master</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>git ls-remote https://capistrano:ourverysecretpassword@github.com/capistrano/rails3-bootstrap-devise-cancan.git
3419812c9f146d9a84b44bcc2c3caef94da54758HEAD
3419812c9f146d9a84b44bcc2c3caef94da54758HEADrefs/heads/master
</code></pre></div>
<p>The bigger problem with passwords, whether inlined into the URL, or entered
into a <code>netrc</code> file, is that the password gives access to <strong>your entire Github
@ -787,11 +758,10 @@ at Github, they recently rolled out a feature called <a href="https://github.com
Tokens</a> which allow you to
do something like this:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ git ls-remote https://.....................@github.com/capistrano/rails3-bootstrap-devise-cancan.git
3419812c9f146d9a84b44bcc2c3caef94da54758HEAD
3419812c9f146d9a84b44bcc2c3caef94da54758HEADrefs/heads/master</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>git ls-remote https://.....................@github.com/capistrano/rails3-bootstrap-devise-cancan.git
3419812c9f146d9a84b44bcc2c3caef94da54758HEAD
3419812c9f146d9a84b44bcc2c3caef94da54758HEADrefs/heads/master
</code></pre></div>
<p>Where <code>....</code> is a personal API token, as such:</p>
@ -824,9 +794,8 @@ have configured <em>passwordless</em> <code>sudo</code>. Configuring <code>sudo<
access to come commands under some circumstances is beyond the scope of this
documentation, but sufficed to say something like:</p>
<div>
<pre data-line=''><code class='language-bash'>deploy ALL=NOPASSWD:/etc/init.d/mysqld, /etc/init.d/apache2</code></pre>
</div>
<div class="highlight"><pre><code class="bash">deploy <span class="nv">ALL</span><span class="o">=</span>NOPASSWD:/etc/init.d/mysqld, /etc/init.d/apache2
</code></pre></div>
<p>This example would give the user named <code>deploy</code> access to call <code>sudo
/etc/init.d/mysql _________</code> and the same for the <code>apache2</code> control script.</p>
@ -841,17 +810,16 @@ notice a change.</p>
<p>To configure this hierarchy, ignoring for the moment the passwordless <code>sudo</code>
access that you may or may not need depending how well your servers are setup:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh root@remote
# Capistrano will use /var/www/....... where ... is the value set in
# :application, you can override this by setting the &#39;:deploy_to&#39; variable
root@remote $ deploy_to=/var/www/rails3-bootstrap-devise-cancan-demo
root@remote $ mkdir -p ${deploy_to}
root@remote $ chown deploy:deploy ${deploy_to}
root@remote $ umask 0002
root@remote $ chmod g+s ${deploy_to}
root@remote $ mkdir ${deploy_to}/{releases,shared}</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh root@remote
<span class="c"># Capistrano will use /var/www/....... where ... is the value set in</span>
<span class="c"># :application, you can override this by setting the &#39;:deploy_to&#39; variable</span>
root@remote <span class="nv">$ deploy_to</span><span class="o">=</span>/var/www/rails3-bootstrap-devise-cancan-demo
root@remote <span class="nv">$ </span>mkdir -p <span class="k">${</span><span class="nv">deploy_to</span><span class="k">}</span>
root@remote <span class="nv">$ </span>chown deploy:deploy <span class="k">${</span><span class="nv">deploy_to</span><span class="k">}</span>
root@remote <span class="nv">$ </span><span class="nb">umask </span>0002
root@remote <span class="nv">$ </span>chmod g+s <span class="k">${</span><span class="nv">deploy_to</span><span class="k">}</span>
root@remote <span class="nv">$ </span>mkdir <span class="k">${</span><span class="nv">deploy_to</span><span class="k">}</span>/<span class="o">{</span>releases,shared<span class="o">}</span>
</code></pre></div>
<p><strong>Note:</strong> The <code>chmod g+s</code> is a really handy, and little known Unix feature, it
means that at the operating system level, without having to pay much attention
@ -864,14 +832,13 @@ group: read/write, other: none</em>. This means that we&#39;ll be able to read t
files from Apache, or our web server by running the web server in the <code>deploy</code>
group namespace.</p>
<div>
<pre data-line=''><code class='language-bash'>root@remote # stat -c &quot;%A (%a) %n&quot; ${deploy_to}/
drwx--S--- (2700) /var/www/rails3-bootstrap-devise-cancan-demo
<div class="highlight"><pre><code class="bash"> root@remote <span class="c"># stat -c &quot;%A (%a) %n&quot; ${deploy_to}/</span>
drwx--S--- <span class="o">(</span>2700<span class="o">)</span> /var/www/rails3-bootstrap-devise-cancan-demo
root@remote # stat -c &quot;%A (%a) %n&quot; ${deploy_to}/*
drwxrwsr-x (2775) /var/www/rails3-bootstrap-devise-cancan-demo/releases
drwxrwsr-x (2775) /var/www/rails3-bootstrap-devise-cancan-demo/shared</code></pre>
</div>
root@remote <span class="c"># stat -c &quot;%A (%a) %n&quot; ${deploy_to}/*</span>
drwxrwsr-x <span class="o">(</span>2775<span class="o">)</span> /var/www/rails3-bootstrap-devise-cancan-demo/releases
drwxrwsr-x <span class="o">(</span>2775<span class="o">)</span> /var/www/rails3-bootstrap-devise-cancan-demo/shared
</code></pre></div>
-->
<!--</div> [> /container <] -->

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>
@ -135,19 +136,18 @@ technologies.</p>
<h3 id="toc_0">1. Checking the directory structure on the remote machine:</h3>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh deploy@remote &#39;ls -lR /var/www/my-application&#39;
my-application:
total 8
drwxrwsr-x 2 deploy deploy 4096 Jun 24 20:55 releases
drwxrwsr-x 2 deploy deploy 4096 Jun 24 20:55 shared
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh deploy@remote <span class="s1">&#39;ls -lR /var/www/my-application&#39;</span>
my-application:
total 8
drwxrwsr-x 2 deploy deploy 4096 Jun 24 20:55 releases
drwxrwsr-x 2 deploy deploy 4096 Jun 24 20:55 shared
my-application/releases:
total 0
my-application/releases:
total 0
my-application/shared:
total 0</code></pre>
</div>
my-application/shared:
total 0
</code></pre></div>
<p>This checks in one simple command that the ssh keys you setup are working (you
might yet be prompted for the password), and the permissions on the directory
@ -159,18 +159,17 @@ can be seen.</p>
quickly introduce ourselves to a quick Cap task to check these things on all
the machines for us:</p>
<div>
<pre data-line=''><code class='language-ruby'>desc &quot;Check that we can access everything&quot;
task :check_write_permissions do
on roles(:all) do |host|
if test(&quot;[ -w #{fetch(:deploy_to)} ]&quot;)
info &quot;#{fetch(:deploy_to)} is writable on #{host}&quot;
else
error &quot;#{fetch(:deploy_to)} is not writable on #{host}&quot;
end
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">desc</span> <span class="s2">&quot;Check that we can access everything&quot;</span>
<span class="n">task</span> <span class="ss">:check_write_permissions</span> <span class="k">do</span>
<span class="n">on</span> <span class="n">roles</span><span class="p">(</span><span class="ss">:all</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">host</span><span class="o">|</span>
<span class="k">if</span> <span class="nb">test</span><span class="p">(</span><span class="s2">&quot;[ -w </span><span class="si">#{</span><span class="n">fetch</span><span class="p">(</span><span class="ss">:deploy_to</span><span class="p">)</span><span class="si">}</span><span class="s2"> ]&quot;</span><span class="p">)</span>
<span class="n">info</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">fetch</span><span class="p">(</span><span class="ss">:deploy_to</span><span class="p">)</span><span class="si">}</span><span class="s2"> is writable on </span><span class="si">#{</span><span class="n">host</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">else</span>
<span class="n">error</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">fetch</span><span class="p">(</span><span class="ss">:deploy_to</span><span class="p">)</span><span class="si">}</span><span class="s2"> is not writable on </span><span class="si">#{</span><span class="n">host</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>Running this should give you a pretty decent overview, one line of output for
each server. It&#39;s also your first introduction to the API of Capistrano for
@ -185,22 +184,20 @@ later, but add those lines to a file in <code>./lib/capistrano/tasks</code>, cal
something like <code>access_check.cap</code>, and run <code>cap -T</code> from the top directory and
we&#39;ll be able to see the task listed:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ bundle exec cap -T
# ... lots of other tasks ...
cap check_write_permissions # Check that we can access everything
# ... lots of other tasks ...</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>bundle <span class="nb">exec </span>cap -T
<span class="c"># ... lots of other tasks ...</span>
cap check_write_permissions <span class="c"># Check that we can access everything</span>
<span class="c"># ... lots of other tasks ...</span>
</code></pre></div>
<p>Then we simply call it:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ bundle exec cap staging check_write_permissions
DEBUG [82c92144] Running /usr/bin/env [ -w /var/www/my-application ] on myserver.com
DEBUG [82c92144] Command: [ -w /var/www/my-application ]
DEBUG [82c92144] Finished in 0.456 seconds command successful.
INFO /var/www/my-application is writable on myserver.com</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>bundle <span class="nb">exec </span>cap staging check_write_permissions
DEBUG <span class="o">[</span>82c92144<span class="o">]</span> Running /usr/bin/env <span class="o">[</span> -w /var/www/my-application <span class="o">]</span> on myserver.com
DEBUG <span class="o">[</span>82c92144<span class="o">]</span> Command: <span class="o">[</span> -w /var/www/my-application <span class="o">]</span>
DEBUG <span class="o">[</span>82c92144<span class="o">]</span> Finished in 0.456 seconds <span class="nb">command </span>successful.
INFO /var/www/my-application is writable on myserver.com
</code></pre></div>
<p>If we&#39;ve done something wrong, that won&#39;t happen and we&#39;ll know that we need
to jump on the mailing list to get help, into IRC or ask a friend.</p>
@ -213,9 +210,8 @@ wrap Git in a shell script that makes it behave.</p>
<p>Capistrano does just this, so to check if the Git access is working, we can
simply call:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ cap staging git:check</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>cap staging git:check
</code></pre></div>
<p>This task is defined
<a href="https://github.com/capistrano/capistrano/blob/master/lib/capistrano/tasks/git.rake">here</a>
@ -228,26 +224,25 @@ one of the pieces we inherit from Rake)</p>
<p>If this fails we&#39;ll see:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ cap staging git:check
cap staging git:check
DEBUG Uploading /tmp/git-ssh.sh 0%
INFO Uploading /tmp/git-ssh.sh 100%
INFO [118bd3e4] Running /usr/bin/env chmod +x /tmp/git-ssh.sh on example.com
DEBUG [118bd3e4] Command: /usr/bin/env chmod +x /tmp/git-ssh.sh
INFO [118bd3e4] Finished in 0.049 seconds command successful.
INFO [a996463f] Running /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git on harrow
DEBUG [a996463f] Command: ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/git-ssh.sh /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git )
DEBUG [a996463f] Warning: Permanently added &#39;github.com,204.232.175.90&#39; (RSA) to the list of known hosts.
DEBUG [a996463f] Permission denied (publickey).
DEBUG [a996463f] fatal: The remote end hung up unexpectedly
cap aborted!
git stdout: Nothing written
git stderr: Nothing written
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>cap staging git:check
cap staging git:check
DEBUG Uploading /tmp/git-ssh.sh 0%
INFO Uploading /tmp/git-ssh.sh 100%
INFO <span class="o">[</span>118bd3e4<span class="o">]</span> Running /usr/bin/env chmod +x /tmp/git-ssh.sh on example.com
DEBUG <span class="o">[</span>118bd3e4<span class="o">]</span> Command: /usr/bin/env chmod +x /tmp/git-ssh.sh
INFO <span class="o">[</span>118bd3e4<span class="o">]</span> Finished in 0.049 seconds <span class="nb">command </span>successful.
INFO <span class="o">[</span>a996463f<span class="o">]</span> Running /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git on harrow
DEBUG <span class="o">[</span>a996463f<span class="o">]</span> Command: <span class="o">(</span> <span class="nv">GIT_ASKPASS</span><span class="o">=</span>/bin/echo <span class="nv">GIT_SSH</span><span class="o">=</span>/tmp/git-ssh.sh /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git <span class="o">)</span>
DEBUG <span class="o">[</span>a996463f<span class="o">]</span> Warning: Permanently added <span class="s1">&#39;github.com,204.232.175.90&#39;</span> <span class="o">(</span>RSA<span class="o">)</span> to the list of known hosts.
DEBUG <span class="o">[</span>a996463f<span class="o">]</span> Permission denied <span class="o">(</span>publickey<span class="o">)</span>.
DEBUG <span class="o">[</span>a996463f<span class="o">]</span> fatal: The remote end hung up unexpectedly
cap aborted!
git stdout: Nothing written
git stderr: Nothing written
Tasks: TOP =&gt; git:check
(See full trace by running task with --trace)</code></pre>
</div>
Tasks: <span class="nv">TOP</span> <span class="o">=</span>&gt; git:check
<span class="o">(</span>See full trace by running task with --trace<span class="o">)</span>
</code></pre></div>
<p>This&#39;ll typically come out looking more beautiful depending on your terminal
colour support, you may well see something like this:</p>
@ -276,56 +271,52 @@ printed out the error messages for us to try and figure out what broke.</li>
working by writing a tiny Cap task, or simply using SSH to do it for us, the
choice is yours:</p>
<div>
<pre data-line=''><code class='language-ruby'># lib/capistrano/tasks/agent_forwarding.cap
desc &quot;Check if agent forwarding is working&quot;
task :forwarding do
on roles(:all) do |h|
if test(&quot;env | grep SSH_AUTH_SOCK&quot;)
info &quot;Agent forwarding is up to #{h}&quot;
else
error &quot;Agent forwarding is NOT up to #{h}&quot;
end
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># lib/capistrano/tasks/agent_forwarding.cap</span>
<span class="n">desc</span> <span class="s2">&quot;Check if agent forwarding is working&quot;</span>
<span class="n">task</span> <span class="ss">:forwarding</span> <span class="k">do</span>
<span class="n">on</span> <span class="n">roles</span><span class="p">(</span><span class="ss">:all</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">h</span><span class="o">|</span>
<span class="k">if</span> <span class="nb">test</span><span class="p">(</span><span class="s2">&quot;env | grep SSH_AUTH_SOCK&quot;</span><span class="p">)</span>
<span class="n">info</span> <span class="s2">&quot;Agent forwarding is up to </span><span class="si">#{</span><span class="n">h</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">else</span>
<span class="n">error</span> <span class="s2">&quot;Agent forwarding is NOT up to </span><span class="si">#{</span><span class="n">h</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>That gave the output:</p>
<div>
<pre data-line=''><code class='language-bash'>cap staging forwarding
DEBUG [f1269276] Running /usr/bin/env env | grep SSH_AUTH_SOCK on example.com
DEBUG [f1269276] Command: env | grep SSH_AUTH_SOCK
DEBUG [f1269276] SSH_AUTH_SOCK=/tmp/ssh-nQUEmyQ2nS/agent.2546
DEBUG [f1269276] Finished in 0.453 seconds command successful.
INFO Agent forwarding is up to example.com</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> cap staging forwarding
DEBUG <span class="o">[</span>f1269276<span class="o">]</span> Running /usr/bin/env env <span class="p">|</span> grep SSH_AUTH_SOCK on example.com
DEBUG <span class="o">[</span>f1269276<span class="o">]</span> Command: env <span class="p">|</span> grep SSH_AUTH_SOCK
DEBUG <span class="o">[</span>f1269276<span class="o">]</span> <span class="nv">SSH_AUTH_SOCK</span><span class="o">=</span>/tmp/ssh-nQUEmyQ2nS/agent.2546
DEBUG <span class="o">[</span>f1269276<span class="o">]</span> Finished in 0.453 seconds <span class="nb">command </span>successful.
INFO Agent forwarding is up to example.com
</code></pre></div>
<p>If you don&#39;t feel like writing a Capistrano task, one could simply do:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh -A example.com &#39;env | grep SSH_AUTH_SOCK&#39;
SSH_AUTH_SOCK=/tmp/ssh-Tb6X8V53tm/agent.2934</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh -A example.com <span class="s1">&#39;env | grep SSH_AUTH_SOCK&#39;</span>
<span class="nv">SSH_AUTH_SOCK</span><span class="o">=</span>/tmp/ssh-Tb6X8V53tm/agent.2934
</code></pre></div>
<p>If we see the <code>SSH_AUTH_SOCK</code> output, that&#39;s a pretty good indication that SSH
agent forwarding is enabled, and if on your local machine <code>ssh-add -l</code> shows
you an SSH key, then we&#39;re good to go. <strong>Make sure that you&#39;re using the
<code>git@...</code> repository URL</strong></p>
<div>
<pre data-line=''><code class='language-bash'>cap staging git:check
DEBUG Uploading /tmp/git-ssh.sh 0%
INFO Uploading /tmp/git-ssh.sh 100%
INFO [21382716] Running /usr/bin/env chmod +x /tmp/git-ssh.sh on example.com
DEBUG [21382716] Command: /usr/bin/env chmod +x /tmp/git-ssh.sh
INFO [21382716] Finished in 0.047 seconds command successful.
INFO [f40edfbb] Running /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git on example.com
DEBUG [f40edfbb] Command: ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/git-ssh.sh /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git )
DEBUG [f40edfbb] 3419812c9f146d9a84b44bcc2c3caef94da54758 HEAD
DEBUG [f40edfbb] 3419812c9f146d9a84b44bcc2c3caef94da54758 refs/heads/master
INFO [f40edfbb] Finished in 3.319 seconds command successful.</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> cap staging git:check
DEBUG Uploading /tmp/git-ssh.sh 0%
INFO Uploading /tmp/git-ssh.sh 100%
INFO <span class="o">[</span>21382716<span class="o">]</span> Running /usr/bin/env chmod +x /tmp/git-ssh.sh on example.com
DEBUG <span class="o">[</span>21382716<span class="o">]</span> Command: /usr/bin/env chmod +x /tmp/git-ssh.sh
INFO <span class="o">[</span>21382716<span class="o">]</span> Finished in 0.047 seconds <span class="nb">command </span>successful.
INFO <span class="o">[</span>f40edfbb<span class="o">]</span> Running /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git on example.com
DEBUG <span class="o">[</span>f40edfbb<span class="o">]</span> Command: <span class="o">(</span> <span class="nv">GIT_ASKPASS</span><span class="o">=</span>/bin/echo <span class="nv">GIT_SSH</span><span class="o">=</span>/tmp/git-ssh.sh /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git <span class="o">)</span>
DEBUG <span class="o">[</span>f40edfbb<span class="o">]</span> 3419812c9f146d9a84b44bcc2c3caef94da54758 HEAD
DEBUG <span class="o">[</span>f40edfbb<span class="o">]</span> 3419812c9f146d9a84b44bcc2c3caef94da54758 refs/heads/master
INFO <span class="o">[</span>f40edfbb<span class="o">]</span> Finished in 3.319 seconds <span class="nb">command </span>successful.
</code></pre></div>
<p><img src="/images/successful-git-check-example-screenshot.png" alt="Capistrano Git Check Colour Example"></p>
@ -355,19 +346,18 @@ technologies.</p>
<h3 id="toc_0">1. Checking the directory structure on the remote machine:</h3>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh deploy@remote &#39;ls -lR /var/www/my-application&#39;
my-application:
total 8
drwxrwsr-x 2 deploy deploy 4096 Jun 24 20:55 releases
drwxrwsr-x 2 deploy deploy 4096 Jun 24 20:55 shared
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh deploy@remote <span class="s1">&#39;ls -lR /var/www/my-application&#39;</span>
my-application:
total 8
drwxrwsr-x 2 deploy deploy 4096 Jun 24 20:55 releases
drwxrwsr-x 2 deploy deploy 4096 Jun 24 20:55 shared
my-application/releases:
total 0
my-application/releases:
total 0
my-application/shared:
total 0</code></pre>
</div>
my-application/shared:
total 0
</code></pre></div>
<p>This checks in one simple command that the ssh keys you setup are working (you
might yet be prompted for the password), and the permissions on the directory
@ -379,18 +369,17 @@ can be seen.</p>
quickly introduce ourselves to a quick Cap task to check these things on all
the machines for us:</p>
<div>
<pre data-line=''><code class='language-ruby'>desc &quot;Check that we can access everything&quot;
task :check_write_permissions do
on roles(:all) do |host|
if test(&quot;[ -w #{fetch(:deploy_to)} ]&quot;)
info &quot;#{fetch(:deploy_to)} is writable on #{host}&quot;
else
error &quot;#{fetch(:deploy_to)} is not writable on #{host}&quot;
end
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">desc</span> <span class="s2">&quot;Check that we can access everything&quot;</span>
<span class="n">task</span> <span class="ss">:check_write_permissions</span> <span class="k">do</span>
<span class="n">on</span> <span class="n">roles</span><span class="p">(</span><span class="ss">:all</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">host</span><span class="o">|</span>
<span class="k">if</span> <span class="nb">test</span><span class="p">(</span><span class="s2">&quot;[ -w </span><span class="si">#{</span><span class="n">fetch</span><span class="p">(</span><span class="ss">:deploy_to</span><span class="p">)</span><span class="si">}</span><span class="s2"> ]&quot;</span><span class="p">)</span>
<span class="n">info</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">fetch</span><span class="p">(</span><span class="ss">:deploy_to</span><span class="p">)</span><span class="si">}</span><span class="s2"> is writable on </span><span class="si">#{</span><span class="n">host</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">else</span>
<span class="n">error</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">fetch</span><span class="p">(</span><span class="ss">:deploy_to</span><span class="p">)</span><span class="si">}</span><span class="s2"> is not writable on </span><span class="si">#{</span><span class="n">host</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>Running this should give you a pretty decent overview, one line of output for
each server. It&#39;s also your first introduction to the API of Capistrano for
@ -405,22 +394,20 @@ later, but add those lines to a file in <code>./lib/capistrano/tasks</code>, cal
something like <code>access_check.cap</code>, and run <code>cap -T</code> from the top directory and
we&#39;ll be able to see the task listed:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ bundle exec cap -T
# ... lots of other tasks ...
cap check_write_permissions # Check that we can access everything
# ... lots of other tasks ...</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>bundle <span class="nb">exec </span>cap -T
<span class="c"># ... lots of other tasks ...</span>
cap check_write_permissions <span class="c"># Check that we can access everything</span>
<span class="c"># ... lots of other tasks ...</span>
</code></pre></div>
<p>Then we simply call it:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ bundle exec cap staging check_write_permissions
DEBUG [82c92144] Running /usr/bin/env [ -w /var/www/my-application ] on myserver.com
DEBUG [82c92144] Command: [ -w /var/www/my-application ]
DEBUG [82c92144] Finished in 0.456 seconds command successful.
INFO /var/www/my-application is writable on myserver.com</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>bundle <span class="nb">exec </span>cap staging check_write_permissions
DEBUG <span class="o">[</span>82c92144<span class="o">]</span> Running /usr/bin/env <span class="o">[</span> -w /var/www/my-application <span class="o">]</span> on myserver.com
DEBUG <span class="o">[</span>82c92144<span class="o">]</span> Command: <span class="o">[</span> -w /var/www/my-application <span class="o">]</span>
DEBUG <span class="o">[</span>82c92144<span class="o">]</span> Finished in 0.456 seconds <span class="nb">command </span>successful.
INFO /var/www/my-application is writable on myserver.com
</code></pre></div>
<p>If we&#39;ve done something wrong, that won&#39;t happen and we&#39;ll know that we need
to jump on the mailing list to get help, into IRC or ask a friend.</p>
@ -433,9 +420,8 @@ wrap Git in a shell script that makes it behave.</p>
<p>Capistrano does just this, so to check if the Git access is working, we can
simply call:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ cap staging git:check</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>cap staging git:check
</code></pre></div>
<p>This task is defined
<a href="https://github.com/capistrano/capistrano/blob/master/lib/capistrano/tasks/git.rake">here</a>
@ -448,26 +434,25 @@ one of the pieces we inherit from Rake)</p>
<p>If this fails we&#39;ll see:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ cap staging git:check
cap staging git:check
DEBUG Uploading /tmp/git-ssh.sh 0%
INFO Uploading /tmp/git-ssh.sh 100%
INFO [118bd3e4] Running /usr/bin/env chmod +x /tmp/git-ssh.sh on example.com
DEBUG [118bd3e4] Command: /usr/bin/env chmod +x /tmp/git-ssh.sh
INFO [118bd3e4] Finished in 0.049 seconds command successful.
INFO [a996463f] Running /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git on harrow
DEBUG [a996463f] Command: ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/git-ssh.sh /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git )
DEBUG [a996463f] Warning: Permanently added &#39;github.com,204.232.175.90&#39; (RSA) to the list of known hosts.
DEBUG [a996463f] Permission denied (publickey).
DEBUG [a996463f] fatal: The remote end hung up unexpectedly
cap aborted!
git stdout: Nothing written
git stderr: Nothing written
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>cap staging git:check
cap staging git:check
DEBUG Uploading /tmp/git-ssh.sh 0%
INFO Uploading /tmp/git-ssh.sh 100%
INFO <span class="o">[</span>118bd3e4<span class="o">]</span> Running /usr/bin/env chmod +x /tmp/git-ssh.sh on example.com
DEBUG <span class="o">[</span>118bd3e4<span class="o">]</span> Command: /usr/bin/env chmod +x /tmp/git-ssh.sh
INFO <span class="o">[</span>118bd3e4<span class="o">]</span> Finished in 0.049 seconds <span class="nb">command </span>successful.
INFO <span class="o">[</span>a996463f<span class="o">]</span> Running /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git on harrow
DEBUG <span class="o">[</span>a996463f<span class="o">]</span> Command: <span class="o">(</span> <span class="nv">GIT_ASKPASS</span><span class="o">=</span>/bin/echo <span class="nv">GIT_SSH</span><span class="o">=</span>/tmp/git-ssh.sh /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git <span class="o">)</span>
DEBUG <span class="o">[</span>a996463f<span class="o">]</span> Warning: Permanently added <span class="s1">&#39;github.com,204.232.175.90&#39;</span> <span class="o">(</span>RSA<span class="o">)</span> to the list of known hosts.
DEBUG <span class="o">[</span>a996463f<span class="o">]</span> Permission denied <span class="o">(</span>publickey<span class="o">)</span>.
DEBUG <span class="o">[</span>a996463f<span class="o">]</span> fatal: The remote end hung up unexpectedly
cap aborted!
git stdout: Nothing written
git stderr: Nothing written
Tasks: TOP =&gt; git:check
(See full trace by running task with --trace)</code></pre>
</div>
Tasks: <span class="nv">TOP</span> <span class="o">=</span>&gt; git:check
<span class="o">(</span>See full trace by running task with --trace<span class="o">)</span>
</code></pre></div>
<p>This&#39;ll typically come out looking more beautiful depending on your terminal
colour support, you may well see something like this:</p>
@ -496,56 +481,52 @@ printed out the error messages for us to try and figure out what broke.</li>
working by writing a tiny Cap task, or simply using SSH to do it for us, the
choice is yours:</p>
<div>
<pre data-line=''><code class='language-ruby'># lib/capistrano/tasks/agent_forwarding.cap
desc &quot;Check if agent forwarding is working&quot;
task :forwarding do
on roles(:all) do |h|
if test(&quot;env | grep SSH_AUTH_SOCK&quot;)
info &quot;Agent forwarding is up to #{h}&quot;
else
error &quot;Agent forwarding is NOT up to #{h}&quot;
end
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="c1"># lib/capistrano/tasks/agent_forwarding.cap</span>
<span class="n">desc</span> <span class="s2">&quot;Check if agent forwarding is working&quot;</span>
<span class="n">task</span> <span class="ss">:forwarding</span> <span class="k">do</span>
<span class="n">on</span> <span class="n">roles</span><span class="p">(</span><span class="ss">:all</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">h</span><span class="o">|</span>
<span class="k">if</span> <span class="nb">test</span><span class="p">(</span><span class="s2">&quot;env | grep SSH_AUTH_SOCK&quot;</span><span class="p">)</span>
<span class="n">info</span> <span class="s2">&quot;Agent forwarding is up to </span><span class="si">#{</span><span class="n">h</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">else</span>
<span class="n">error</span> <span class="s2">&quot;Agent forwarding is NOT up to </span><span class="si">#{</span><span class="n">h</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>That gave the output:</p>
<div>
<pre data-line=''><code class='language-bash'>cap staging forwarding
DEBUG [f1269276] Running /usr/bin/env env | grep SSH_AUTH_SOCK on example.com
DEBUG [f1269276] Command: env | grep SSH_AUTH_SOCK
DEBUG [f1269276] SSH_AUTH_SOCK=/tmp/ssh-nQUEmyQ2nS/agent.2546
DEBUG [f1269276] Finished in 0.453 seconds command successful.
INFO Agent forwarding is up to example.com</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> cap staging forwarding
DEBUG <span class="o">[</span>f1269276<span class="o">]</span> Running /usr/bin/env env <span class="p">|</span> grep SSH_AUTH_SOCK on example.com
DEBUG <span class="o">[</span>f1269276<span class="o">]</span> Command: env <span class="p">|</span> grep SSH_AUTH_SOCK
DEBUG <span class="o">[</span>f1269276<span class="o">]</span> <span class="nv">SSH_AUTH_SOCK</span><span class="o">=</span>/tmp/ssh-nQUEmyQ2nS/agent.2546
DEBUG <span class="o">[</span>f1269276<span class="o">]</span> Finished in 0.453 seconds <span class="nb">command </span>successful.
INFO Agent forwarding is up to example.com
</code></pre></div>
<p>If you don&#39;t feel like writing a Capistrano task, one could simply do:</p>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ ssh -A example.com &#39;env | grep SSH_AUTH_SOCK&#39;
SSH_AUTH_SOCK=/tmp/ssh-Tb6X8V53tm/agent.2934</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>ssh -A example.com <span class="s1">&#39;env | grep SSH_AUTH_SOCK&#39;</span>
<span class="nv">SSH_AUTH_SOCK</span><span class="o">=</span>/tmp/ssh-Tb6X8V53tm/agent.2934
</code></pre></div>
<p>If we see the <code>SSH_AUTH_SOCK</code> output, that&#39;s a pretty good indication that SSH
agent forwarding is enabled, and if on your local machine <code>ssh-add -l</code> shows
you an SSH key, then we&#39;re good to go. <strong>Make sure that you&#39;re using the
<code>git@...</code> repository URL</strong></p>
<div>
<pre data-line=''><code class='language-bash'>cap staging git:check
DEBUG Uploading /tmp/git-ssh.sh 0%
INFO Uploading /tmp/git-ssh.sh 100%
INFO [21382716] Running /usr/bin/env chmod +x /tmp/git-ssh.sh on example.com
DEBUG [21382716] Command: /usr/bin/env chmod +x /tmp/git-ssh.sh
INFO [21382716] Finished in 0.047 seconds command successful.
INFO [f40edfbb] Running /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git on example.com
DEBUG [f40edfbb] Command: ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/git-ssh.sh /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git )
DEBUG [f40edfbb] 3419812c9f146d9a84b44bcc2c3caef94da54758 HEAD
DEBUG [f40edfbb] 3419812c9f146d9a84b44bcc2c3caef94da54758 refs/heads/master
INFO [f40edfbb] Finished in 3.319 seconds command successful.</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> cap staging git:check
DEBUG Uploading /tmp/git-ssh.sh 0%
INFO Uploading /tmp/git-ssh.sh 100%
INFO <span class="o">[</span>21382716<span class="o">]</span> Running /usr/bin/env chmod +x /tmp/git-ssh.sh on example.com
DEBUG <span class="o">[</span>21382716<span class="o">]</span> Command: /usr/bin/env chmod +x /tmp/git-ssh.sh
INFO <span class="o">[</span>21382716<span class="o">]</span> Finished in 0.047 seconds <span class="nb">command </span>successful.
INFO <span class="o">[</span>f40edfbb<span class="o">]</span> Running /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git on example.com
DEBUG <span class="o">[</span>f40edfbb<span class="o">]</span> Command: <span class="o">(</span> <span class="nv">GIT_ASKPASS</span><span class="o">=</span>/bin/echo <span class="nv">GIT_SSH</span><span class="o">=</span>/tmp/git-ssh.sh /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git <span class="o">)</span>
DEBUG <span class="o">[</span>f40edfbb<span class="o">]</span> 3419812c9f146d9a84b44bcc2c3caef94da54758 HEAD
DEBUG <span class="o">[</span>f40edfbb<span class="o">]</span> 3419812c9f146d9a84b44bcc2c3caef94da54758 refs/heads/master
INFO <span class="o">[</span>f40edfbb<span class="o">]</span> Finished in 3.319 seconds <span class="nb">command </span>successful.
</code></pre></div>
<p><img src="/images/successful-git-check-example-screenshot.png" alt="Capistrano Git Check Colour Example"></p>
-->

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>
@ -125,16 +126,15 @@
<p>When you run <code>cap production deploy</code>, it invokes the following tasks in
sequence:</p>
<div>
<pre data-line=''><code class='language-ruby'>deploy:starting - start a deployment, make sure everything is ready
deploy:started - started hook (for custom tasks)
deploy:updating - update server(s) with a new release
deploy:updated - updated hook
deploy:publishing - publish the new release
deploy:published - published hook
deploy:finishing - finish the deployment, clean up everything
deploy:finished - finished hook</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"><span class="ss">deploy</span><span class="p">:</span><span class="n">starting</span> <span class="o">-</span> <span class="n">start</span> <span class="n">a</span> <span class="n">deployment</span><span class="p">,</span> <span class="n">make</span> <span class="n">sure</span> <span class="n">everything</span> <span class="n">is</span> <span class="n">ready</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">started</span> <span class="o">-</span> <span class="n">started</span> <span class="n">hook</span> <span class="p">(</span><span class="k">for</span> <span class="n">custom</span> <span class="n">tasks</span><span class="p">)</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">updating</span> <span class="o">-</span> <span class="n">update</span> <span class="n">server</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="n">with</span> <span class="n">a</span> <span class="kp">new</span> <span class="n">release</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">updated</span> <span class="o">-</span> <span class="n">updated</span> <span class="n">hook</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">publishing</span> <span class="o">-</span> <span class="n">publish</span> <span class="n">the</span> <span class="kp">new</span> <span class="n">release</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">published</span> <span class="o">-</span> <span class="n">published</span> <span class="n">hook</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">finishing</span> <span class="o">-</span> <span class="n">finish</span> <span class="n">the</span> <span class="n">deployment</span><span class="p">,</span> <span class="n">clean</span> <span class="n">up</span> <span class="n">everything</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">finished</span> <span class="o">-</span> <span class="n">finished</span> <span class="n">hook</span>
</code></pre></div>
<p>Notice there are several hook tasks e.g. <code>:started</code>, <code>:updated</code> for
you to hook up custom tasks into the flow using <code>after()</code> and <code>before()</code>.</p>
@ -144,16 +144,15 @@ you to hook up custom tasks into the flow using <code>after()</code> and <code>b
<p>When you run <code>cap production deploy:rollback</code>, it invokes the following
tasks in sequence:</p>
<div>
<pre data-line=''><code class='language-ruby'>deploy:starting
deploy:started
deploy:reverting - revert server(s) to previous release
deploy:reverted - reverted hook
deploy:publishing
deploy:published
deploy:finishing_rollback - finish the rollback, clean up everything
deploy:finished</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"><span class="ss">deploy</span><span class="p">:</span><span class="n">starting</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">started</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">reverting</span> <span class="o">-</span> <span class="n">revert</span> <span class="n">server</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="n">to</span> <span class="n">previous</span> <span class="n">release</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">reverted</span> <span class="o">-</span> <span class="n">reverted</span> <span class="n">hook</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">publishing</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">published</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">finishing_rollback</span> <span class="o">-</span> <span class="n">finish</span> <span class="n">the</span> <span class="n">rollback</span><span class="p">,</span> <span class="n">clean</span> <span class="n">up</span> <span class="n">everything</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">finished</span>
</code></pre></div>
<p>As you can see, rollback flow shares many tasks with deploy flow. But note that, rollback flow runs its own <code>:finishing_rollback</code> task because its
cleanup process is usually different from deploy flow.</p>
@ -162,70 +161,67 @@ cleanup process is usually different from deploy flow.</p>
<p>Assume you require the following files in <code>Capfile</code>,</p>
<div>
<pre data-line=''><code class='language-ruby'># Capfile
require &#39;capistrano/setup&#39;
require &#39;capistrano/deploy&#39;
require &#39;capistrano/bundler&#39;
require &#39;capistrano/rails/migrations&#39;
require &#39;capistrano/rails/assets&#39;</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"><span class="c1"># Capfile</span>
<span class="nb">require</span> <span class="s1">&#39;capistrano/setup&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;capistrano/deploy&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;capistrano/bundler&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;capistrano/rails/migrations&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;capistrano/rails/assets&#39;</span>
</code></pre></div>
<p>When you run <code>cap production deploy</code>, it runs these tasks:</p>
<div>
<pre data-line=''><code class='language-ruby'>deploy
deploy:starting
[before]
deploy:ensure_stage
deploy:set_shared_assets
deploy:check
deploy:started
deploy:updating
git:create_release
deploy:symlink:shared
deploy:updated
[before]
deploy:bundle
[after]
deploy:migrate
deploy:compile_assets
deploy:cleanup_assets
deploy:normalise_assets
deploy:publishing
deploy:symlink:release
deploy:restart
deploy:published
deploy:finishing
deploy:cleanup
deploy:finished
deploy:log_revision</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"><span class="n">deploy</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">starting</span>
<span class="o">[</span><span class="n">before</span><span class="o">]</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">ensure_stage</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">set_shared_assets</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">check</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">started</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">updating</span>
<span class="ss">git</span><span class="p">:</span><span class="n">create_release</span>
<span class="ss">deploy</span><span class="p">:</span><span class="ss">symlink</span><span class="p">:</span><span class="n">shared</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">updated</span>
<span class="o">[</span><span class="n">before</span><span class="o">]</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">bundle</span>
<span class="o">[</span><span class="n">after</span><span class="o">]</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">migrate</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">compile_assets</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">cleanup_assets</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">normalise_assets</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">publishing</span>
<span class="ss">deploy</span><span class="p">:</span><span class="ss">symlink</span><span class="p">:</span><span class="n">release</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">restart</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">published</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">finishing</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">cleanup</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">finished</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">log_revision</span>
</code></pre></div>
<p>For <code>cap production deploy:rollback</code>, it runs these tasks:</p>
<div>
<pre data-line=''><code class='language-ruby'>deploy
deploy:starting
[before]
deploy:ensure_stage
deploy:set_shared_assets
deploy:check
deploy:started
deploy:reverting
deploy:revert_release
deploy:reverted
[after]
deploy:rollback_assets
deploy:publishing
deploy:symlink:release
deploy:restart
deploy:published
deploy:finishing_rollback
deploy:cleanup_rollback
deploy:finished
deploy:log_revision</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"><span class="n">deploy</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">starting</span>
<span class="o">[</span><span class="n">before</span><span class="o">]</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">ensure_stage</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">set_shared_assets</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">check</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">started</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">reverting</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">revert_release</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">reverted</span>
<span class="o">[</span><span class="n">after</span><span class="o">]</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">rollback_assets</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">publishing</span>
<span class="ss">deploy</span><span class="p">:</span><span class="ss">symlink</span><span class="p">:</span><span class="n">release</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">restart</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">published</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">finishing_rollback</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">cleanup_rollback</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">finished</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">log_revision</span>
</code></pre></div>
</div>
</div>
@ -243,16 +239,15 @@ require &#39;capistrano/rails/assets&#39;</code></pre>
<p>When you run <code>cap production deploy</code>, it invokes the following tasks in
sequence:</p>
<div>
<pre data-line=''><code class='language-ruby'>deploy:starting - start a deployment, make sure everything is ready
deploy:started - started hook (for custom tasks)
deploy:updating - update server(s) with a new release
deploy:updated - updated hook
deploy:publishing - publish the new release
deploy:published - published hook
deploy:finishing - finish the deployment, clean up everything
deploy:finished - finished hook</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"><span class="ss">deploy</span><span class="p">:</span><span class="n">starting</span> <span class="o">-</span> <span class="n">start</span> <span class="n">a</span> <span class="n">deployment</span><span class="p">,</span> <span class="n">make</span> <span class="n">sure</span> <span class="n">everything</span> <span class="n">is</span> <span class="n">ready</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">started</span> <span class="o">-</span> <span class="n">started</span> <span class="n">hook</span> <span class="p">(</span><span class="k">for</span> <span class="n">custom</span> <span class="n">tasks</span><span class="p">)</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">updating</span> <span class="o">-</span> <span class="n">update</span> <span class="n">server</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="n">with</span> <span class="n">a</span> <span class="kp">new</span> <span class="n">release</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">updated</span> <span class="o">-</span> <span class="n">updated</span> <span class="n">hook</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">publishing</span> <span class="o">-</span> <span class="n">publish</span> <span class="n">the</span> <span class="kp">new</span> <span class="n">release</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">published</span> <span class="o">-</span> <span class="n">published</span> <span class="n">hook</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">finishing</span> <span class="o">-</span> <span class="n">finish</span> <span class="n">the</span> <span class="n">deployment</span><span class="p">,</span> <span class="n">clean</span> <span class="n">up</span> <span class="n">everything</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">finished</span> <span class="o">-</span> <span class="n">finished</span> <span class="n">hook</span>
</code></pre></div>
<p>Notice there are several hook tasks e.g. <code>:started</code>, <code>:updated</code> for
you to hook up custom tasks into the flow using <code>after()</code> and <code>before()</code>.</p>
@ -262,16 +257,15 @@ you to hook up custom tasks into the flow using <code>after()</code> and <code>b
<p>When you run <code>cap production deploy:rollback</code>, it invokes the following
tasks in sequence:</p>
<div>
<pre data-line=''><code class='language-ruby'>deploy:starting
deploy:started
deploy:reverting - revert server(s) to previous release
deploy:reverted - reverted hook
deploy:publishing
deploy:published
deploy:finishing_rollback - finish the rollback, clean up everything
deploy:finished</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"><span class="ss">deploy</span><span class="p">:</span><span class="n">starting</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">started</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">reverting</span> <span class="o">-</span> <span class="n">revert</span> <span class="n">server</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="n">to</span> <span class="n">previous</span> <span class="n">release</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">reverted</span> <span class="o">-</span> <span class="n">reverted</span> <span class="n">hook</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">publishing</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">published</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">finishing_rollback</span> <span class="o">-</span> <span class="n">finish</span> <span class="n">the</span> <span class="n">rollback</span><span class="p">,</span> <span class="n">clean</span> <span class="n">up</span> <span class="n">everything</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">finished</span>
</code></pre></div>
<p>As you can see, rollback flow shares many tasks with deploy flow. But note that, rollback flow runs its own <code>:finishing_rollback</code> task because its
cleanup process is usually different from deploy flow.</p>
@ -280,70 +274,67 @@ cleanup process is usually different from deploy flow.</p>
<p>Assume you require the following files in <code>Capfile</code>,</p>
<div>
<pre data-line=''><code class='language-ruby'># Capfile
require &#39;capistrano/setup&#39;
require &#39;capistrano/deploy&#39;
require &#39;capistrano/bundler&#39;
require &#39;capistrano/rails/migrations&#39;
require &#39;capistrano/rails/assets&#39;</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"><span class="c1"># Capfile</span>
<span class="nb">require</span> <span class="s1">&#39;capistrano/setup&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;capistrano/deploy&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;capistrano/bundler&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;capistrano/rails/migrations&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;capistrano/rails/assets&#39;</span>
</code></pre></div>
<p>When you run <code>cap production deploy</code>, it runs these tasks:</p>
<div>
<pre data-line=''><code class='language-ruby'>deploy
deploy:starting
[before]
deploy:ensure_stage
deploy:set_shared_assets
deploy:check
deploy:started
deploy:updating
git:create_release
deploy:symlink:shared
deploy:updated
[before]
deploy:bundle
[after]
deploy:migrate
deploy:compile_assets
deploy:cleanup_assets
deploy:normalise_assets
deploy:publishing
deploy:symlink:release
deploy:restart
deploy:published
deploy:finishing
deploy:cleanup
deploy:finished
deploy:log_revision</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"><span class="n">deploy</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">starting</span>
<span class="o">[</span><span class="n">before</span><span class="o">]</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">ensure_stage</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">set_shared_assets</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">check</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">started</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">updating</span>
<span class="ss">git</span><span class="p">:</span><span class="n">create_release</span>
<span class="ss">deploy</span><span class="p">:</span><span class="ss">symlink</span><span class="p">:</span><span class="n">shared</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">updated</span>
<span class="o">[</span><span class="n">before</span><span class="o">]</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">bundle</span>
<span class="o">[</span><span class="n">after</span><span class="o">]</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">migrate</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">compile_assets</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">cleanup_assets</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">normalise_assets</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">publishing</span>
<span class="ss">deploy</span><span class="p">:</span><span class="ss">symlink</span><span class="p">:</span><span class="n">release</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">restart</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">published</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">finishing</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">cleanup</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">finished</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">log_revision</span>
</code></pre></div>
<p>For <code>cap production deploy:rollback</code>, it runs these tasks:</p>
<div>
<pre data-line=''><code class='language-ruby'>deploy
deploy:starting
[before]
deploy:ensure_stage
deploy:set_shared_assets
deploy:check
deploy:started
deploy:reverting
deploy:revert_release
deploy:reverted
[after]
deploy:rollback_assets
deploy:publishing
deploy:symlink:release
deploy:restart
deploy:published
deploy:finishing_rollback
deploy:cleanup_rollback
deploy:finished
deploy:log_revision</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"><span class="n">deploy</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">starting</span>
<span class="o">[</span><span class="n">before</span><span class="o">]</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">ensure_stage</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">set_shared_assets</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">check</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">started</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">reverting</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">revert_release</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">reverted</span>
<span class="o">[</span><span class="n">after</span><span class="o">]</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">rollback_assets</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">publishing</span>
<span class="ss">deploy</span><span class="p">:</span><span class="ss">symlink</span><span class="p">:</span><span class="n">release</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">restart</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">published</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">finishing_rollback</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">cleanup_rollback</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">finished</span>
<span class="ss">deploy</span><span class="p">:</span><span class="n">log_revision</span>
</code></pre></div>
-->
<!--</div> [> /container <] -->

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>
@ -132,47 +133,48 @@ therefore recommended to use an appropriate bundler.
<p>The following command will install the latest released capistrano <code>v3</code> revision:</p>
<div>
<pre data-line=''><code class='language-bash'>$ gem install capistrano</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> <span class="nv">$ </span>gem install capistrano
</code></pre></div>
<p>Or grab the bleeding edge head from:</p>
<div>
<pre data-line=''><code class='language-bash'>$ git clone https://github.com/capistrano/capistrano.git
$ cd capistrano
$ gem build *.gemspec
$ gem install *.gem</code></pre>
</div>
Or grab the bleeding edge head from:
<h3 id="toc_1">Usage in a Rails project</h3>
<p>Add the following lines to the Gemfile:</p>
<div class="highlight"><pre><code class="bash"> <span class="nv">$ </span>git clone https://github.com/capistrano/capistrano.git
<span class="nv">$ </span><span class="nb">cd </span>capistrano
<span class="nv">$ </span>gem build *.gemspec
<span class="nv">$ </span>gem install *.gem
</code></pre></div>
<div>
<pre data-line=''><code class='language-ruby'>group :development do
gem &#39;capistrano-rails&#39;, &#39;~&gt; 1.0.0&#39;
end</code></pre>
</div>
<p>The <code>capistrano-rails</code> gem includes extras specifically designed for Ruby on
Rails, specifically:</p>
### Usage in a Rails project
<ul>
<li>Asset Pipeline Support</li>
<li>Database Migration Support</li>
</ul>
Add the following lines to the Gemfile:
<p>The documentation for these components can be found in
<a href="https://github.com/capistrano/rails/blob/master/README.md">their</a>,
<a href="https://github.com/capistrano/bundler/blob/master/README.md">respective</a>,
<a href="https://github.com/capistrano/rails/blob/master/README.md">READMEs</a>. However for the most
part, to get the best, and most sensible results, simply <code>require</code> in
Capfile, after the <code>require &#39;capistrano/deploy&#39;</code> line:</p>
<div>
<pre data-line=''><code class='language-ruby'>require &#39;capistrano/rails&#39;</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">group</span> <span class="ss">:development</span> <span class="k">do</span>
<span class="n">gem</span> <span class="s1">&#39;capistrano-rails&#39;</span><span class="p">,</span> <span class="s1">&#39;~&gt; 1.0.0&#39;</span>
<span class="k">end</span>
</code></pre></div>
The `capistrano-rails` gem includes extras specifically designed for Ruby on
Rails, specifically:
* Asset Pipeline Support
* Database Migration Support
The documentation for these components can be found in
[their][capistrano-rails-asset-pipeline-readme],
[respective][capistrano-rails-gem-bundler-readme],
[READMEs][capistrano-rails-database-migrations-readme]. However for the most
part, to get the best, and most sensible results, simply `require` in
Capfile, after the `require 'capistrano/deploy'` line:
<div class="highlight"><pre><code class="ruby"> <span class="nb">require</span> <span class="s1">&#39;capistrano/rails&#39;</span>
</code></pre></div>
<div class="alert alert-info">
<h5>Help! I was using Capistrano `v2.x` and I didn't want to upgrade!</h5>
@ -181,17 +183,18 @@ If you are using Capistrano `v2.x.x` and have also installed Capistrano `v3`
by mistake, then you can lock your Gem version for Capistrano at something
like:
<div>
<pre data-line=''><code class='language-ruby'>gem &#39;capistrano&#39;, &#39;~&gt; 2.15&#39; # Or whatever patch release you are using</code></pre>
<div class="highlight"><pre><code class="ruby"> <span class="n">gem</span> <span class="s1">&#39;capistrano&#39;</span><span class="p">,</span> <span class="s1">&#39;~&gt; 2.15&#39;</span> <span class="c1"># Or whatever patch release you are using</span>
</code></pre></div>
This is the [pessimistic operator][rubygems-pessimistic-operator] which
installs the closest matching version, at the time of writing this would
install `2.15.4`, and any other point-release in the `2.15.x` family without
the risk of accidentally upgrading to `v3`.
</div>
<p>This is the <a href="http://docs.rubygems.org/read/chapter/16#page74">pessimistic operator</a> which
installs the closest matching version, at the time of writing this would
install <code>2.15.4</code>, and any other point-release in the <code>2.15.x</code> family without
the risk of accidentally upgrading to <code>v3</code>.
</div></p>
<h2 id="toc_2"></h2>
<h2 id="toc_1"></h2>
</div>
</div>
@ -216,47 +219,48 @@ therefore recommended to use an appropriate bundler.
<p>The following command will install the latest released capistrano <code>v3</code> revision:</p>
<div>
<pre data-line=''><code class='language-bash'>$ gem install capistrano</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> <span class="nv">$ </span>gem install capistrano
</code></pre></div>
<p>Or grab the bleeding edge head from:</p>
<div>
<pre data-line=''><code class='language-bash'>$ git clone https://github.com/capistrano/capistrano.git
$ cd capistrano
$ gem build *.gemspec
$ gem install *.gem</code></pre>
</div>
Or grab the bleeding edge head from:
<h3 id="toc_1">Usage in a Rails project</h3>
<p>Add the following lines to the Gemfile:</p>
<div class="highlight"><pre><code class="bash"> <span class="nv">$ </span>git clone https://github.com/capistrano/capistrano.git
<span class="nv">$ </span><span class="nb">cd </span>capistrano
<span class="nv">$ </span>gem build *.gemspec
<span class="nv">$ </span>gem install *.gem
</code></pre></div>
<div>
<pre data-line=''><code class='language-ruby'>group :development do
gem &#39;capistrano-rails&#39;, &#39;~&gt; 1.0.0&#39;
end</code></pre>
</div>
<p>The <code>capistrano-rails</code> gem includes extras specifically designed for Ruby on
Rails, specifically:</p>
### Usage in a Rails project
<ul>
<li>Asset Pipeline Support</li>
<li>Database Migration Support</li>
</ul>
Add the following lines to the Gemfile:
<p>The documentation for these components can be found in
<a href="https://github.com/capistrano/rails/blob/master/README.md">their</a>,
<a href="https://github.com/capistrano/bundler/blob/master/README.md">respective</a>,
<a href="https://github.com/capistrano/rails/blob/master/README.md">READMEs</a>. However for the most
part, to get the best, and most sensible results, simply <code>require</code> in
Capfile, after the <code>require &#39;capistrano/deploy&#39;</code> line:</p>
<div>
<pre data-line=''><code class='language-ruby'>require &#39;capistrano/rails&#39;</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">group</span> <span class="ss">:development</span> <span class="k">do</span>
<span class="n">gem</span> <span class="s1">&#39;capistrano-rails&#39;</span><span class="p">,</span> <span class="s1">&#39;~&gt; 1.0.0&#39;</span>
<span class="k">end</span>
</code></pre></div>
The `capistrano-rails` gem includes extras specifically designed for Ruby on
Rails, specifically:
* Asset Pipeline Support
* Database Migration Support
The documentation for these components can be found in
[their][capistrano-rails-asset-pipeline-readme],
[respective][capistrano-rails-gem-bundler-readme],
[READMEs][capistrano-rails-database-migrations-readme]. However for the most
part, to get the best, and most sensible results, simply `require` in
Capfile, after the `require 'capistrano/deploy'` line:
<div class="highlight"><pre><code class="ruby"> <span class="nb">require</span> <span class="s1">&#39;capistrano/rails&#39;</span>
</code></pre></div>
<div class="alert alert-info">
<h5>Help! I was using Capistrano `v2.x` and I didn't want to upgrade!</h5>
@ -265,17 +269,18 @@ If you are using Capistrano `v2.x.x` and have also installed Capistrano `v3`
by mistake, then you can lock your Gem version for Capistrano at something
like:
<div>
<pre data-line=''><code class='language-ruby'>gem &#39;capistrano&#39;, &#39;~&gt; 2.15&#39; # Or whatever patch release you are using</code></pre>
<div class="highlight"><pre><code class="ruby"> <span class="n">gem</span> <span class="s1">&#39;capistrano&#39;</span><span class="p">,</span> <span class="s1">&#39;~&gt; 2.15&#39;</span> <span class="c1"># Or whatever patch release you are using</span>
</code></pre></div>
This is the [pessimistic operator][rubygems-pessimistic-operator] which
installs the closest matching version, at the time of writing this would
install `2.15.4`, and any other point-release in the `2.15.x` family without
the risk of accidentally upgrading to `v3`.
</div>
<p>This is the <a href="http://docs.rubygems.org/read/chapter/16#page74">pessimistic operator</a> which
installs the closest matching version, at the time of writing this would
install <code>2.15.4</code>, and any other point-release in the <code>2.15.x</code> family without
the risk of accidentally upgrading to <code>v3</code>.
</div></p>
<h2 id="toc_2"></h2>
<h2 id="toc_1"></h2>
-->
<!--</div> [> /container <] -->

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>
@ -153,34 +154,31 @@ configuration into place at deploy time.</p>
<p>The original <code>database.yml</code> should be added to the <code>.gitignore</code> (or your SCM&#39;s
parallel concept of ignored files)</p>
<div>
<pre data-line=''><code class='language-bash'>$ cp config/database.yml{,.example}
$ echo config/database.yml &gt;&gt; .gitignore</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> <span class="nv">$ </span>cp config/database.yml<span class="o">{</span>,.example<span class="o">}</span>
<span class="nv">$ </span><span class="nb">echo </span>config/database.yml &gt;&gt; .gitignore
</code></pre></div>
<p>This should be done for any other secret files, we&#39;ll create the production
version of the file when we deploy, and symlink it into place.</p>
<h3 id="toc_2">3. Initialize Capistrano in your application.</h3>
<div>
<pre data-line=''><code class='language-bash'>$ cd my-project
$ cap install</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> <span class="nv">$ </span><span class="nb">cd </span>my-project
<span class="nv">$ </span>cap install
</code></pre></div>
<p>This will create a bunch of files, the important ones are:</p>
<div>
<pre data-line=''><code class='language-bash'>├── Capfile
├── config
│   ├── deploy
│   │   ├── production.rb
│   │   └── staging.rb
│   └── deploy.rb
└── lib
└── capistrano
└── tasks</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> ├── Capfile
├── config
│   ├── deploy
│   │   ├── production.rb
│   │   └── staging.rb
│   └── deploy.rb
└── lib
└── capistrano
└── tasks
</code></pre></div>
<p>Your new Capfile will automatically any tasks from any *.cap files in lib/capistrano/tasks.</p>
@ -205,28 +203,27 @@ common.</p>
<p>The example file generated will look something like this:</p>
<div>
<pre data-line=''><code class='language-ruby'>set :stage, :staging
<div class="highlight"><pre><code class="ruby"> <span class="n">set</span> <span class="ss">:stage</span><span class="p">,</span> <span class="ss">:staging</span>
# Simple Role Syntax
# ==================
# Supports bulk-adding hosts to roles, the primary
# server in each group is considered to be the first
# unless any hosts have the primary property set.
role :app, %w{example.com}
role :web, %w{example.com}
role :db, %w{example.com}
<span class="c1"># Simple Role Syntax</span>
<span class="c1"># ==================</span>
<span class="c1"># Supports bulk-adding hosts to roles, the primary</span>
<span class="c1"># server in each group is considered to be the first</span>
<span class="c1"># unless any hosts have the primary property set.</span>
<span class="n">role</span> <span class="ss">:app</span><span class="p">,</span> <span class="sx">%w{example.com}</span>
<span class="n">role</span> <span class="ss">:web</span><span class="p">,</span> <span class="sx">%w{example.com}</span>
<span class="n">role</span> <span class="ss">:db</span><span class="p">,</span> <span class="sx">%w{example.com}</span>
# Extended Server Syntax
# ======================
# This can be used to drop a more detailed server
# definition into the server list. The second argument
# is something that quacks like a hash and can be used
# to set extended properties on the server.
server &#39;example.com&#39;, roles: %w{web app}, my_property: :my_value
<span class="c1"># Extended Server Syntax</span>
<span class="c1"># ======================</span>
<span class="c1"># This can be used to drop a more detailed server</span>
<span class="c1"># definition into the server list. The second argument</span>
<span class="c1"># is something that quacks like a hash and can be used</span>
<span class="c1"># to set extended properties on the server.</span>
<span class="n">server</span> <span class="s1">&#39;example.com&#39;</span><span class="p">,</span> <span class="ss">roles</span><span class="p">:</span> <span class="sx">%w{web app}</span><span class="p">,</span> <span class="n">my_property</span><span class="p">:</span> <span class="ss">:my_value</span>
# set :rails_env, :staging</code></pre>
</div>
<span class="c1"># set :rails_env, :staging</span>
</code></pre></div>
<p>Both the simple role, and extended server syntaxes result in one or more
servers for each role being defined. The <code>app</code> and <code>db</code> roles are just
@ -245,12 +242,11 @@ servers, one where we set the username, and another where we set the port.
These host strings are parsed and expanded out in to the equivalent of the
server line after the comment:</p>
<div>
<pre data-line=''><code class='language-ruby'>role :web, %w{hello@world.com example.com:1234}
# ...is the same as doing...
server &#39;world.com&#39; roles: [:web], user: &#39;hello&#39;
server &#39;example.com&#39;, roles: [:web], port: 1234</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">role</span> <span class="ss">:web</span><span class="p">,</span> <span class="sx">%w{hello@world.com example.com:1234}</span>
<span class="c1"># ...is the same as doing...</span>
<span class="n">server</span> <span class="s1">&#39;world.com&#39;</span> <span class="ss">roles</span><span class="p">:</span> <span class="o">[</span><span class="ss">:web</span><span class="o">]</span><span class="p">,</span> <span class="ss">user</span><span class="p">:</span> <span class="s1">&#39;hello&#39;</span>
<span class="n">server</span> <span class="s1">&#39;example.com&#39;</span><span class="p">,</span> <span class="ss">roles</span><span class="p">:</span> <span class="o">[</span><span class="ss">:web</span><span class="o">]</span><span class="p">,</span> <span class="ss">port</span><span class="p">:</span> <span class="mi">1234</span>
</code></pre></div>
<h3 id="toc_4">5. Set the shared information in <code>deploy.rb</code>.</h3>
@ -262,11 +258,10 @@ deploy</em> are specified here.</p>
self-documenting, commented-out configuration options, feel free to play with
them a little:</p>
<div>
<pre data-line=''><code class='language-ruby'>set :application, &#39;my app name&#39;
set :repo_url, &#39;git@example.com:me/my_repo.git&#39;
ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">set</span> <span class="ss">:application</span><span class="p">,</span> <span class="s1">&#39;my app name&#39;</span>
<span class="n">set</span> <span class="ss">:repo_url</span><span class="p">,</span> <span class="s1">&#39;git@example.com:me/my_repo.git&#39;</span>
<span class="n">ask</span> <span class="ss">:branch</span><span class="p">,</span> <span class="nb">proc</span> <span class="p">{</span> <span class="sb">`git rev-parse --abbrev-ref HEAD`</span><span class="o">.</span><span class="n">chomp</span> <span class="p">}</span>
</code></pre></div>
<p>Here we&#39;d set the name of the application, ideally in a way that&#39;s safe for
filenames on your target operating system.</p>
@ -285,11 +280,10 @@ Cancan (for authorisation) along side Twitter Bootstrap for assets has been
forked to the Capistrano repository, but you can find the (unchanged) original
<a href="https://github.com/RailsApps/rails3-bootstrap-devise-cancan">here</a>.</p>
<div>
<pre data-line=''><code class='language-ruby'>set :application, &#39;rails3-bootstrap-devise-cancan-demo&#39;
set :repo_url, &#39;https://github.com/capistrano/rails3-bootstrap-devise-cancan&#39;
set :branch, &#39;master&#39;</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">set</span> <span class="ss">:application</span><span class="p">,</span> <span class="s1">&#39;rails3-bootstrap-devise-cancan-demo&#39;</span>
<span class="n">set</span> <span class="ss">:repo_url</span><span class="p">,</span> <span class="s1">&#39;https://github.com/capistrano/rails3-bootstrap-devise-cancan&#39;</span>
<span class="n">set</span> <span class="ss">:branch</span><span class="p">,</span> <span class="s1">&#39;master&#39;</span>
</code></pre></div>
<p>I&#39;ve simplified the <code>:branch</code> variable to simply be a <code>set</code> variable, not a
question prompt, as this repository only has a master branch.</p>
@ -347,34 +341,31 @@ configuration into place at deploy time.</p>
<p>The original <code>database.yml</code> should be added to the <code>.gitignore</code> (or your SCM&#39;s
parallel concept of ignored files)</p>
<div>
<pre data-line=''><code class='language-bash'>$ cp config/database.yml{,.example}
$ echo config/database.yml &gt;&gt; .gitignore</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> <span class="nv">$ </span>cp config/database.yml<span class="o">{</span>,.example<span class="o">}</span>
<span class="nv">$ </span><span class="nb">echo </span>config/database.yml &gt;&gt; .gitignore
</code></pre></div>
<p>This should be done for any other secret files, we&#39;ll create the production
version of the file when we deploy, and symlink it into place.</p>
<h3 id="toc_2">3. Initialize Capistrano in your application.</h3>
<div>
<pre data-line=''><code class='language-bash'>$ cd my-project
$ cap install</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> <span class="nv">$ </span><span class="nb">cd </span>my-project
<span class="nv">$ </span>cap install
</code></pre></div>
<p>This will create a bunch of files, the important ones are:</p>
<div>
<pre data-line=''><code class='language-bash'>├── Capfile
├── config
│   ├── deploy
│   │   ├── production.rb
│   │   └── staging.rb
│   └── deploy.rb
└── lib
└── capistrano
└── tasks</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> ├── Capfile
├── config
│   ├── deploy
│   │   ├── production.rb
│   │   └── staging.rb
│   └── deploy.rb
└── lib
└── capistrano
└── tasks
</code></pre></div>
<p>Your new Capfile will automatically any tasks from any *.cap files in lib/capistrano/tasks.</p>
@ -399,28 +390,27 @@ common.</p>
<p>The example file generated will look something like this:</p>
<div>
<pre data-line=''><code class='language-ruby'>set :stage, :staging
<div class="highlight"><pre><code class="ruby"> <span class="n">set</span> <span class="ss">:stage</span><span class="p">,</span> <span class="ss">:staging</span>
# Simple Role Syntax
# ==================
# Supports bulk-adding hosts to roles, the primary
# server in each group is considered to be the first
# unless any hosts have the primary property set.
role :app, %w{example.com}
role :web, %w{example.com}
role :db, %w{example.com}
<span class="c1"># Simple Role Syntax</span>
<span class="c1"># ==================</span>
<span class="c1"># Supports bulk-adding hosts to roles, the primary</span>
<span class="c1"># server in each group is considered to be the first</span>
<span class="c1"># unless any hosts have the primary property set.</span>
<span class="n">role</span> <span class="ss">:app</span><span class="p">,</span> <span class="sx">%w{example.com}</span>
<span class="n">role</span> <span class="ss">:web</span><span class="p">,</span> <span class="sx">%w{example.com}</span>
<span class="n">role</span> <span class="ss">:db</span><span class="p">,</span> <span class="sx">%w{example.com}</span>
# Extended Server Syntax
# ======================
# This can be used to drop a more detailed server
# definition into the server list. The second argument
# is something that quacks like a hash and can be used
# to set extended properties on the server.
server &#39;example.com&#39;, roles: %w{web app}, my_property: :my_value
<span class="c1"># Extended Server Syntax</span>
<span class="c1"># ======================</span>
<span class="c1"># This can be used to drop a more detailed server</span>
<span class="c1"># definition into the server list. The second argument</span>
<span class="c1"># is something that quacks like a hash and can be used</span>
<span class="c1"># to set extended properties on the server.</span>
<span class="n">server</span> <span class="s1">&#39;example.com&#39;</span><span class="p">,</span> <span class="ss">roles</span><span class="p">:</span> <span class="sx">%w{web app}</span><span class="p">,</span> <span class="n">my_property</span><span class="p">:</span> <span class="ss">:my_value</span>
# set :rails_env, :staging</code></pre>
</div>
<span class="c1"># set :rails_env, :staging</span>
</code></pre></div>
<p>Both the simple role, and extended server syntaxes result in one or more
servers for each role being defined. The <code>app</code> and <code>db</code> roles are just
@ -439,12 +429,11 @@ servers, one where we set the username, and another where we set the port.
These host strings are parsed and expanded out in to the equivalent of the
server line after the comment:</p>
<div>
<pre data-line=''><code class='language-ruby'>role :web, %w{hello@world.com example.com:1234}
# ...is the same as doing...
server &#39;world.com&#39; roles: [:web], user: &#39;hello&#39;
server &#39;example.com&#39;, roles: [:web], port: 1234</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">role</span> <span class="ss">:web</span><span class="p">,</span> <span class="sx">%w{hello@world.com example.com:1234}</span>
<span class="c1"># ...is the same as doing...</span>
<span class="n">server</span> <span class="s1">&#39;world.com&#39;</span> <span class="ss">roles</span><span class="p">:</span> <span class="o">[</span><span class="ss">:web</span><span class="o">]</span><span class="p">,</span> <span class="ss">user</span><span class="p">:</span> <span class="s1">&#39;hello&#39;</span>
<span class="n">server</span> <span class="s1">&#39;example.com&#39;</span><span class="p">,</span> <span class="ss">roles</span><span class="p">:</span> <span class="o">[</span><span class="ss">:web</span><span class="o">]</span><span class="p">,</span> <span class="ss">port</span><span class="p">:</span> <span class="mi">1234</span>
</code></pre></div>
<h3 id="toc_4">5. Set the shared information in <code>deploy.rb</code>.</h3>
@ -456,11 +445,10 @@ deploy</em> are specified here.</p>
self-documenting, commented-out configuration options, feel free to play with
them a little:</p>
<div>
<pre data-line=''><code class='language-ruby'>set :application, &#39;my app name&#39;
set :repo_url, &#39;git@example.com:me/my_repo.git&#39;
ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">set</span> <span class="ss">:application</span><span class="p">,</span> <span class="s1">&#39;my app name&#39;</span>
<span class="n">set</span> <span class="ss">:repo_url</span><span class="p">,</span> <span class="s1">&#39;git@example.com:me/my_repo.git&#39;</span>
<span class="n">ask</span> <span class="ss">:branch</span><span class="p">,</span> <span class="nb">proc</span> <span class="p">{</span> <span class="sb">`git rev-parse --abbrev-ref HEAD`</span><span class="o">.</span><span class="n">chomp</span> <span class="p">}</span>
</code></pre></div>
<p>Here we&#39;d set the name of the application, ideally in a way that&#39;s safe for
filenames on your target operating system.</p>
@ -479,11 +467,10 @@ Cancan (for authorisation) along side Twitter Bootstrap for assets has been
forked to the Capistrano repository, but you can find the (unchanged) original
<a href="https://github.com/RailsApps/rails3-bootstrap-devise-cancan">here</a>.</p>
<div>
<pre data-line=''><code class='language-ruby'>set :application, &#39;rails3-bootstrap-devise-cancan-demo&#39;
set :repo_url, &#39;https://github.com/capistrano/rails3-bootstrap-devise-cancan&#39;
set :branch, &#39;master&#39;</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">set</span> <span class="ss">:application</span><span class="p">,</span> <span class="s1">&#39;rails3-bootstrap-devise-cancan-demo&#39;</span>
<span class="n">set</span> <span class="ss">:repo_url</span><span class="p">,</span> <span class="s1">&#39;https://github.com/capistrano/rails3-bootstrap-devise-cancan&#39;</span>
<span class="n">set</span> <span class="ss">:branch</span><span class="p">,</span> <span class="s1">&#39;master&#39;</span>
</code></pre></div>
<p>I&#39;ve simplified the <code>:branch</code> variable to simply be a <code>set</code> variable, not a
question prompt, as this repository only has a master branch.</p>

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>
@ -139,9 +140,9 @@ Ruby software to form part of a larger tool.</p>
<h4 id="toc_1">What does it look like?</h4>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ cap staging deploy</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>cap staging deploy
</code></pre></div>
<div>
<pre data-line class="language-capistrano"><code data-language="capistrano"><span style="color:white;">DEBUG</span> Uploading /tmp/git-ssh.sh 0%
@ -217,53 +218,52 @@ Ruby software to form part of a larger tool.</p>
<li>A sane, expressive API:</li>
</ul>
<div>
<pre data-line=''><code class='language-ruby'>desc &quot;Show off the API&quot;
task :ditty do
<div class="highlight"><pre><code class="ruby"> <span class="n">desc</span> <span class="s2">&quot;Show off the API&quot;</span>
<span class="n">task</span> <span class="ss">:ditty</span> <span class="k">do</span>
on roles(:all) do |host|
# Capture output from the remote host, and re-use it
# we can reflect on the `host` object passed to the block
# and use the `info` logger method to benefit from the
# output formatter that is selected.
uptime = capture(&#39;uptime&#39;)
if host.roles.include?(:web)
info &quot;Your webserver #{host} has uptime: #{uptime}&quot;
end
end
<span class="n">on</span> <span class="n">roles</span><span class="p">(</span><span class="ss">:all</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">host</span><span class="o">|</span>
<span class="c1"># Capture output from the remote host, and re-use it</span>
<span class="c1"># we can reflect on the `host` object passed to the block</span>
<span class="c1"># and use the `info` logger method to benefit from the</span>
<span class="c1"># output formatter that is selected.</span>
<span class="n">uptime</span> <span class="o">=</span> <span class="n">capture</span><span class="p">(</span><span class="s1">&#39;uptime&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">host</span><span class="o">.</span><span class="n">roles</span><span class="o">.</span><span class="n">include?</span><span class="p">(</span><span class="ss">:web</span><span class="p">)</span>
<span class="n">info</span> <span class="s2">&quot;Your webserver </span><span class="si">#{</span><span class="n">host</span><span class="si">}</span><span class="s2"> has uptime: </span><span class="si">#{</span><span class="n">uptime</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
on roles(:app) do
# We can set environmental variables for the duration of a block
# and move the process into a directoy, executing arbitrary tasks
# such as letting Rails do some heavy lifting.
with({:rails_env =&gt; :production}) do
within(&#39;/var/www/my/rails/app&#39;) do
execute :rails, :runner, &#39;MyModel.something&#39;
end
end
end
<span class="n">on</span> <span class="n">roles</span><span class="p">(</span><span class="ss">:app</span><span class="p">)</span> <span class="k">do</span>
<span class="c1"># We can set environmental variables for the duration of a block</span>
<span class="c1"># and move the process into a directoy, executing arbitrary tasks</span>
<span class="c1"># such as letting Rails do some heavy lifting.</span>
<span class="n">with</span><span class="p">({</span><span class="ss">:rails_env</span> <span class="o">=&gt;</span> <span class="ss">:production</span><span class="p">})</span> <span class="k">do</span>
<span class="n">within</span><span class="p">(</span><span class="s1">&#39;/var/www/my/rails/app&#39;</span><span class="p">)</span> <span class="k">do</span>
<span class="n">execute</span> <span class="ss">:rails</span><span class="p">,</span> <span class="ss">:runner</span><span class="p">,</span> <span class="s1">&#39;MyModel.something&#39;</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
on roles(:db) do
# We can even switch users, provided we have support on the remote
# server for switching to that user without being prompted for a
# passphrase.
as &#39;postgres&#39; do
widgets = capture &quot;echo &#39;SELECT * FROM widgets;&#39; | psql my_database&quot;
if widgets.to_i &lt; 50
warn &quot;There are fewer than 50 widgets in the database on #{host}!&quot;
end
end
end
<span class="n">on</span> <span class="n">roles</span><span class="p">(</span><span class="ss">:db</span><span class="p">)</span> <span class="k">do</span>
<span class="c1"># We can even switch users, provided we have support on the remote</span>
<span class="c1"># server for switching to that user without being prompted for a</span>
<span class="c1"># passphrase.</span>
<span class="n">as</span> <span class="s1">&#39;postgres&#39;</span> <span class="k">do</span>
<span class="n">widgets</span> <span class="o">=</span> <span class="n">capture</span> <span class="s2">&quot;echo &#39;SELECT * FROM widgets;&#39; | psql my_database&quot;</span>
<span class="k">if</span> <span class="n">widgets</span><span class="o">.</span><span class="n">to_i</span> <span class="o">&lt;</span> <span class="mi">50</span>
<span class="nb">warn</span> <span class="s2">&quot;There are fewer than 50 widgets in the database on </span><span class="si">#{</span><span class="n">host</span><span class="si">}</span><span class="s2">!&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
on roles(:all) do
# We can even use `test` the way the Unix gods intended
if test(&quot;[ -d /some/directory ]&quot;)
info &quot;Phew, it&#39;s ok, the directory exists!&quot;
end
end
<span class="n">on</span> <span class="n">roles</span><span class="p">(</span><span class="ss">:all</span><span class="p">)</span> <span class="k">do</span>
<span class="c1"># We can even use `test` the way the Unix gods intended</span>
<span class="k">if</span> <span class="nb">test</span><span class="p">(</span><span class="s2">&quot;[ -d /some/directory ]&quot;</span><span class="p">)</span>
<span class="n">info</span> <span class="s2">&quot;Phew, it&#39;s ok, the directory exists!&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
end</code></pre>
</div>
<span class="k">end</span>
</code></pre></div>
</div>
</div>
@ -295,9 +295,9 @@ Ruby software to form part of a larger tool.</p>
<h4 id="toc_1">What does it look like?</h4>
<div>
<pre data-line=''><code class='language-bash'>me@localhost $ cap staging deploy</code></pre>
</div>
<div class="highlight"><pre><code class="bash"> me@localhost <span class="nv">$ </span>cap staging deploy
</code></pre></div>
<div>
<pre data-line class="language-capistrano"><code data-language="capistrano"><span style="color:white;">DEBUG</span> Uploading /tmp/git-ssh.sh 0%
@ -373,53 +373,52 @@ Ruby software to form part of a larger tool.</p>
<li>A sane, expressive API:</li>
</ul>
<div>
<pre data-line=''><code class='language-ruby'>desc &quot;Show off the API&quot;
task :ditty do
<div class="highlight"><pre><code class="ruby"> <span class="n">desc</span> <span class="s2">&quot;Show off the API&quot;</span>
<span class="n">task</span> <span class="ss">:ditty</span> <span class="k">do</span>
on roles(:all) do |host|
# Capture output from the remote host, and re-use it
# we can reflect on the `host` object passed to the block
# and use the `info` logger method to benefit from the
# output formatter that is selected.
uptime = capture(&#39;uptime&#39;)
if host.roles.include?(:web)
info &quot;Your webserver #{host} has uptime: #{uptime}&quot;
end
end
<span class="n">on</span> <span class="n">roles</span><span class="p">(</span><span class="ss">:all</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">host</span><span class="o">|</span>
<span class="c1"># Capture output from the remote host, and re-use it</span>
<span class="c1"># we can reflect on the `host` object passed to the block</span>
<span class="c1"># and use the `info` logger method to benefit from the</span>
<span class="c1"># output formatter that is selected.</span>
<span class="n">uptime</span> <span class="o">=</span> <span class="n">capture</span><span class="p">(</span><span class="s1">&#39;uptime&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">host</span><span class="o">.</span><span class="n">roles</span><span class="o">.</span><span class="n">include?</span><span class="p">(</span><span class="ss">:web</span><span class="p">)</span>
<span class="n">info</span> <span class="s2">&quot;Your webserver </span><span class="si">#{</span><span class="n">host</span><span class="si">}</span><span class="s2"> has uptime: </span><span class="si">#{</span><span class="n">uptime</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
on roles(:app) do
# We can set environmental variables for the duration of a block
# and move the process into a directoy, executing arbitrary tasks
# such as letting Rails do some heavy lifting.
with({:rails_env =&gt; :production}) do
within(&#39;/var/www/my/rails/app&#39;) do
execute :rails, :runner, &#39;MyModel.something&#39;
end
end
end
<span class="n">on</span> <span class="n">roles</span><span class="p">(</span><span class="ss">:app</span><span class="p">)</span> <span class="k">do</span>
<span class="c1"># We can set environmental variables for the duration of a block</span>
<span class="c1"># and move the process into a directoy, executing arbitrary tasks</span>
<span class="c1"># such as letting Rails do some heavy lifting.</span>
<span class="n">with</span><span class="p">({</span><span class="ss">:rails_env</span> <span class="o">=&gt;</span> <span class="ss">:production</span><span class="p">})</span> <span class="k">do</span>
<span class="n">within</span><span class="p">(</span><span class="s1">&#39;/var/www/my/rails/app&#39;</span><span class="p">)</span> <span class="k">do</span>
<span class="n">execute</span> <span class="ss">:rails</span><span class="p">,</span> <span class="ss">:runner</span><span class="p">,</span> <span class="s1">&#39;MyModel.something&#39;</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
on roles(:db) do
# We can even switch users, provided we have support on the remote
# server for switching to that user without being prompted for a
# passphrase.
as &#39;postgres&#39; do
widgets = capture &quot;echo &#39;SELECT * FROM widgets;&#39; | psql my_database&quot;
if widgets.to_i &lt; 50
warn &quot;There are fewer than 50 widgets in the database on #{host}!&quot;
end
end
end
<span class="n">on</span> <span class="n">roles</span><span class="p">(</span><span class="ss">:db</span><span class="p">)</span> <span class="k">do</span>
<span class="c1"># We can even switch users, provided we have support on the remote</span>
<span class="c1"># server for switching to that user without being prompted for a</span>
<span class="c1"># passphrase.</span>
<span class="n">as</span> <span class="s1">&#39;postgres&#39;</span> <span class="k">do</span>
<span class="n">widgets</span> <span class="o">=</span> <span class="n">capture</span> <span class="s2">&quot;echo &#39;SELECT * FROM widgets;&#39; | psql my_database&quot;</span>
<span class="k">if</span> <span class="n">widgets</span><span class="o">.</span><span class="n">to_i</span> <span class="o">&lt;</span> <span class="mi">50</span>
<span class="nb">warn</span> <span class="s2">&quot;There are fewer than 50 widgets in the database on </span><span class="si">#{</span><span class="n">host</span><span class="si">}</span><span class="s2">!&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
on roles(:all) do
# We can even use `test` the way the Unix gods intended
if test(&quot;[ -d /some/directory ]&quot;)
info &quot;Phew, it&#39;s ok, the directory exists!&quot;
end
end
<span class="n">on</span> <span class="n">roles</span><span class="p">(</span><span class="ss">:all</span><span class="p">)</span> <span class="k">do</span>
<span class="c1"># We can even use `test` the way the Unix gods intended</span>
<span class="k">if</span> <span class="nb">test</span><span class="p">(</span><span class="s2">&quot;[ -d /some/directory ]&quot;</span><span class="p">)</span>
<span class="n">info</span> <span class="s2">&quot;Phew, it&#39;s ok, the directory exists!&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
end</code></pre>
</div>
<span class="k">end</span>
</code></pre></div>
-->
<!--</div> [> /container <] -->

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>
@ -126,18 +127,18 @@
<p>2.
We recommend to capify the project from scratch and move definitions from old to new configs then.</p>
<p><div>
<pre data-line=''><code class='language-bash'>mkdir old_cap
mv Capfile old_cap
mv config/deploy.rb old_cap
mv config/deploy/ old_cap # --&gt; only for multistage setups</code></pre>
</div></p>
<div class="highlight"><pre><code class="bash"> mkdir old_cap
mv Capfile old_cap
mv config/deploy.rb old_cap
mv config/deploy/ old_cap <span class="c"># --&gt; only for multistage setups</span>
</code></pre></div>
<p>It&#39;s time to capify:</p>
<p><div>
<pre data-line=''><code class='language-bash'>cap install</code></pre>
</div></p>
<div class="highlight"><pre><code class="bash"> cap install
</code></pre></div>
<p>3.
Capistrano 3.x is multistage by default, so you will have <code>config/deploy/production.rb</code> and <code>config/deploy/staging.rb</code> right after capifying.
@ -149,11 +150,11 @@ mv config/deploy/ old_cap # --&gt; only for multistage setups</code></pre>
<p>5.
If you had a gateway server set doing <code>set :gateway, &quot;www.capify.org&quot;</code> you should upgrade to</p>
<p><div>
<pre data-line=''><code class='language-ruby'>require &#39;net/ssh/proxy/command&#39;</p>
<div class="highlight"><pre><code class="ruby"> <span class="nb">require</span> <span class="s1">&#39;net/ssh/proxy/command&#39;</span>
<p>set :ssh_options, proxy: Net::SSH::Proxy::Command.new(&#39;ssh mygateway.com -W %h:%p&#39;)</code></pre>
</div></p>
<span class="n">set</span> <span class="ss">:ssh_options</span><span class="p">,</span> <span class="ss">proxy</span><span class="p">:</span> <span class="no">Net</span><span class="o">::</span><span class="no">SSH</span><span class="o">::</span><span class="no">Proxy</span><span class="o">::</span><span class="no">Command</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">&#39;ssh mygateway.com -W %h:%p&#39;</span><span class="p">)</span>
</code></pre></div>
<p>Or the per-server <code>ssh_options</code> equivalent.</p>
@ -167,9 +168,9 @@ mv config/deploy/ old_cap # --&gt; only for multistage setups</code></pre>
<p>7.
If you didn&#39;t use <code>deploy_to</code> before and deployed to <code>/u/apps/your_app_name</code>, you need one more change. Now default deploy path is <code>/var/www/app_name</code> and your config will be broken after upgrade. Just declare custom <code>deploy_to</code> option:</p>
<p><div>
<pre data-line=''><code class='language-ruby'>set :deploy_to, &quot;/u/apps/#{fetch(:application)}&quot;</code></pre>
</div></p>
<div class="highlight"><pre><code class="ruby"> <span class="n">set</span> <span class="ss">:deploy_to</span><span class="p">,</span> <span class="s2">&quot;/u/apps/</span><span class="si">#{</span><span class="n">fetch</span><span class="p">(</span><span class="ss">:application</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span>
</code></pre></div>
<p>But in advance, <code>/u/apps</code> is not the best place to store apps and we advice you to change it later.</p>
@ -185,22 +186,20 @@ mv config/deploy/ old_cap # --&gt; only for multistage setups</code></pre>
<p>Instead of:</p>
<div>
<pre data-line=''><code class='language-ruby'>run &lt;&lt;-CMD.compact
cd -- #{latest_release} &amp;&amp;
RAILS_ENV=#{rails_env.to_s.shellescape} #{asset_env} #{rake} assets:precompile
CMD</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">run</span> <span class="o">&lt;&lt;-</span><span class="no">CMD</span><span class="o">.</span><span class="n">compact</span>
<span class="sh"> cd -- #{latest_release} &amp;&amp;</span>
<span class="sh"> RAILS_ENV=#{rails_env.to_s.shellescape} #{asset_env} #{rake} assets:precompile</span>
<span class="no"> CMD</span>
</code></pre></div>
<p>It&#39;s better to use:</p>
<div>
<pre data-line=''><code class='language-ruby'>within fetch(:latest_release_directory)
with rails_env: fetch(:rails_env) do
execute :rake, &#39;assets:precompile&#39;
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">within</span> <span class="n">fetch</span><span class="p">(</span><span class="ss">:latest_release_directory</span><span class="p">)</span>
<span class="n">with</span> <span class="n">rails_env</span><span class="p">:</span> <span class="n">fetch</span><span class="p">(</span><span class="ss">:rails_env</span><span class="p">)</span> <span class="k">do</span>
<span class="n">execute</span> <span class="ss">:rake</span><span class="p">,</span> <span class="s1">&#39;assets:precompile&#39;</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
</div>
</div>
@ -219,18 +218,18 @@ end</code></pre>
<p>2.
We recommend to capify the project from scratch and move definitions from old to new configs then.</p>
<p><div>
<pre data-line=''><code class='language-bash'>mkdir old_cap
mv Capfile old_cap
mv config/deploy.rb old_cap
mv config/deploy/ old_cap # --&gt; only for multistage setups</code></pre>
</div></p>
<div class="highlight"><pre><code class="bash"> mkdir old_cap
mv Capfile old_cap
mv config/deploy.rb old_cap
mv config/deploy/ old_cap <span class="c"># --&gt; only for multistage setups</span>
</code></pre></div>
<p>It&#39;s time to capify:</p>
<p><div>
<pre data-line=''><code class='language-bash'>cap install</code></pre>
</div></p>
<div class="highlight"><pre><code class="bash"> cap install
</code></pre></div>
<p>3.
Capistrano 3.x is multistage by default, so you will have <code>config/deploy/production.rb</code> and <code>config/deploy/staging.rb</code> right after capifying.
@ -242,11 +241,11 @@ mv config/deploy/ old_cap # --&gt; only for multistage setups</code></pre>
<p>5.
If you had a gateway server set doing <code>set :gateway, &quot;www.capify.org&quot;</code> you should upgrade to</p>
<p><div>
<pre data-line=''><code class='language-ruby'>require &#39;net/ssh/proxy/command&#39;</p>
<div class="highlight"><pre><code class="ruby"> <span class="nb">require</span> <span class="s1">&#39;net/ssh/proxy/command&#39;</span>
<p>set :ssh_options, proxy: Net::SSH::Proxy::Command.new(&#39;ssh mygateway.com -W %h:%p&#39;)</code></pre>
</div></p>
<span class="n">set</span> <span class="ss">:ssh_options</span><span class="p">,</span> <span class="ss">proxy</span><span class="p">:</span> <span class="no">Net</span><span class="o">::</span><span class="no">SSH</span><span class="o">::</span><span class="no">Proxy</span><span class="o">::</span><span class="no">Command</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">&#39;ssh mygateway.com -W %h:%p&#39;</span><span class="p">)</span>
</code></pre></div>
<p>Or the per-server <code>ssh_options</code> equivalent.</p>
@ -260,9 +259,9 @@ mv config/deploy/ old_cap # --&gt; only for multistage setups</code></pre>
<p>7.
If you didn&#39;t use <code>deploy_to</code> before and deployed to <code>/u/apps/your_app_name</code>, you need one more change. Now default deploy path is <code>/var/www/app_name</code> and your config will be broken after upgrade. Just declare custom <code>deploy_to</code> option:</p>
<p><div>
<pre data-line=''><code class='language-ruby'>set :deploy_to, &quot;/u/apps/#{fetch(:application)}&quot;</code></pre>
</div></p>
<div class="highlight"><pre><code class="ruby"> <span class="n">set</span> <span class="ss">:deploy_to</span><span class="p">,</span> <span class="s2">&quot;/u/apps/</span><span class="si">#{</span><span class="n">fetch</span><span class="p">(</span><span class="ss">:application</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span>
</code></pre></div>
<p>But in advance, <code>/u/apps</code> is not the best place to store apps and we advice you to change it later.</p>
@ -278,22 +277,20 @@ mv config/deploy/ old_cap # --&gt; only for multistage setups</code></pre>
<p>Instead of:</p>
<div>
<pre data-line=''><code class='language-ruby'>run &lt;&lt;-CMD.compact
cd -- #{latest_release} &amp;&amp;
RAILS_ENV=#{rails_env.to_s.shellescape} #{asset_env} #{rake} assets:precompile
CMD</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">run</span> <span class="o">&lt;&lt;-</span><span class="no">CMD</span><span class="o">.</span><span class="n">compact</span>
<span class="sh"> cd -- #{latest_release} &amp;&amp;</span>
<span class="sh"> RAILS_ENV=#{rails_env.to_s.shellescape} #{asset_env} #{rake} assets:precompile</span>
<span class="no"> CMD</span>
</code></pre></div>
<p>It&#39;s better to use:</p>
<div>
<pre data-line=''><code class='language-ruby'>within fetch(:latest_release_directory)
with rails_env: fetch(:rails_env) do
execute :rake, &#39;assets:precompile&#39;
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"> <span class="n">within</span> <span class="n">fetch</span><span class="p">(</span><span class="ss">:latest_release_directory</span><span class="p">)</span>
<span class="n">with</span> <span class="n">rails_env</span><span class="p">:</span> <span class="n">fetch</span><span class="p">(</span><span class="ss">:rails_env</span><span class="p">)</span> <span class="k">do</span>
<span class="n">execute</span> <span class="ss">:rake</span><span class="p">,</span> <span class="s1">&#39;assets:precompile&#39;</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
-->
<!--</div> [> /container <] -->

View file

@ -12,6 +12,7 @@
<link rel="stylesheet" href="/css/capistrano.css">
<link rel="stylesheet" href="/css/social_foundicons.css" />
<link rel="stylesheet" href="/css/okaidia.css">
<link rel="stylesheet" href="/css/syntax.css">
<script src="/js/vendor/custom.modernizr.js"></script>
</head>
<body>
@ -120,15 +121,14 @@
<h2>A remote server automation and deployment tool written in Ruby.</h2>
<h3 id="toc_0">A Simple Task</h3>
<div>
<pre data-line=''><code class='language-ruby'>role :demo, %w{example.com example.org example.net}
task :uptime do |host|
on roles(:demo), in: :parallel do
uptime = capture(:uptime)
puts &quot;#{host.hostname} reports: #{uptime}&quot;
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"><span class="n">role</span> <span class="ss">:demo</span><span class="p">,</span> <span class="sx">%w{example.com example.org example.net}</span>
<span class="n">task</span> <span class="ss">:uptime</span> <span class="k">do</span> <span class="o">|</span><span class="n">host</span><span class="o">|</span>
<span class="n">on</span> <span class="n">roles</span><span class="p">(</span><span class="ss">:demo</span><span class="p">),</span> <span class="k">in</span><span class="p">:</span> <span class="ss">:parallel</span> <span class="k">do</span>
<span class="n">uptime</span> <span class="o">=</span> <span class="n">capture</span><span class="p">(</span><span class="ss">:uptime</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">host</span><span class="o">.</span><span class="n">hostname</span><span class="si">}</span><span class="s2"> reports: </span><span class="si">#{</span><span class="n">uptime</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>Capistrano extends the <em>Rake</em> DSL with methods specific to running commands
<code>on()</code> servers.</p>
@ -160,15 +160,14 @@ extended to support them.</p>
<!-- <h3 id="toc_0">A Simple Task</h3>
<div>
<pre data-line=''><code class='language-ruby'>role :demo, %w{example.com example.org example.net}
task :uptime do |host|
on roles(:demo), in: :parallel do
uptime = capture(:uptime)
puts &quot;#{host.hostname} reports: #{uptime}&quot;
end
end</code></pre>
</div>
<div class="highlight"><pre><code class="ruby"><span class="n">role</span> <span class="ss">:demo</span><span class="p">,</span> <span class="sx">%w{example.com example.org example.net}</span>
<span class="n">task</span> <span class="ss">:uptime</span> <span class="k">do</span> <span class="o">|</span><span class="n">host</span><span class="o">|</span>
<span class="n">on</span> <span class="n">roles</span><span class="p">(</span><span class="ss">:demo</span><span class="p">),</span> <span class="k">in</span><span class="p">:</span> <span class="ss">:parallel</span> <span class="k">do</span>
<span class="n">uptime</span> <span class="o">=</span> <span class="n">capture</span><span class="p">(</span><span class="ss">:uptime</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">host</span><span class="o">.</span><span class="n">hostname</span><span class="si">}</span><span class="s2"> reports: </span><span class="si">#{</span><span class="n">uptime</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>Capistrano extends the <em>Rake</em> DSL with methods specific to running commands
<code>on()</code> servers.</p>

View file

@ -14,14 +14,14 @@ h1, h2, h3, h4, h5, h6 {
font-family: 'Enriqueta', serif;
}
p code, li code {
/*p code, li code {
padding: 3px;
background-color: #E6E6E6;
font-family: "droid-sans-mono", Consolas, Monaco, 'Andale Mono', monospace;
font-size: 0.9em;
color: #222;
border-radius: 3px;
}
}*/
footer {
padding: 1em;
@ -52,6 +52,6 @@ footer ul.social.icons li {
height: 44px !important;
}
pre code {
/*pre code {
color: #fff;
}
}*/

60
css/syntax.css Normal file
View file

@ -0,0 +1,60 @@
.highlight { background: #ffffff; padding: 10px; }
.highlight .c { color: #999988; font-style: italic } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { font-weight: bold } /* Keyword */
.highlight .o { font-weight: bold } /* Operator */
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #999999 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { font-weight: bold } /* Keyword.Constant */
.highlight .kd { font-weight: bold } /* Keyword.Declaration */
.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #009999 } /* Literal.Number */
.highlight .s { color: #d14 } /* Literal.String */
.highlight .na { color: #008080 } /* Name.Attribute */
.highlight .nb { color: #0086B3 } /* Name.Builtin */
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
.highlight .no { color: #008080 } /* Name.Constant */
.highlight .ni { color: #800080 } /* Name.Entity */
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
.highlight .nn { color: #555555 } /* Name.Namespace */
.highlight .nt { color: #000080 } /* Name.Tag */
.highlight .nv { color: #008080 } /* Name.Variable */
.highlight .ow { font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #009999 } /* Literal.Number.Float */
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
.highlight .sb { color: #d14 } /* Literal.String.Backtick */
.highlight .sc { color: #d14 } /* Literal.String.Char */
.highlight .sd { color: #d14 } /* Literal.String.Doc */
.highlight .s2 { color: #d14 } /* Literal.String.Double */
.highlight .se { color: #d14 } /* Literal.String.Escape */
.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
.highlight .si { color: #d14 } /* Literal.String.Interpol */
.highlight .sx { color: #d14 } /* Literal.String.Other */
.highlight .sr { color: #009926 } /* Literal.String.Regex */
.highlight .s1 { color: #d14 } /* Literal.String.Single */
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #008080 } /* Name.Variable.Class */
.highlight .vg { color: #008080 } /* Name.Variable.Global */
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */

View file

@ -3,7 +3,7 @@ title: Capistrano in ruby script
layout: default
---
Instead of building a config folder and deploy, you may want to programmatically set everything in a single ruby script. This could be done as follows:
{% prism ruby %}
{% highlight ruby %}
require 'capistrano/all'
stages = "production"
@ -19,6 +19,6 @@ Instead of building a config folder and deploy, you may want to programmatically
Capistrano::Application.invoke("production")
Capistrano::Application.invoke("deploy")
{% endprism%}
{% endhighlight%}
Note that the require order is important as the stage needs to be set before you load setup and deploy.

View file

@ -13,14 +13,14 @@ that match a given set of hostnames.
If the filter matches no servers, no actions will be taken.
If you specify a filter, it will match servers that have the listed hostnames,
If you specify a filter, it will match servers that have the listed hostnames,
and it will run *all* the roles for each server. In other words, it only affects
the servers the task runs on, not what tasks are run on a server.
the servers the task runs on, not what tasks are run on a server.
You can limit by role and by host; if you do this, the role filtering will
apply first. For example, lets say you filtered by the role `app`, then by
the hostnames `server1` and `server2`. Capistrano would first filter the
available servers to only those with the role `app`, then filter them
available servers to only those with the role `app`, then filter them
to look for servers with the hostname `server1` or `server2`. If only `server2`
had the role `app` (`server1` has some other role), then in this situation your
task would only run on `server2`.
@ -34,9 +34,9 @@ There are three ways to specify the host filter.
Capistrano will read the host filter from the environment variable `HOSTS`
if it is set. You can set it inline:
{% prism bash %}
{% highlight bash %}
HOSTS=server1,server2 cap production deploy
{% endprism %}
{% endhighlight %}
Specify multiple hosts by separating them with a comma.
@ -45,9 +45,9 @@ Specify multiple hosts by separating them with a comma.
You can set the host filter inside your deploy configuration. For example,
you can set the following inside `config/deploy.rb`:
{% prism ruby %}
{% highlight ruby %}
set :filter, :hosts => %w{server1 server2}
{% endprism %}
{% endhighlight %}
Note that you specify the filter as an array rather than as a comma-separated
list of servers when using this method.
@ -57,9 +57,9 @@ list of servers when using this method.
In a similar way to using the environment variable, you can set the role
filter by specifying it as a command line argument to `cap`:
{% prism bash %}
{% highlight bash %}
cap --hosts=server1,server2 production deploy
{% endprism %}
{% endhighlight %}
Like the environment variable method, specify multiple servers by separating
them with a comma.
Like the environment variable method, specify multiple servers by separating
them with a comma.

View file

@ -8,7 +8,7 @@ The `remote_file` task is allowing the existence of a remote file to be set as a
As as example, this task can be used to ensure that files to be linked exist
before running the check:linked_files task:
{% prism ruby %}
{% highlight ruby %}
namespace :deploy do
namespace :check do
task :linked_files => 'config/newrelic.yml'
@ -21,4 +21,4 @@ before running the check:linked_files task:
sh "curl -o #{t.name} https://rpm.newrelic.com/accounts/xx/newrelic.yml"
end
{% endprism %}
{% endhighlight %}

View file

@ -12,7 +12,7 @@ match a given role or roles.
If the filter matches no servers, no actions will be taken.
If you specify a filter, it will match any servers that have that role, but
If you specify a filter, it will match any servers that have that role, but
it will _only_ run the tasks for that role, not for any other roles that
server may have. For example, if you filtered for servers with the `web` role,
and a server had both the `web` and `db` role, only the `web` role would
@ -27,9 +27,9 @@ There are three ways to specify the role filter.
Capistrano will read the role filter from the environment variable `ROLES`
if it is set. You can set it inline:
{% prism bash %}
{% highlight bash %}
ROLES=app,web cap production deploy
{% endprism %}
{% endhighlight %}
Specify multiple roles by separating them with a comma.
@ -38,9 +38,9 @@ Specify multiple roles by separating them with a comma.
You can set the role filter inside your deploy configuration. For example,
you can set the following inside `config/deploy.rb`:
{% prism ruby %}
{% highlight ruby %}
set :filter, :roles => %w{app web}
{% endprism %}
{% endhighlight %}
Note that you specify the filter as an array rather than as a comma-separated
list of roles when using this method.
@ -50,9 +50,9 @@ list of roles when using this method.
In a similar way to using the environment variable, you can set the role
filter by specifying it as a command line argument to `cap`:
{% prism bash %}
{% highlight bash %}
cap --roles=app,web production deploy
{% endprism %}
{% endhighlight %}
Like the environment variable method, specify multiple roles by separating them
with a comma.
with a comma.

View file

@ -7,10 +7,10 @@ Capistrano executes commands on remote servers using [**SSHKit**](https://github
An example setting a working directory, user and environment variable:
{% prism ruby %}
{% highlight ruby %}
on roles(:app), in: :sequence, wait: 5 do
within "/opt/sites/example.com" do
# commands in this block execute in the
# commands in this block execute in the
# directory: /opt/sites/example.com
as :deploy do
# commands in this block execute as the "deploy" user.
@ -23,7 +23,7 @@ on roles(:app), in: :sequence, wait: 5 do
end
end
end
{% endprism %}
{% endhighlight %}
For more examples, see the EXAMPLES.md file in the [**SSHKit**](https://github.com/capistrano/sshkit) project:

View file

@ -60,23 +60,23 @@ figure this out!
First, we'll try a *real* SSH session, logging in via our terminal, and seeing
what happens:
{% prism bash %}
{% highlight bash %}
me@localhost $ ssh me@remote
me@remote $ [[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'
Interactive
me@remote $ shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'
Login shell
{% endprism %}
{% endhighlight %}
Contrast that with what happens when we hand the command to run to the SSH
command line without logging in first...
{% prism bash %}
{% highlight bash %}
me@localhost $ ssh me@remote "[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'"
Interactive
me@localhost $ ssh me@remote "shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'"
Not login shell
{% endprism %}
{% endhighlight %}
Here we can see that Bash is still starting in **interactive** mode when we're
just running a single command, that's because the terminal we are using is
@ -86,7 +86,7 @@ When we try the same with Capistrano we'll see yet another set of results; we
can have a very simple, Capfile, we don't even need to load the default
recipes to test this:
{% prism ruby %}
{% highlight ruby %}
# Capistrano 3.0.x
task :query_interactive do
on 'me@remote' do
@ -98,16 +98,16 @@ recipes to test this:
info capture("shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'")
end
end
{% endprism %}
{% endhighlight %}
Gives us the following:
{% prism bash %}
{% highlight bash %}
me@localhost $ cap query_login
INFO Not login shell
me@localhost $ cap query_interactive
INFO Not interactive
{% endprism %}
{% endhighlight %}
## <a id="which_startup_files_loaded"></a>Which shell startup files do get loaded?

View file

@ -12,10 +12,10 @@ to make this work reliably for unique logins across team members)
To create this deploy user we'll assume something like the following has been
done:
{% prism bash %}
{% highlight bash %}
root@remote $ adduser deploy
root@remote $ passwd -l deploy
{% endprism %}
{% endhighlight %}
The first line creates a completely standard user, it has a home directory,
which we'll need in a moment, and has a shell, so it may log in. This needs to
@ -53,9 +53,9 @@ public key to the `deploy` user's `authorized_keys` file, that way if someone
quits or gets fired, you can remove their key from that file, and the rest of
you can keep on shipping!
{% prism bash %}
{% highlight bash %}
me@localhost $ ssh-keygen -t rsa -C 'me@my_email_address.com'
{% endprism %}
{% endhighlight %}
You'll be prompted for a passphrase, that's fine. Type one and keep it safe.
This passphrase ensures that if your computer is stolen, people still need a
@ -71,17 +71,17 @@ minutes upwards.)
We can see which keys are loaded in the SSH agent by running `ssh-add -l`
{% prism bash %}
{% highlight bash %}
me@localhost $ ssh-add -l
2048 af:ce:7e:c5:93:18:39:ff:54:20:7a:2d:ec:05:7c:a5 /Users/me/.ssh/id_rsa (RSA)
{% endprism %}
{% endhighlight %}
If you don't see any keys listed, you can simply run `ssh-add`:
{% prism bash %}
{% highlight bash %}
me@localhost $ ssh-add
Identity added: /Users/me/.ssh/id_rsa (/Users/me/.ssh/id_rsa)
{% endprism %}
{% endhighlight %}
Typically, ssh-add will ask you for the passphrase when you add a key.
@ -97,10 +97,10 @@ At this point with the key loaded into the agent, we need to put the
`/home/users/deploy/.ssh/authorized_keys`, to get the contents of that file,
we can ask our local key agent for the public parts of the keys it has loaded:
{% prism bash %}
{% highlight bash %}
me@localhost $ ssh-add -L
ssh-rsa jccXJ/JRfGxnkh/8iL........dbfCH/9cDiKa0Dw8XGAo01mU/w== /Users/me/.ssh/id_rsa
{% endprism %}
{% endhighlight %}
This will be a lot longer when you run it, I snipped the output because it
looked bad.
@ -115,7 +115,7 @@ If you are on linux there often exists a command
[`ssh-copy-id`](http://linux.die.net/man/1/ssh-copy-id) which streamlines this
process, otherwise the workflow is something like:
{% prism bash %}
{% highlight bash %}
me@localhost $ ssh root@remote
root@remote $ su - deploy
deploy@remote $ cd ~
@ -123,7 +123,7 @@ process, otherwise the workflow is something like:
deploy@remote $ echo "ssh-rsa jccXJ/JRfGxnkh/8iL........dbfCH/9cDiKa0Dw8XGAo01mU/w== /Users/me/.ssh/id_rsa" >> .ssh/authorized_keys
deploy@remote $ chmod 700 .ssh
deploy@remote $ chmod 600 .ssh/authorized_keys
{% endprism %}
{% endhighlight %}
**Remember:** This needs to be done on every server you want to use, you can
use the same key for each one, but only one key per developer is recommended.
@ -131,11 +131,11 @@ use the same key for each one, but only one key per developer is recommended.
If we did all that correctly, we should now be able to do something like this:
{% prism bash %}
{% highlight bash %}
me@localhost $ ssh deploy@one-of-my-servers.com 'hostname; uptime'
one-of-my-servers.com
19:23:32 up 62 days, 44 min, 1 user, load average: 0.00, 0.01, 0.05
{% endprism %}
{% endhighlight %}
That should happen without having to enter a passphrase for your SSH key, or
prompting you for an SSH password (which the deploy user doesn't have anyway).
@ -163,7 +163,7 @@ charset="utf-8"></script>
If your server isn't accessible directly and you need to use the SSH
ProxyCommand option, you should do
{% prism ruby %}
{% highlight ruby %}
require 'net/ssh/proxy/command'
set :ssh_options, proxy: Net::SSH::Proxy::Command.new('ssh mygateway.com -W %h:%p')
@ -174,7 +174,7 @@ server 'internal-hostname',
ssh_options: {
proxy: Net::SSH::Proxy::Command.new('ssh mygateway.com -W %h:%p'),
}
{% endprism %}
{% endhighlight %}
#### 1.2 From our servers to the repository host
@ -191,10 +191,10 @@ Github.
Here's how we can check if that works, first get the URL of the repository:
{% prism bash %}
{% highlight bash %}
me@localhost $ git config remote.origin.url
git@github.com:capistrano/rails3-bootstrap-devise-cancan.git
{% endprism %}
{% endhighlight %}
Here we're listing our private (for testing purposes) fork of the
rails3-bootstrap-devise-cancan repository forked from the Rails Examples and
@ -202,13 +202,13 @@ Tutorials project.
We can try to access the repository via our server by doing the following:
{% prism bash %}
{% highlight bash %}
# List SSH keys that are loaded into the agent
me@localhost $ ssh-add -l
# Make sure they key is loaded if 'ssh-add -l' didn't show anything
me@localhost $ ssh-add
me@localhost $ ssh -A deploy@one-of-my-servers.com 'git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git
{% endprism %}
{% endhighlight %}
We first check that the agent has the keys loaded. If not we simply load it
and enter the passphrase when prompted.
@ -224,7 +224,7 @@ to the list of known hosts.
From the SSH documentation:
{% prism bash %}
{% highlight bash %}
-A Enables forwarding of the authentication agent connection. This can also be
specified on a per-host basis in a configuration file.
@ -234,7 +234,7 @@ From the SSH documentation:
attacker cannot obtain key material from the agent, however they can perform
operations on the keys that enable them to authenticate using the identities
loaded into the agent.
{% endprism %}
{% endhighlight %}
In layman's terms, you shouldn't use SSH agent forwarding to machines where you
don't trust the administrators, as they can can override the permissions on
@ -253,11 +253,11 @@ Github, we'll be prompted for a username and password:
##### 1.2.2.1 With a regular username/password
{% prism bash %}
{% highlight bash %}
me@localhost $ git ls-remote https://github.com/capistrano/rails3-bootstrap-devise-cancan.git
Username for 'https://github.com': myownusername
Password for 'https://capistrano@github.com':
{% endprism %}
{% endhighlight %}
This challenge response prompt doesn't work well for automating things, so
there are two ways to get around this depending on your server's host
@ -268,11 +268,11 @@ The other mechanism, and the reason that its **very** important to always use
HTTPS not plain ol' HTTP is to embed the username and password in the URL,
note this won't work well if your password has special characters:
{% prism bash %}
{% highlight bash %}
me@localhost $ git ls-remote https://capistrano:ourverysecretpassword@github.com/capistrano/rails3-bootstrap-devise-cancan.git
3419812c9f146d9a84b44bcc2c3caef94da54758HEAD
3419812c9f146d9a84b44bcc2c3caef94da54758HEADrefs/heads/master
{% endprism %}
{% endhighlight %}
The bigger problem with passwords, whether inlined into the URL, or entered
into a `netrc` file, is that the password gives access to **your entire Github
@ -285,11 +285,11 @@ at Github, they recently rolled out a feature called [Personal API
Tokens](https://github.com/blog/1509-personal-api-tokens) which allow you to
do something like this:
{% prism bash %}
{% highlight bash %}
me@localhost $ git ls-remote https://.....................@github.com/capistrano/rails3-bootstrap-devise-cancan.git
3419812c9f146d9a84b44bcc2c3caef94da54758HEAD
3419812c9f146d9a84b44bcc2c3caef94da54758HEADrefs/heads/master
{% endprism %}
{% endhighlight %}
Where `....` is a personal API token, as such:
@ -320,9 +320,9 @@ have configured *passwordless* `sudo`. Configuring `sudo` to give some users
access to come commands under some circumstances is beyond the scope of this
documentation, but sufficed to say something like:
{% prism bash %}
{% highlight bash %}
deploy ALL=NOPASSWD:/etc/init.d/mysqld, /etc/init.d/apache2
{% endprism %}
{% endhighlight %}
This example would give the user named `deploy` access to call `sudo
/etc/init.d/mysql _________` and the same for the `apache2` control script.
@ -337,7 +337,7 @@ notice a change.
To configure this hierarchy, ignoring for the moment the passwordless `sudo`
access that you may or may not need depending how well your servers are setup:
{% prism bash %}
{% highlight bash %}
me@localhost $ ssh root@remote
# Capistrano will use /var/www/....... where ... is the value set in
# :application, you can override this by setting the ':deploy_to' variable
@ -347,7 +347,7 @@ access that you may or may not need depending how well your servers are setup:
root@remote $ umask 0002
root@remote $ chmod g+s ${deploy_to}
root@remote $ mkdir ${deploy_to}/{releases,shared}
{% endprism %}
{% endhighlight %}
**Note:** The `chmod g+s` is a really handy, and little known Unix feature, it
means that at the operating system level, without having to pay much attention
@ -360,12 +360,12 @@ group: read/write, other: none*. This means that we'll be able to read these
files from Apache, or our web server by running the web server in the `deploy`
group namespace.
{% prism bash %}
{% highlight bash %}
root@remote # stat -c "%A (%a) %n" ${deploy_to}/
drwx--S--- (2700) /var/www/rails3-bootstrap-devise-cancan-demo
root@remote # stat -c "%A (%a) %n" ${deploy_to}/*
drwxrwsr-x (2775) /var/www/rails3-bootstrap-devise-cancan-demo/releases
drwxrwsr-x (2775) /var/www/rails3-bootstrap-devise-cancan-demo/shared
{% endprism %}
{% endhighlight %}

View file

@ -20,7 +20,7 @@ technologies.
### 1. Checking the directory structure on the remote machine:
{% prism bash %}
{% highlight bash %}
me@localhost $ ssh deploy@remote 'ls -lR /var/www/my-application'
my-application:
total 8
@ -32,7 +32,7 @@ technologies.
my-application/shared:
total 0
{% endprism %}
{% endhighlight %}
This checks in one simple command that the ssh keys you setup are working (you
might yet be prompted for the password), and the permissions on the directory
@ -44,7 +44,7 @@ Now that we know how to check for permissions, and repository access, we'll
quickly introduce ourselves to a quick Cap task to check these things on all
the machines for us:
{% prism ruby %}
{% highlight ruby %}
desc "Check that we can access everything"
task :check_write_permissions do
on roles(:all) do |host|
@ -55,7 +55,7 @@ the machines for us:
end
end
end
{% endprism %}
{% endhighlight %}
Running this should give you a pretty decent overview, one line of output for
each server. It's also your first introduction to the API of Capistrano for
@ -70,22 +70,22 @@ later, but add those lines to a file in `./lib/capistrano/tasks`, call it
something like `access_check.cap`, and run `cap -T` from the top directory and
we'll be able to see the task listed:
{% prism bash %}
{% highlight bash %}
me@localhost $ bundle exec cap -T
# ... lots of other tasks ...
cap check_write_permissions # Check that we can access everything
# ... lots of other tasks ...
{% endprism %}
{% endhighlight %}
Then we simply call it:
{% prism bash %}
{% highlight bash %}
me@localhost $ bundle exec cap staging check_write_permissions
DEBUG [82c92144] Running /usr/bin/env [ -w /var/www/my-application ] on myserver.com
DEBUG [82c92144] Command: [ -w /var/www/my-application ]
DEBUG [82c92144] Finished in 0.456 seconds command successful.
INFO /var/www/my-application is writable on myserver.com
{% endprism %}
{% endhighlight %}
If we've done something wrong, that won't happen and we'll know that we need
to jump on the mailing list to get help, into IRC or ask a friend.
@ -98,9 +98,9 @@ wrap Git in a shell script that makes it behave.
Capistrano does just this, so to check if the Git access is working, we can
simply call:
{% prism bash %}
{% highlight bash %}
me@localhost $ cap staging git:check
{% endprism %}
{% endhighlight %}
This task is defined
[here](https://github.com/capistrano/capistrano/blob/master/lib/capistrano/tasks/git.rake)
@ -113,7 +113,7 @@ one of the pieces we inherit from Rake)
If this fails we'll see:
{% prism bash %}
{% highlight bash %}
me@localhost $ cap staging git:check
cap staging git:check
DEBUG Uploading /tmp/git-ssh.sh 0%
@ -132,7 +132,7 @@ If this fails we'll see:
Tasks: TOP => git:check
(See full trace by running task with --trace)
{% endprism %}
{% endhighlight %}
This'll typically come out looking more beautiful depending on your terminal
colour support, you may well see something like this:
@ -159,7 +159,7 @@ In this case, we'll be using SSH agent forwarding, we can check if that's
working by writing a tiny Cap task, or simply using SSH to do it for us, the
choice is yours:
{% prism ruby %}
{% highlight ruby %}
# lib/capistrano/tasks/agent_forwarding.cap
desc "Check if agent forwarding is working"
task :forwarding do
@ -171,32 +171,32 @@ choice is yours:
end
end
end
{% endprism %}
{% endhighlight %}
That gave the output:
{% prism bash %}
{% highlight bash %}
cap staging forwarding
DEBUG [f1269276] Running /usr/bin/env env | grep SSH_AUTH_SOCK on example.com
DEBUG [f1269276] Command: env | grep SSH_AUTH_SOCK
DEBUG [f1269276] SSH_AUTH_SOCK=/tmp/ssh-nQUEmyQ2nS/agent.2546
DEBUG [f1269276] Finished in 0.453 seconds command successful.
INFO Agent forwarding is up to example.com
{% endprism %}
{% endhighlight %}
If you don't feel like writing a Capistrano task, one could simply do:
{% prism bash %}
{% highlight bash %}
me@localhost $ ssh -A example.com 'env | grep SSH_AUTH_SOCK'
SSH_AUTH_SOCK=/tmp/ssh-Tb6X8V53tm/agent.2934
{% endprism %}
{% endhighlight %}
If we see the `SSH_AUTH_SOCK` output, that's a pretty good indication that SSH
agent forwarding is enabled, and if on your local machine `ssh-add -l` shows
you an SSH key, then we're good to go. **Make sure that you're using the
`git@...` repository URL**
{% prism bash %}
{% highlight bash %}
cap staging git:check
DEBUG Uploading /tmp/git-ssh.sh 0%
INFO Uploading /tmp/git-ssh.sh 100%
@ -208,6 +208,6 @@ you an SSH key, then we're good to go. **Make sure that you're using the
DEBUG [f40edfbb] 3419812c9f146d9a84b44bcc2c3caef94da54758 HEAD
DEBUG [f40edfbb] 3419812c9f146d9a84b44bcc2c3caef94da54758 refs/heads/master
INFO [f40edfbb] Finished in 3.319 seconds command successful.
{% endprism %}
{% endhighlight %}
![Capistrano Git Check Colour Example](/images/successful-git-check-example-screenshot.png)

View file

@ -10,7 +10,7 @@ Capistrano v3 provides a default **deploy flow** and a **rollback flow**:
When you run `cap production deploy`, it invokes the following tasks in
sequence:
{% prism ruby %}
{% highlight ruby %}
deploy:starting - start a deployment, make sure everything is ready
deploy:started - started hook (for custom tasks)
deploy:updating - update server(s) with a new release
@ -19,7 +19,7 @@ deploy:publishing - publish the new release
deploy:published - published hook
deploy:finishing - finish the deployment, clean up everything
deploy:finished - finished hook
{% endprism %}
{% endhighlight %}
Notice there are several hook tasks e.g. `:started`, `:updated` for
you to hook up custom tasks into the flow using `after()` and `before()`.
@ -29,7 +29,7 @@ you to hook up custom tasks into the flow using `after()` and `before()`.
When you run `cap production deploy:rollback`, it invokes the following
tasks in sequence:
{% prism ruby %}
{% highlight ruby %}
deploy:starting
deploy:started
deploy:reverting - revert server(s) to previous release
@ -38,7 +38,7 @@ deploy:publishing
deploy:published
deploy:finishing_rollback - finish the rollback, clean up everything
deploy:finished
{% endprism %}
{% endhighlight %}
As you can see, rollback flow shares many tasks with deploy flow. But note that, rollback flow runs its own `:finishing_rollback` task because its
cleanup process is usually different from deploy flow.
@ -47,18 +47,18 @@ cleanup process is usually different from deploy flow.
Assume you require the following files in `Capfile`,
{% prism ruby %}
{% highlight ruby %}
# Capfile
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/bundler'
require 'capistrano/rails/migrations'
require 'capistrano/rails/assets'
{% endprism %}
{% endhighlight %}
When you run `cap production deploy`, it runs these tasks:
{% prism ruby %}
{% highlight ruby %}
deploy
deploy:starting
[before]
@ -85,11 +85,11 @@ deploy
deploy:cleanup
deploy:finished
deploy:log_revision
{% endprism %}
{% endhighlight %}
For `cap production deploy:rollback`, it runs these tasks:
{% prism ruby %}
{% highlight ruby %}
deploy
deploy:starting
[before]
@ -110,5 +110,5 @@ deploy
deploy:cleanup_rollback
deploy:finished
deploy:log_revision
{% endprism %}
{% endhighlight %}

View file

@ -17,28 +17,28 @@ therefore recommended to use an appropriate bundler.
The following command will install the latest released capistrano `v3` revision:
{% prism bash %}
{% highlight bash %}
$ gem install capistrano
{% endprism %}
{% endhighlight %}
Or grab the bleeding edge head from:
{% prism bash %}
{% highlight bash %}
$ git clone https://github.com/capistrano/capistrano.git
$ cd capistrano
$ gem build *.gemspec
$ gem install *.gem
{% endprism %}
{% endhighlight %}
### Usage in a Rails project
Add the following lines to the Gemfile:
{% prism ruby %}
{% highlight ruby %}
group :development do
gem 'capistrano-rails', '~> 1.0.0'
end
{% endprism %}
{% endhighlight %}
The `capistrano-rails` gem includes extras specifically designed for Ruby on
Rails, specifically:
@ -53,9 +53,9 @@ The documentation for these components can be found in
part, to get the best, and most sensible results, simply `require` in
Capfile, after the `require 'capistrano/deploy'` line:
{% prism ruby %}
{% highlight ruby %}
require 'capistrano/rails'
{% endprism %}
{% endhighlight %}
<div class="alert alert-info">
<h5>Help! I was using Capistrano `v2.x` and I didn't want to upgrade!</h5>
@ -64,9 +64,9 @@ If you are using Capistrano `v2.x.x` and have also installed Capistrano `v3`
by mistake, then you can lock your Gem version for Capistrano at something
like:
{% prism ruby %}
{% highlight ruby %}
gem 'capistrano', '~> 2.15' # Or whatever patch release you are using
{% endprism %}
{% endhighlight %}
This is the [pessimistic operator][rubygems-pessimistic-operator] which
installs the closest matching version, at the time of writing this would

View file

@ -38,24 +38,24 @@ configuration into place at deploy time.
The original `database.yml` should be added to the `.gitignore` (or your SCM's
parallel concept of ignored files)
{% prism bash %}
{% highlight bash %}
$ cp config/database.yml{,.example}
$ echo config/database.yml >> .gitignore
{% endprism %}
{% endhighlight %}
This should be done for any other secret files, we'll create the production
version of the file when we deploy, and symlink it into place.
### 3. Initialize Capistrano in your application.
{% prism bash %}
{% highlight bash %}
$ cd my-project
$ cap install
{% endprism %}
{% endhighlight %}
This will create a bunch of files, the important ones are:
{% prism bash %}
{% highlight bash %}
├── Capfile
├── config
│   ├── deploy
@ -65,7 +65,7 @@ This will create a bunch of files, the important ones are:
└── lib
└── capistrano
└── tasks
{% endprism %}
{% endhighlight %}
Your new Capfile will automatically any tasks from any *.cap files in lib/capistrano/tasks.
@ -90,7 +90,7 @@ common.
The example file generated will look something like this:
{% prism ruby %}
{% highlight ruby %}
set :stage, :staging
# Simple Role Syntax
@ -111,7 +111,7 @@ The example file generated will look something like this:
server 'example.com', roles: %w{web app}, my_property: :my_value
# set :rails_env, :staging
{% endprism %}
{% endhighlight %}
Both the simple role, and extended server syntaxes result in one or more
servers for each role being defined. The `app` and `db` roles are just
@ -130,12 +130,12 @@ servers, one where we set the username, and another where we set the port.
These host strings are parsed and expanded out in to the equivalent of the
server line after the comment:
{% prism ruby %}
{% highlight ruby %}
role :web, %w{hello@world.com example.com:1234}
# ...is the same as doing...
server 'world.com' roles: [:web], user: 'hello'
server 'example.com', roles: [:web], port: 1234
{% endprism %}
{% endhighlight %}
### 5. Set the shared information in `deploy.rb`.
@ -147,11 +147,11 @@ The generated sample file starts with the following, and is followed by a few
self-documenting, commented-out configuration options, feel free to play with
them a little:
{% prism ruby %}
{% highlight ruby %}
set :application, 'my app name'
set :repo_url, 'git@example.com:me/my_repo.git'
ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }
{% endprism %}
{% endhighlight %}
Here we'd set the name of the application, ideally in a way that's safe for
filenames on your target operating system.
@ -170,11 +170,11 @@ Cancan (for authorisation) along side Twitter Bootstrap for assets has been
forked to the Capistrano repository, but you can find the (unchanged) original
[here](https://github.com/RailsApps/rails3-bootstrap-devise-cancan).
{% prism ruby %}
{% highlight ruby %}
set :application, 'rails3-bootstrap-devise-cancan-demo'
set :repo_url, 'https://github.com/capistrano/rails3-bootstrap-devise-cancan'
set :branch, 'master'
{% endprism %}
{% endhighlight %}
I've simplified the `:branch` variable to simply be a `set` variable, not a
question prompt, as this repository only has a master branch.

View file

@ -22,9 +22,9 @@ Ruby software to form part of a larger tool.
#### What does it look like?
{% prism bash %}
{% highlight bash %}
me@localhost $ cap staging deploy
{% endprism %}
{% endhighlight %}
<div>
<pre data-line class="language-capistrano"><code data-language="capistrano"><span style="color:white;">DEBUG</span> Uploading /tmp/git-ssh.sh 0%
@ -98,7 +98,7 @@ There's lots of cool stuff in the Capistrano toy box:
* Support for complex environments.
* A sane, expressive API:
{% prism ruby %}
{% highlight ruby %}
desc "Show off the API"
task :ditty do
@ -144,4 +144,4 @@ There's lots of cool stuff in the Capistrano toy box:
end
end
{% endprism %}
{% endhighlight %}

View file

@ -12,18 +12,18 @@ layout: default
2.
We recommend to capify the project from scratch and move definitions from old to new configs then.
{% prism bash %}
{% highlight bash %}
mkdir old_cap
mv Capfile old_cap
mv config/deploy.rb old_cap
mv config/deploy/ old_cap # --> only for multistage setups
{% endprism %}
{% endhighlight %}
It's time to capify:
{% prism bash %}
{% highlight bash %}
cap install
{% endprism %}
{% endhighlight %}
3.
Capistrano 3.x is multistage by default, so you will have `config/deploy/production.rb` and `config/deploy/staging.rb` right after capifying.
@ -35,11 +35,11 @@ layout: default
5.
If you had a gateway server set doing `set :gateway, "www.capify.org"` you should upgrade to
{% prism ruby %}
{% highlight ruby %}
require 'net/ssh/proxy/command'
set :ssh_options, proxy: Net::SSH::Proxy::Command.new('ssh mygateway.com -W %h:%p')
{% endprism %}
{% endhighlight %}
Or the per-server `ssh_options` equivalent.
@ -54,9 +54,9 @@ layout: default
7.
If you didn't use `deploy_to` before and deployed to `/u/apps/your_app_name`, you need one more change. Now default deploy path is `/var/www/app_name` and your config will be broken after upgrade. Just declare custom `deploy_to` option:
{% prism ruby %}
{% highlight ruby %}
set :deploy_to, "/u/apps/#{fetch(:application)}"
{% endprism %}
{% endhighlight %}
But in advance, `/u/apps` is not the best place to store apps and we advice you to change it later.
@ -72,19 +72,19 @@ layout: default
Instead of:
{% prism ruby %}
{% highlight ruby %}
run <<-CMD.compact
cd -- #{latest_release} &&
RAILS_ENV=#{rails_env.to_s.shellescape} #{asset_env} #{rake} assets:precompile
CMD
{% endprism %}
{% endhighlight %}
It's better to use:
{% prism ruby %}
{% highlight ruby %}
within fetch(:latest_release_directory)
with rails_env: fetch(:rails_env) do
execute :rake, 'assets:precompile'
end
end
{% endprism %}
{% endhighlight %}

View file

@ -5,7 +5,7 @@ title: A remote server automation and deployment tool written in Ruby.
### A Simple Task
{% prism ruby %}
{% highlight ruby %}
role :demo, %w{example.com example.org example.net}
task :uptime do |host|
on roles(:demo), in: :parallel do
@ -13,7 +13,7 @@ task :uptime do |host|
puts "#{host.hostname} reports: #{uptime}"
end
end
{% endprism %}
{% endhighlight %}
Capistrano extends the *Rake* DSL with methods specific to running commands
`on()` servers.