mirror of
				https://github.com/capistrano/capistrano
				synced 2023-03-27 23:21:18 -04:00 
			
		
		
		
	More cold-start documentation
This commit is contained in:
		
							parent
							
								
									4592f0e5d7
								
							
						
					
					
						commit
						bd73a5a56f
					
				
					 6 changed files with 777 additions and 0 deletions
				
			
		
							
								
								
									
										564
									
								
								_site/documentation/getting-started/cold-start/index.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										564
									
								
								_site/documentation/getting-started/cold-start/index.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,564 @@
 | 
			
		|||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta charset="utf-8">
 | 
			
		||||
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
			
		||||
    <title>Cold Start</title>
 | 
			
		||||
    <link href='http://fonts.googleapis.com/css?family=Enriqueta' rel='stylesheet' type='text/css'>
 | 
			
		||||
    <script type="text/javascript" src="//use.typekit.net/itm5ubu.js"></script>
 | 
			
		||||
    <script type="text/javascript">try{Typekit.load();}catch(e){}</script>
 | 
			
		||||
    <link rel="stylesheet" href="/css/foundation.css" />
 | 
			
		||||
    <link rel="stylesheet" href="/css/capistrano.css">
 | 
			
		||||
    <link rel="stylesheet" href="/css/social_foundicons.css" />
 | 
			
		||||
    <link rel="stylesheet" href="/css/okaidia.css">
 | 
			
		||||
    <script src="/js/vendor/custom.modernizr.js"></script>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
 | 
			
		||||
    <script type="text/javascript">
 | 
			
		||||
      var _gauges = _gauges || [];
 | 
			
		||||
      (function() {
 | 
			
		||||
        var t   = document.createElement('script');
 | 
			
		||||
        t.type  = 'text/javascript';
 | 
			
		||||
        t.async = true;
 | 
			
		||||
        t.id    = 'gauges-tracker';
 | 
			
		||||
        t.setAttribute('data-site-id', '51c83c32613f5d7df70000bc');
 | 
			
		||||
        t.src = '//secure.gaug.es/track.js';
 | 
			
		||||
        var s = document.getElementsByTagName('script')[0];
 | 
			
		||||
        s.parentNode.insertBefore(t, s);
 | 
			
		||||
      })();
 | 
			
		||||
    </script>
 | 
			
		||||
 | 
			
		||||
    <script type="text/javascript">
 | 
			
		||||
      setTimeout(function(){var a=document.createElement("script");
 | 
			
		||||
      var b=document.getElementsByTagName("script")[0];
 | 
			
		||||
      a.src=document.location.protocol+"//dnn506yrbagrg.cloudfront.net/pages/scripts/0017/6418.js?"+Math.floor(new Date().getTime()/3600000);
 | 
			
		||||
      a.async=true;a.type="text/javascript";b.parentNode.insertBefore(a,b)}, 1);
 | 
			
		||||
    </script>
 | 
			
		||||
 | 
			
		||||
    <script>
 | 
			
		||||
      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
 | 
			
		||||
      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
 | 
			
		||||
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
 | 
			
		||||
      })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
 | 
			
		||||
 | 
			
		||||
      ga('create', 'UA-41970098-1', 'capistranorb.com');
 | 
			
		||||
      ga('send', 'pageview');
 | 
			
		||||
    </script>
 | 
			
		||||
    <div class="top-bar">
 | 
			
		||||
  <a href="/" class="brand">
 | 
			
		||||
    <img src="/images/CapistranoLogo.png" />
 | 
			
		||||
  </a>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <div class="row">
 | 
			
		||||
      <div class="large-4 columns">
 | 
			
		||||
        <ul class="side-nav">
 | 
			
		||||
  <li><a href="http://www.harrow.io/" class="advertisment"><span class="label label-important">New</span> Hosted Capistrano for Teams</a></li>
 | 
			
		||||
  <li class="divider"></li>
 | 
			
		||||
  <h5>Overview</h5>
 | 
			
		||||
  <li><a href="/documentation/overview/what-is-capistrano/">What is Capistrano?</a></li>
 | 
			
		||||
  <li><a href="/documentation/overview/introductory-demo-video/">Introductory Demo Video</a></li>
 | 
			
		||||
  <li class="divider"></li>
 | 
			
		||||
  <h5>Getting Started</h5>
 | 
			
		||||
  <li><a href="/documentation/getting-started/installation/">Installation</a></li>
 | 
			
		||||
  <li><a href="/documentation/getting-started/preparing-your-application/">Preparing Your Application</a></li>
 | 
			
		||||
  <li><a href="/documentation/getting-started/authentication-and-authorisation/">Authentication & Authorisation</a></li>
 | 
			
		||||
  <li><a href="/documentation/getting-started/cold-start/">Cold Start</a></li>
 | 
			
		||||
  <li><a href="/documentation/getting-started/rollbacks/">Rollbacks</a></li>
 | 
			
		||||
  <li class="divider"></li>
 | 
			
		||||
  <h5>Troubleshooting</h5>
 | 
			
		||||
  <li><a href="/documentation/troubleshooting/authentication/">SCM (Git) Authentication</a></li>
 | 
			
		||||
  <li><a href="/documentation/troubleshooting/connectivity/">Connectivity</a></li>
 | 
			
		||||
  <!--<li><a href="/documentation/troubleshooting/gateway-servers/">Gateway Servers</a></li>-->
 | 
			
		||||
  <li><a href="/documentation/troubleshooting/agent-forwarding/">Agent Forwarding</a></li>
 | 
			
		||||
  <li><a href="/documentation/troubleshooting/sudo-password/">`sudo` Password</a></li>
 | 
			
		||||
  <li><a href="/documentation/troubleshooting/rvm-rbenv-nvm/">RVM, `rbenv` And `nvm`</a></li>
 | 
			
		||||
  <li class="divider"></li>
 | 
			
		||||
  <h5>FAQ</h5>
 | 
			
		||||
  <li><a
 | 
			
		||||
    href="/documentation/faq/why-does-something-work-in-my-ssh-session-but-not-in-capistrano/">Why Does Something Work In An SSH Session, But Not In Capistrano?</a></li>
 | 
			
		||||
  <li><a href="/documentation/faq/should-i-use-capistrano-to-provision-my-servers/">Should I Use Capistrano To Provision My Servers?</a></li>
 | 
			
		||||
  <li class="divider"></li>
 | 
			
		||||
  <h5>Power Use-Cases</h5>
 | 
			
		||||
  <li><a href="/documentation/power-use-cases/integration-with-rake/">Integration With Rake</a></li>
 | 
			
		||||
  <li><a href="/documentation/power-use-cases/driving-tools-such-as-chef-solo/">Driving Tools Such As <em>Chef Solo</em></a></li>
 | 
			
		||||
  <li class="divider"></li>
 | 
			
		||||
  <h5>Recent Announcements</h5>
 | 
			
		||||
  
 | 
			
		||||
    <li><a href="/2013/06/01/release-announcement.html"><span class="post-date">01 Jun 2013</span> Capistrano Version 3 Release Announcement</a></li>
 | 
			
		||||
  
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="large-8 column">
 | 
			
		||||
        <div class="content">
 | 
			
		||||
          <h2>Cold Start</h2>
 | 
			
		||||
          <p>At this point we should have a deploy user on all the servers we intend to
 | 
			
		||||
deploy to, that user should have permission to write to wherever we plan on
 | 
			
		||||
deploying to, by default that'll be something like <code>/var/www/my-application</code>.</p>
 | 
			
		||||
 | 
			
		||||
<p>We've set up the directory with decent permissions so that we can deploy
 | 
			
		||||
without breaking things, and that everyone on our team can deploy, too.</p>
 | 
			
		||||
 | 
			
		||||
<p>Let's run through what we've done so far, and how to check it's all working,
 | 
			
		||||
in the last step of this part of the guide we'll create the production-only
 | 
			
		||||
shared files.</p>
 | 
			
		||||
 | 
			
		||||
<p>Again, this guide assumes Ruby on Rails, but most of everything we're doing so
 | 
			
		||||
far is applicable in slightly modified forms to other frameworks and
 | 
			
		||||
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 'ls -lR /var/www/my-application'
 | 
			
		||||
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/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
 | 
			
		||||
can be seen.</p>
 | 
			
		||||
 | 
			
		||||
<h3 id="toc_1">2. Writing our first <em>cap task</em> to formalize this into a check!</h3>
 | 
			
		||||
 | 
			
		||||
<p>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:</p>
 | 
			
		||||
 | 
			
		||||
<div>
 | 
			
		||||
  <pre data-line=''><code class='language-ruby'>desc "Check that we can access everything"
 | 
			
		||||
task :check_write_permissions do
 | 
			
		||||
  on roles(:all) do |host|
 | 
			
		||||
    if test("[ -w #{fetch(:deploy_to)} ]")
 | 
			
		||||
      info "#{fetch(:deploy_to)} is writable on #{host}"
 | 
			
		||||
    else
 | 
			
		||||
      error "#{fetch(:deploy_to)} is not writable on #{host}"
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end</code></pre>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<p>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
 | 
			
		||||
writing your own tasks, namely <code>desc()</code>, <code>task()</code>, <code>on()</code>, <code>roles()</code>,
 | 
			
		||||
<code>test()</code>, <code>info()</code>, and <code>error()</code>.</p>
 | 
			
		||||
 | 
			
		||||
<p>The first two methods, <code>desc()</code> and <code>task()</code> are actually from Rake, the
 | 
			
		||||
library that forms the foundation of the Capistrano task system, the other
 | 
			
		||||
methods are part of our sub-project
 | 
			
		||||
<a href="https://github.com/leehambley/sshkit"><strong>SSHKit</strong></a>. We'll dive into those more
 | 
			
		||||
later, but add those lines to a file in <code>./lib/capistrano/tasks</code>, call it
 | 
			
		||||
something like <code>access_check.cap</code>, and run <code>cap -T</code> from the top directory and
 | 
			
		||||
we'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>
 | 
			
		||||
 | 
			
		||||
<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>
 | 
			
		||||
 | 
			
		||||
<p>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, or into IRC or ask a friend.</p>
 | 
			
		||||
 | 
			
		||||
<p>Depending how you have set your Git authentication credentials up, checking
 | 
			
		||||
Git can be a bit complicated, so we've shipped a task in the core library that
 | 
			
		||||
can check your git access, Git isn't particularly scriptable, so one has to
 | 
			
		||||
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>
 | 
			
		||||
 | 
			
		||||
<p>This task is defined
 | 
			
		||||
<a href="https://github.com/capistrano/capistrano/blob/v3/lib/capistrano/tasks/git.rake#L17">here</a>
 | 
			
		||||
in the source code, and looks a lot like what we wrote above to check the file
 | 
			
		||||
permissions, however the Git check recipe is a bit more complicated, having to
 | 
			
		||||
potentially deal with three different authentication schemes, which need to be
 | 
			
		||||
worked around differently. This task expresses a <em>dependency</em> on the
 | 
			
		||||
<code>git:git-wrapper</code> task which is resolved first for us by Capistrano. (This is
 | 
			
		||||
one of the pieces we inherit from Rake)</p>
 | 
			
		||||
 | 
			
		||||
<p>If this fails we'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 'github.com,204.232.175.90' (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
 | 
			
		||||
 | 
			
		||||
Tasks: TOP => git:check
 | 
			
		||||
(See full trace by running task with --trace)</code></pre>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<p>This'll typically come out looking more beautiful depending on your terminal
 | 
			
		||||
colour support, you may well see something like this:</p>
 | 
			
		||||
 | 
			
		||||
<p><img src="/images/git-check-example-screenshot.png" alt="Capistrano Git Check Colour Example"></p>
 | 
			
		||||
 | 
			
		||||
<p>To run through that shortly, what did we do:</p>
 | 
			
		||||
 | 
			
		||||
<ol>
 | 
			
		||||
<li>We asked Capistrano to run the command <code>git:check</code>.</li>
 | 
			
		||||
<li>Capistrano recognised that in order to fulfil this request, it had first
 | 
			
		||||
to execute the task <code>git:wrapper</code>, a <em>prerequisite</em>.</li>
 | 
			
		||||
<li>Capistrano exexuted the <code>git:wrapper</code> task, and uploaded the
 | 
			
		||||
<code>/tmp/git-ssh.sh</code> file, and made it executable. This satisfies the
 | 
			
		||||
<code>git:wrapper</code> task defined
 | 
			
		||||
<a href="https://github.com/capistrano/capistrano/blob/v3/lib/capistrano/tasks/git.rake#L9">here</a>
 | 
			
		||||
in the source code. This script is actually processed as a template.</li>
 | 
			
		||||
<li>With the git wrapper in place, we can safely script against Git without it
 | 
			
		||||
prompting us for input, so we ask git to <code>ls-remote</code> on the repository we
 | 
			
		||||
defined. As this exited with an <a href="https://en.wikipedia.org/wiki/Exit_status">unclean
 | 
			
		||||
status</a>, Capistrano aborted, and
 | 
			
		||||
printed out the erorr messages for us to try and figure out what broke.</li>
 | 
			
		||||
</ol>
 | 
			
		||||
 | 
			
		||||
<p>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:</p>
 | 
			
		||||
 | 
			
		||||
<div>
 | 
			
		||||
  <pre data-line=''><code class='language-ruby'># lib/capistrano/tasks/agent_forwarding.cap
 | 
			
		||||
desc "Check if agent forwarding is working"
 | 
			
		||||
task :forwarding do
 | 
			
		||||
  on roles(:all) do |h|
 | 
			
		||||
    if test("env | grep SSH_AUTH_SOCK")
 | 
			
		||||
      info "Agent forwarding is up to #{h}"
 | 
			
		||||
    else
 | 
			
		||||
      error "Agent forwarding is NOT up to #{h}"
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end</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>
 | 
			
		||||
 | 
			
		||||
<p>If you don'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 'env | grep SSH_AUTH_SOCK'
 | 
			
		||||
SSH_AUTH_SOCK=/tmp/ssh-Tb6X8V53tm/agent.2934</code></pre>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<p>If we see the <code>SSH_AUTH_SOCK</code> output, that'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're good to go. <strong>Make sure that you'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>
 | 
			
		||||
 | 
			
		||||
<p><img src="/images/successful-git-check-example-screenshot.png" alt="Capistrano Git Check Colour Example"></p>
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!--<div class="container">                                     -->
 | 
			
		||||
      <!--      <h1 class="title"><a href="/">Capistrano</a></h1>-->
 | 
			
		||||
      <!--      <a class="extra" href="/">home</a>                    -->
 | 
			
		||||
      <!--    </div>                                                  -->
 | 
			
		||||
 | 
			
		||||
    <!--    <p>At this point we should have a deploy user on all the servers we intend to
 | 
			
		||||
deploy to, that user should have permission to write to wherever we plan on
 | 
			
		||||
deploying to, by default that'll be something like <code>/var/www/my-application</code>.</p>
 | 
			
		||||
 | 
			
		||||
<p>We've set up the directory with decent permissions so that we can deploy
 | 
			
		||||
without breaking things, and that everyone on our team can deploy, too.</p>
 | 
			
		||||
 | 
			
		||||
<p>Let's run through what we've done so far, and how to check it's all working,
 | 
			
		||||
in the last step of this part of the guide we'll create the production-only
 | 
			
		||||
shared files.</p>
 | 
			
		||||
 | 
			
		||||
<p>Again, this guide assumes Ruby on Rails, but most of everything we're doing so
 | 
			
		||||
far is applicable in slightly modified forms to other frameworks and
 | 
			
		||||
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 'ls -lR /var/www/my-application'
 | 
			
		||||
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/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
 | 
			
		||||
can be seen.</p>
 | 
			
		||||
 | 
			
		||||
<h3 id="toc_1">2. Writing our first <em>cap task</em> to formalize this into a check!</h3>
 | 
			
		||||
 | 
			
		||||
<p>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:</p>
 | 
			
		||||
 | 
			
		||||
<div>
 | 
			
		||||
  <pre data-line=''><code class='language-ruby'>desc "Check that we can access everything"
 | 
			
		||||
task :check_write_permissions do
 | 
			
		||||
  on roles(:all) do |host|
 | 
			
		||||
    if test("[ -w #{fetch(:deploy_to)} ]")
 | 
			
		||||
      info "#{fetch(:deploy_to)} is writable on #{host}"
 | 
			
		||||
    else
 | 
			
		||||
      error "#{fetch(:deploy_to)} is not writable on #{host}"
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end</code></pre>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<p>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
 | 
			
		||||
writing your own tasks, namely <code>desc()</code>, <code>task()</code>, <code>on()</code>, <code>roles()</code>,
 | 
			
		||||
<code>test()</code>, <code>info()</code>, and <code>error()</code>.</p>
 | 
			
		||||
 | 
			
		||||
<p>The first two methods, <code>desc()</code> and <code>task()</code> are actually from Rake, the
 | 
			
		||||
library that forms the foundation of the Capistrano task system, the other
 | 
			
		||||
methods are part of our sub-project
 | 
			
		||||
<a href="https://github.com/leehambley/sshkit"><strong>SSHKit</strong></a>. We'll dive into those more
 | 
			
		||||
later, but add those lines to a file in <code>./lib/capistrano/tasks</code>, call it
 | 
			
		||||
something like <code>access_check.cap</code>, and run <code>cap -T</code> from the top directory and
 | 
			
		||||
we'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>
 | 
			
		||||
 | 
			
		||||
<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>
 | 
			
		||||
 | 
			
		||||
<p>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, or into IRC or ask a friend.</p>
 | 
			
		||||
 | 
			
		||||
<p>Depending how you have set your Git authentication credentials up, checking
 | 
			
		||||
Git can be a bit complicated, so we've shipped a task in the core library that
 | 
			
		||||
can check your git access, Git isn't particularly scriptable, so one has to
 | 
			
		||||
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>
 | 
			
		||||
 | 
			
		||||
<p>This task is defined
 | 
			
		||||
<a href="https://github.com/capistrano/capistrano/blob/v3/lib/capistrano/tasks/git.rake#L17">here</a>
 | 
			
		||||
in the source code, and looks a lot like what we wrote above to check the file
 | 
			
		||||
permissions, however the Git check recipe is a bit more complicated, having to
 | 
			
		||||
potentially deal with three different authentication schemes, which need to be
 | 
			
		||||
worked around differently. This task expresses a <em>dependency</em> on the
 | 
			
		||||
<code>git:git-wrapper</code> task which is resolved first for us by Capistrano. (This is
 | 
			
		||||
one of the pieces we inherit from Rake)</p>
 | 
			
		||||
 | 
			
		||||
<p>If this fails we'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 'github.com,204.232.175.90' (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
 | 
			
		||||
 | 
			
		||||
Tasks: TOP => git:check
 | 
			
		||||
(See full trace by running task with --trace)</code></pre>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<p>This'll typically come out looking more beautiful depending on your terminal
 | 
			
		||||
colour support, you may well see something like this:</p>
 | 
			
		||||
 | 
			
		||||
<p><img src="/images/git-check-example-screenshot.png" alt="Capistrano Git Check Colour Example"></p>
 | 
			
		||||
 | 
			
		||||
<p>To run through that shortly, what did we do:</p>
 | 
			
		||||
 | 
			
		||||
<ol>
 | 
			
		||||
<li>We asked Capistrano to run the command <code>git:check</code>.</li>
 | 
			
		||||
<li>Capistrano recognised that in order to fulfil this request, it had first
 | 
			
		||||
to execute the task <code>git:wrapper</code>, a <em>prerequisite</em>.</li>
 | 
			
		||||
<li>Capistrano exexuted the <code>git:wrapper</code> task, and uploaded the
 | 
			
		||||
<code>/tmp/git-ssh.sh</code> file, and made it executable. This satisfies the
 | 
			
		||||
<code>git:wrapper</code> task defined
 | 
			
		||||
<a href="https://github.com/capistrano/capistrano/blob/v3/lib/capistrano/tasks/git.rake#L9">here</a>
 | 
			
		||||
in the source code. This script is actually processed as a template.</li>
 | 
			
		||||
<li>With the git wrapper in place, we can safely script against Git without it
 | 
			
		||||
prompting us for input, so we ask git to <code>ls-remote</code> on the repository we
 | 
			
		||||
defined. As this exited with an <a href="https://en.wikipedia.org/wiki/Exit_status">unclean
 | 
			
		||||
status</a>, Capistrano aborted, and
 | 
			
		||||
printed out the erorr messages for us to try and figure out what broke.</li>
 | 
			
		||||
</ol>
 | 
			
		||||
 | 
			
		||||
<p>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:</p>
 | 
			
		||||
 | 
			
		||||
<div>
 | 
			
		||||
  <pre data-line=''><code class='language-ruby'># lib/capistrano/tasks/agent_forwarding.cap
 | 
			
		||||
desc "Check if agent forwarding is working"
 | 
			
		||||
task :forwarding do
 | 
			
		||||
  on roles(:all) do |h|
 | 
			
		||||
    if test("env | grep SSH_AUTH_SOCK")
 | 
			
		||||
      info "Agent forwarding is up to #{h}"
 | 
			
		||||
    else
 | 
			
		||||
      error "Agent forwarding is NOT up to #{h}"
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end</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>
 | 
			
		||||
 | 
			
		||||
<p>If you don'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 'env | grep SSH_AUTH_SOCK'
 | 
			
		||||
SSH_AUTH_SOCK=/tmp/ssh-Tb6X8V53tm/agent.2934</code></pre>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<p>If we see the <code>SSH_AUTH_SOCK</code> output, that'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're good to go. <strong>Make sure that you'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>
 | 
			
		||||
 | 
			
		||||
<p><img src="/images/successful-git-check-example-screenshot.png" alt="Capistrano Git Check Colour Example"></p>
 | 
			
		||||
                                           -->
 | 
			
		||||
 | 
			
		||||
    <!--</div> [> /container <]                                     -->
 | 
			
		||||
 | 
			
		||||
  <div class="row">
 | 
			
		||||
  <div class="large-4 columns">
 | 
			
		||||
    <ul>
 | 
			
		||||
    <li><a href="/about">About Capistrano</a></li>
 | 
			
		||||
    <li><a href="https://github.com/capistrano/capistrano/blob/master/CONTRIBUTING">Contributing</a></li>
 | 
			
		||||
    <li><a href="https://rubygems.org/gems/capistrano/versions">Releases</a></li>
 | 
			
		||||
    <li><a href="/upgrading">Upgrading</a></li>
 | 
			
		||||
    <li><a href="/security">Security</a></li>
 | 
			
		||||
    </ul>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  <div class="large-4 columns">
 | 
			
		||||
    <ul>
 | 
			
		||||
      <li><a href="http://stackoverflow.com/questions/tagged/capistrano">StackOverflow</a></li>
 | 
			
		||||
      <li><a href="https://groups.google.com/forum/#!forum/capistrano">Mailing List</a></li>
 | 
			
		||||
      <li><a href=".... ">Commercial Support</a></li>
 | 
			
		||||
    </ul>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  <div class="large-4 columns">
 | 
			
		||||
    <ul>
 | 
			
		||||
      <li><a href="//twitter.com/capistranorb"><i class="foundicon-twitter"></i></a></li>
 | 
			
		||||
      <li><a href="//github.com/capistrano"><i class="foundicon-github"></i></a></li>
 | 
			
		||||
    </ul>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  <script src="/js/prism.js"></script>
 | 
			
		||||
  <script src="/js/prism.ruby.js"></script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								_site/images/git-check-example-screenshot.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								_site/images/git-check-example-screenshot.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 78 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								_site/images/successful-git-check-example-screenshot.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								_site/images/successful-git-check-example-screenshot.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 71 KiB  | 
							
								
								
									
										213
									
								
								documentation/getting-started/cold-start/index.markdown
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								documentation/getting-started/cold-start/index.markdown
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,213 @@
 | 
			
		|||
---
 | 
			
		||||
title: Cold Start
 | 
			
		||||
layout: default
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
At this point we should have a deploy user on all the servers we intend to
 | 
			
		||||
deploy to, that user should have permission to write to wherever we plan on
 | 
			
		||||
deploying to, by default that'll be something like `/var/www/my-application`.
 | 
			
		||||
 | 
			
		||||
We've set up the directory with decent permissions so that we can deploy
 | 
			
		||||
without breaking things, and that everyone on our team can deploy, too.
 | 
			
		||||
 | 
			
		||||
Let's run through what we've done so far, and how to check it's all working,
 | 
			
		||||
in the last step of this part of the guide we'll create the production-only
 | 
			
		||||
shared files.
 | 
			
		||||
 | 
			
		||||
Again, this guide assumes Ruby on Rails, but most of everything we're doing so
 | 
			
		||||
far is applicable in slightly modified forms to other frameworks and
 | 
			
		||||
technologies.
 | 
			
		||||
 | 
			
		||||
### 1. Checking the directory structure on the remote machine:
 | 
			
		||||
 | 
			
		||||
{% prism bash %}
 | 
			
		||||
    me@localhost $ ssh deploy@remote 'ls -lR /var/www/my-application'
 | 
			
		||||
    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/shared:
 | 
			
		||||
    total 0
 | 
			
		||||
{% endprism %}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
can be seen.
 | 
			
		||||
 | 
			
		||||
### 2. Writing our first *cap task* to formalize this into a check!
 | 
			
		||||
 | 
			
		||||
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 %}
 | 
			
		||||
    desc "Check that we can access everything"
 | 
			
		||||
    task :check_write_permissions do
 | 
			
		||||
      on roles(:all) do |host|
 | 
			
		||||
        if test("[ -w #{fetch(:deploy_to)} ]")
 | 
			
		||||
          info "#{fetch(:deploy_to)} is writable on #{host}"
 | 
			
		||||
        else
 | 
			
		||||
          error "#{fetch(:deploy_to)} is not writable on #{host}"
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
{% endprism %}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
writing your own tasks, namely `desc()`, `task()`, `on()`, `roles()`,
 | 
			
		||||
`test()`, `info()`, and `error()`.
 | 
			
		||||
 | 
			
		||||
The first two methods, `desc()` and `task()` are actually from Rake, the
 | 
			
		||||
library that forms the foundation of the Capistrano task system, the other
 | 
			
		||||
methods are part of our sub-project
 | 
			
		||||
[**SSHKit**](https://github.com/leehambley/sshkit). We'll dive into those more
 | 
			
		||||
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 %}
 | 
			
		||||
    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 %}
 | 
			
		||||
 | 
			
		||||
Then we simply call it:
 | 
			
		||||
 | 
			
		||||
{% prism 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 %}
 | 
			
		||||
 | 
			
		||||
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, or into IRC or ask a friend.
 | 
			
		||||
 | 
			
		||||
Depending how you have set your Git authentication credentials up, checking
 | 
			
		||||
Git can be a bit complicated, so we've shipped a task in the core library that
 | 
			
		||||
can check your git access, Git isn't particularly scriptable, so one has to
 | 
			
		||||
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 %}
 | 
			
		||||
  me@localhost $ cap staging git:check
 | 
			
		||||
{% endprism %}
 | 
			
		||||
 | 
			
		||||
This task is defined
 | 
			
		||||
[here](https://github.com/capistrano/capistrano/blob/v3/lib/capistrano/tasks/git.rake#L17)
 | 
			
		||||
in the source code, and looks a lot like what we wrote above to check the file
 | 
			
		||||
permissions, however the Git check recipe is a bit more complicated, having to
 | 
			
		||||
potentially deal with three different authentication schemes, which need to be
 | 
			
		||||
worked around differently. This task expresses a *dependency* on the
 | 
			
		||||
`git:git-wrapper` task which is resolved first for us by Capistrano. (This is
 | 
			
		||||
one of the pieces we inherit from Rake)
 | 
			
		||||
 | 
			
		||||
If this fails we'll see:
 | 
			
		||||
 | 
			
		||||
{% prism 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 'github.com,204.232.175.90' (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
 | 
			
		||||
 | 
			
		||||
    Tasks: TOP => git:check
 | 
			
		||||
    (See full trace by running task with --trace)
 | 
			
		||||
{% endprism %}
 | 
			
		||||
 | 
			
		||||
This'll typically come out looking more beautiful depending on your terminal
 | 
			
		||||
colour support, you may well see something like this:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
To run through that shortly, what did we do:
 | 
			
		||||
 | 
			
		||||
1. We asked Capistrano to run the command `git:check`.
 | 
			
		||||
2. Capistrano recognised that in order to fulfil this request, it had first
 | 
			
		||||
to execute the task `git:wrapper`, a *prerequisite*.
 | 
			
		||||
3. Capistrano exexuted the `git:wrapper` task, and uploaded the
 | 
			
		||||
   `/tmp/git-ssh.sh` file, and made it executable. This satisfies the
 | 
			
		||||
   `git:wrapper` task defined
 | 
			
		||||
   [here](https://github.com/capistrano/capistrano/blob/v3/lib/capistrano/tasks/git.rake#L9)
 | 
			
		||||
   in the source code. This script is actually processed as a template.
 | 
			
		||||
4. With the git wrapper in place, we can safely script against Git without it
 | 
			
		||||
   prompting us for input, so we ask git to `ls-remote` on the repository we
 | 
			
		||||
   defined. As this exited with an [unclean
 | 
			
		||||
   status](https://en.wikipedia.org/wiki/Exit_status), Capistrano aborted, and
 | 
			
		||||
   printed out the erorr messages for us to try and figure out what broke.
 | 
			
		||||
 | 
			
		||||
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 %}
 | 
			
		||||
    # lib/capistrano/tasks/agent_forwarding.cap
 | 
			
		||||
    desc "Check if agent forwarding is working"
 | 
			
		||||
    task :forwarding do
 | 
			
		||||
      on roles(:all) do |h|
 | 
			
		||||
        if test("env | grep SSH_AUTH_SOCK")
 | 
			
		||||
          info "Agent forwarding is up to #{h}"
 | 
			
		||||
        else
 | 
			
		||||
          error "Agent forwarding is NOT up to #{h}"
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
{% endprism %}
 | 
			
		||||
 | 
			
		||||
That gave the output:
 | 
			
		||||
 | 
			
		||||
{% prism 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 %}
 | 
			
		||||
 | 
			
		||||
If you don't feel like writing a Capistrano task, one could simply do:
 | 
			
		||||
 | 
			
		||||
{% prism bash %}
 | 
			
		||||
    me@localhost $ ssh -A example.com 'env | grep SSH_AUTH_SOCK'
 | 
			
		||||
    SSH_AUTH_SOCK=/tmp/ssh-Tb6X8V53tm/agent.2934
 | 
			
		||||
{% endprism %}
 | 
			
		||||
 | 
			
		||||
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 %}
 | 
			
		||||
    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.
 | 
			
		||||
{% endprism %}
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								images/git-check-example-screenshot.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								images/git-check-example-screenshot.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 78 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								images/successful-git-check-example-screenshot.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								images/successful-git-check-example-screenshot.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 71 KiB  | 
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue