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:
|
||||
|
||||
![Capistrano Git Check Colour Example](/images/git-check-example-screenshot.png)
|
||||
|
||||
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 %}
|
||||
|
||||
![Capistrano Git Check Colour Example](/images/successful-git-check-example-screenshot.png)
|
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
Reference in a new issue