mirror of
https://github.com/capistrano/capistrano
synced 2023-03-27 23:21:18 -04:00
Commit this stuff before I lose it all
This commit is contained in:
commit
61aec364b2
26 changed files with 1094 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
_site
|
6
Gemfile
Normal file
6
Gemfile
Normal file
|
@ -0,0 +1,6 @@
|
|||
source "https://rubygems.org"
|
||||
|
||||
gem "debugger"
|
||||
gem "jekyll"
|
||||
gem "redcarpet"
|
||||
gem "git"
|
50
Gemfile.lock
Normal file
50
Gemfile.lock
Normal file
|
@ -0,0 +1,50 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
classifier (1.3.3)
|
||||
fast-stemmer (>= 1.0.0)
|
||||
colorator (0.1)
|
||||
columnize (0.3.6)
|
||||
commander (4.1.3)
|
||||
highline (~> 1.6.11)
|
||||
debugger (1.6.0)
|
||||
columnize (>= 0.3.1)
|
||||
debugger-linecache (~> 1.2.0)
|
||||
debugger-ruby_core_source (~> 1.2.1)
|
||||
debugger-linecache (1.2.0)
|
||||
debugger-ruby_core_source (1.2.2)
|
||||
directory_watcher (1.4.1)
|
||||
fast-stemmer (1.0.2)
|
||||
git (1.2.5)
|
||||
highline (1.6.19)
|
||||
jekyll (1.0.2)
|
||||
classifier (~> 1.3)
|
||||
colorator (~> 0.1)
|
||||
commander (~> 4.1.3)
|
||||
directory_watcher (~> 1.4.1)
|
||||
kramdown (~> 1.0.2)
|
||||
liquid (~> 2.3)
|
||||
maruku (~> 0.5)
|
||||
pygments.rb (~> 0.5.0)
|
||||
safe_yaml (~> 0.7.0)
|
||||
kramdown (1.0.2)
|
||||
liquid (2.5.0)
|
||||
maruku (0.6.1)
|
||||
syntax (>= 1.0.0)
|
||||
posix-spawn (0.3.6)
|
||||
pygments.rb (0.5.0)
|
||||
posix-spawn (~> 0.3.6)
|
||||
yajl-ruby (~> 1.1.0)
|
||||
redcarpet (2.2.2)
|
||||
safe_yaml (0.7.1)
|
||||
syntax (1.0.0)
|
||||
yajl-ruby (1.1.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
debugger
|
||||
git
|
||||
jekyll
|
||||
redcarpet
|
7
_config.yml
Normal file
7
_config.yml
Normal file
|
@ -0,0 +1,7 @@
|
|||
name: Capistrano
|
||||
pygments: true
|
||||
markdown: redcarpet
|
||||
redcarpet:
|
||||
extensions: ["no_intra_emphasis", "fenced_code_blocks", "autolink", "tables", "with_toc_data"]
|
||||
table_of_contents:
|
||||
dirs: [documentation]
|
28
_includes/footer.html
Normal file
28
_includes/footer.html
Normal file
|
@ -0,0 +1,28 @@
|
|||
<div class="bottom-menu">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="span2 brand">
|
||||
<a href="http://capistranorb.com/" class="capistrano-logo"></a>
|
||||
</div>
|
||||
|
||||
<div class="span8">
|
||||
<ul class="bottom-links">
|
||||
<li><a href="#fakelink">About Capistrano</a></li>
|
||||
<li><a href="#fakelink">Contributing</a></li>
|
||||
<li><a href="#fakelink">Releases</a></li>
|
||||
<li><a href="#fakelink">Upgrading</a></li>
|
||||
<li><a href="#fakelink">StackOverflow</a></li>
|
||||
<li><a href="#fakelink">Mailing List</a></li>
|
||||
<li><a href="#fakelink">Support</a></li>
|
||||
<li><a href="#fakelink">Links</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="span2">
|
||||
<ul class="bottom-icons">
|
||||
<li><a href="#fakelink" class="fui-twitter"></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
5
_includes/header.html
Normal file
5
_includes/header.html
Normal file
|
@ -0,0 +1,5 @@
|
|||
<div class="header pure-u-1-1">
|
||||
<a href="/" class="brand">
|
||||
<img src="/images/CapistranoLogo.png" />
|
||||
</a>
|
||||
</div>
|
31
_includes/navigation.html
Normal file
31
_includes/navigation.html
Normal file
|
@ -0,0 +1,31 @@
|
|||
<div class="pure-menu pure-menu-open">
|
||||
<ul class="nav nav-list">
|
||||
<li><a href="http://www.harrow.io/" class="advertisment"><span class="label label-important">New</span> Hosted Capistrano for Teams</a></li>
|
||||
<li class="pure-menu-heading">Overview</li>
|
||||
<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="pure-menu-heading">Getting Started</li>
|
||||
<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="pure-menu-heading">Troubleshooting</li>
|
||||
<li><a href="/documentation/troubleshooting/authentication/">SCM (Git, SVN, etc) 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="pure-menu-heading">FAQ</li>
|
||||
<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="pure-menu-heading">Power Use-Cases</li>
|
||||
<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="pure-menu-heading">Recent Announcements</li>
|
||||
{% for post in site.posts %}
|
||||
<li><a href="{{ post.url }}"><span class="post-date">{{ post.date | date_to_string }}</span> {{ post.title }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
47
_layouts/default.html
Normal file
47
_layouts/default.html
Normal file
|
@ -0,0 +1,47 @@
|
|||
<!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>{{ page.title }}</title>
|
||||
<script type="text/javascript" src="//use.typekit.net/itm5ubu.js"></script>
|
||||
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
|
||||
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,300' rel='stylesheet' type='text/css'>
|
||||
<link href='http://fonts.googleapis.com/css?family=Montserrat' rel='stylesheet' type='text/css'>
|
||||
<link href='http://fonts.googleapis.com/css?family=Enriqueta' rel='stylesheet' type='text/css'>
|
||||
<link href="http://vjs.zencdn.net/4.0.2/video-js.css" rel="stylesheet">
|
||||
<script src="http://vjs.zencdn.net/4.0.2/video.js"></script>
|
||||
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.1.0/pure-min.css">
|
||||
<link rel="stylesheet" href="/css/syntax.css">
|
||||
<link rel="stylesheet" href="/css/capistrano.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{% include header.html %}
|
||||
|
||||
<div class="pure-g-r">
|
||||
<div class="pure-u-1-3">
|
||||
{% include navigation.html %}
|
||||
</div>
|
||||
<div class="pure-u-2-3">
|
||||
<div class="content">
|
||||
<h2>{{ page.title }}</h2>
|
||||
{{ content }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--<div class="container"> -->
|
||||
<!-- <h1 class="title"><a href="/">{{ site.name }}</a></h1>-->
|
||||
<!-- <a class="extra" href="/">home</a> -->
|
||||
<!-- </div> -->
|
||||
|
||||
<!-- {{ content }} -->
|
||||
|
||||
<!--</div> [> /container <] -->
|
||||
|
||||
{% include footer.html %}
|
||||
|
||||
</body>
|
||||
</html>
|
8
_layouts/post.html
Normal file
8
_layouts/post.html
Normal file
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
layout: default
|
||||
---
|
||||
<p class="meta">{{ page.date | date_to_string }}</p>
|
||||
|
||||
<div id="post">
|
||||
{{ content }}
|
||||
</div>
|
1
_layouts/table_of_contents.html
Normal file
1
_layouts/table_of_contents.html
Normal file
|
@ -0,0 +1 @@
|
|||
Why is this here?
|
32
_plugins/gitactivity.rb
Normal file
32
_plugins/gitactivity.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
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)
|
30
_plugins/table_of_contents.rb
Normal file
30
_plugins/table_of_contents.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
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)
|
24
_posts/2013-05-18-welcome-to-jekyll.markdown
Normal file
24
_posts/2013-05-18-welcome-to-jekyll.markdown
Normal file
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
layout: post
|
||||
title: "Welcome to Jekyll!"
|
||||
date: 2013-05-18 15:09:49
|
||||
categories: jekyll update
|
||||
---
|
||||
|
||||
You'll find this post in your `_posts` directory - edit this post and re-build (or run with the `-w` switch) to see your changes!
|
||||
To add new posts, simply add a file in the `_posts` directory that follows the convention: YYYY-MM-DD-name-of-post.ext.
|
||||
|
||||
Jekyll also offers powerful support for code snippets:
|
||||
|
||||
{% highlight ruby %}
|
||||
def print_hi(name)
|
||||
puts "Hi, #{name}"
|
||||
end
|
||||
print_hi('Tom')
|
||||
#=> prints 'Hi, Tom' to STDOUT.
|
||||
{% endhighlight %}
|
||||
|
||||
Check out the [Jekyll docs][jekyll] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll's GitHub repo][jekyll-gh].
|
||||
|
||||
[jekyll-gh]: https://github.com/mojombo/jekyll
|
||||
[jekyll]: http://jekyllrb.com
|
529
_posts/2013-06-01-release-announcement.markdown
Normal file
529
_posts/2013-06-01-release-announcement.markdown
Normal file
|
@ -0,0 +1,529 @@
|
|||
---
|
||||
layout: post
|
||||
title: "Capistrano Version 3 Release Announcement"
|
||||
date: 2013-06-01 00:00:00
|
||||
---
|
||||
|
||||
After what seems like years of work, the Capistrano team (that's Tom and I)
|
||||
are pleased to announce the first *major* release of Capistrano in almost 5
|
||||
years.
|
||||
|
||||
The reasons behind the length of time between the last architectural overhaul
|
||||
and this one are numerous, but it can be summrised to say that Capistrano is a
|
||||
widely used tool, and when working around software deployment it's really a
|
||||
question of downtime. If we had changed something significant in Capistrano we
|
||||
could have taken a lot of sites offline, and made a lot of people very
|
||||
unhappy. Until this point we haven't felt that the time has been ripe where
|
||||
the benefits of a slightly rocky upgrade path are worth the risks of downtime.
|
||||
|
||||
It also hasn't helped historically that we've only just gotten to grips with
|
||||
Ruby 1.9, and that Bundler's near ubuquity means that now it's trivial to lock
|
||||
a Gem at a specific version. With other tools in the Ruby eco system it's
|
||||
become easier for us to make significant changes to a tool upon which many
|
||||
hundreds of thousands of people rely.
|
||||
|
||||
### Design Goals
|
||||
|
||||
We had a few goals for this release, in no particular order they were:
|
||||
|
||||
* **Get away from our own DSL solution.** Great DSL alternatives (Rake, Sake, Thor,
|
||||
etc) are already widely used.
|
||||
* **Better modularisation.** to enable people outside the Rails community to
|
||||
benefit from Capistrano's *best-practice* workflow, and to enable people in
|
||||
the Rails community to pick and choose support for components they use
|
||||
(Database Migrations, Asset Pipeline, etc)
|
||||
* **Easier Debugging.** A lot of problems with Capistrano come from weirdness
|
||||
surrounding environmental issues around PTY vs non-TTY environments, login
|
||||
and non-login shells not to mention *environment managers* such as rvm,
|
||||
rbenv and nvm.
|
||||
* **Speed.** We know that in a lot of environments speed of deploment is a
|
||||
huge factor, since Rails introduced the *Asset Pipeline* it's not uncommon
|
||||
for a deploy that formerly took 5 seconds now takes 5 minutes. This really
|
||||
is mostly out of our control, but with improved support for parallelism,
|
||||
rolling restarts we feel confident that things are bettwe not.
|
||||
* **Applicability.** We've always maintained that Capistrano is a terrible
|
||||
tool for system provisioning, and that more often than not servers are
|
||||
better being setup with Chef, Puppet or similar, whilst we still agree with
|
||||
that, the new features in Capistrano really lend themselves to integrating
|
||||
with these kinds of tools.
|
||||
|
||||
### What's missing?
|
||||
|
||||
Before we get too carried away it's worth shortlisting the things that don't
|
||||
exist in version three, *yet*.
|
||||
|
||||
* *Run Locally.* `run_locally` was always a bit of the poor relation in the
|
||||
family, it didn't quite work the same way as other things, and I never liked
|
||||
the idea that you were binding a tool that in principle should be cross
|
||||
platform (Ruby, and Capistrano) to locally executing shell commands which
|
||||
probably only work on POSIX-like operating systems. I hope that
|
||||
`run_locally` will stay gone, and that as a community we can find better
|
||||
ways of doing things that always relied on locally creating tarballs, or
|
||||
writing configuration files, or similar.
|
||||
* *SSH Gateway Support.* SSH Gateway support hasn't been implemented in
|
||||
version three yet, I hope that this will be done soon. As I have no direct
|
||||
need for it, I haven't the means to test it with a view to implementing it,
|
||||
yet.
|
||||
* *Mecurial, Subversion, and CVS Support.* These have been removed as we've
|
||||
been able to implement the Git SCM in an incredibly neat way that isn't
|
||||
compatible with the others. We wanted to break the cycle of always sticking
|
||||
with the lowest common denominator, so we are **actively** looking for
|
||||
people who are interested in contributing, or sharing expertise on the
|
||||
*best-practice* way of speedily deploying from your respective choice of
|
||||
source control.
|
||||
* *`HOSTFILTER` ,`ROLEFILTER` and friends.* These have gone away because I
|
||||
always felt they were indemic of a bad design desision about using
|
||||
Environmental Variables. These will be coming back as flags passed to `cap`
|
||||
on the CLI, and options that can be set on the Capistrano::Application Ruby
|
||||
class.
|
||||
* *Shell.* The shell has been removed temporarily pending a neater
|
||||
implementation, we've got something that we are playing with internally, but
|
||||
it needs better readline support, and some more controls around what to do
|
||||
when things go badly on some servers, but not others.
|
||||
* *Cold Deploy.* The `cap deploy:cold` is a really old legacy component,
|
||||
orignally from the days of the `script/spinner` where deploying cold
|
||||
(starting workers that weren't running), and deploying a *warm* system were
|
||||
different (restarting existing worker pools, which wasn't fun!) By and large
|
||||
these things have gone away, and it's time `deploy:cold` went away. It's
|
||||
safe in every case we could find to call setup, and seed and other Rake
|
||||
tasks without things blowing up, and that should be the approach we take.
|
||||
Tasks on the server should be idempotent, and if something is called twice,
|
||||
let it be.
|
||||
* *Coloured Output.*✝ The capistrano-colours Gem was (fairly) recently merged
|
||||
into Capistrano v2, this has gone away in favour of a IO streaming model
|
||||
inspired by MiniTest/Pride. Read more below in new features.
|
||||
|
||||
### What's new?
|
||||
|
||||
Each section here really deserves it's own sub-heading as some of the new
|
||||
features are awesome.
|
||||
|
||||
#### Rake Integration
|
||||
|
||||
We have moved away from our own DSL implemenation to implement Capistrano as a
|
||||
Rake application.
|
||||
|
||||
Rake has always supported being sub-classed, so to speak as a
|
||||
*sub-application*; it is however poorly documented. By subclassing
|
||||
Rake::Application one can specify what the *Rakefile* should look like, where
|
||||
to search for it, and how to load other *Rakefiles*.
|
||||
|
||||
The *Rake* DSL is widely used, well known and very powerful. As Rake is
|
||||
essentially a dependency resolution system, it offers a lot of nice ways to,
|
||||
for example build a tarball as a dependency of uploading it and deploying it.
|
||||
|
||||
This has allowed us to do away with the *copy* strategy all together, as it
|
||||
can now be implemented from scratch in fewer than ten lines of code. You can
|
||||
check out the [replicating the copy strategy][] screencast and acompanying
|
||||
documentation if you want to explore that any further.
|
||||
|
||||
The guiding principle is dependency resolution, and interoperability with
|
||||
other tools, for example:
|
||||
|
||||
{% highlight ruby %}
|
||||
# No description, this is an internal method
|
||||
task :notify do
|
||||
this_release_tag = sh("git describe --abbrev=0 --tags")
|
||||
last_ten_commits = sh("git log #{this_release_tag}~10..#{this_release_tag}")
|
||||
Mail.deliver do
|
||||
to "team@example.com"
|
||||
subject "Releasing #{this_release_tag} Now!"
|
||||
body last_ten_commits
|
||||
end
|
||||
end
|
||||
|
||||
namespace :deploy
|
||||
task default: :notify
|
||||
end
|
||||
{% 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
|
||||
resolve this dependency at Runtime, mailing the recent changelog to your team,
|
||||
assuming everything is setup correctly.
|
||||
|
||||
#### Built In Stage Support
|
||||
|
||||
#### Parallelism
|
||||
|
||||
In former versions of Capistrano there was a *parallel* option to run
|
||||
different tasks differently on groups of servers, it looked something like
|
||||
this:
|
||||
|
||||
{% highlight ruby %}
|
||||
task :restart do
|
||||
parallel do |session|
|
||||
session.when "in?(:app)", "/u/apps/social/script/restart-mongrel"
|
||||
session.when "in?(:web)", "/u/apps/social/script/restart-apache"
|
||||
session.else "echo nothing to do"
|
||||
end
|
||||
end
|
||||
{% 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
|
||||
couple of freelancers who were consulting with them. (Hint, one of those guys
|
||||
went on to found Travis-CI!)
|
||||
|
||||
The equivilent code in under Capistrano v3 would look like this:
|
||||
|
||||
{% highlight ruby %}
|
||||
task :restart do
|
||||
on :all, in: :parallel do |host|
|
||||
if host.roles.include?(:app)
|
||||
execute "/u/apps/social/script/restart-mongrel"
|
||||
elsif host.roles.include?(:web)
|
||||
execute "/u/apps/social/script/restart-web"
|
||||
else
|
||||
info "Nothing to do for #{host} with roles #{host.properties.roles}."
|
||||
end
|
||||
end
|
||||
end
|
||||
{% 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
|
||||
think it's clearer, more idiomatic Ruby code which relies less on an intimate
|
||||
knowledge of how the Capistrano DSL happens to work. It also hints at the
|
||||
built-in logging subsystem, keep reading to learn more.
|
||||
|
||||
Other modes for parallelism include:
|
||||
|
||||
{% highlight ruby %}
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
{% 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
|
||||
again!
|
||||
|
||||
#### Streaming IO
|
||||
|
||||
This IO streaming model means that results from commands, the commands
|
||||
themselves and any other arbitrary output are sent as objects to a class with
|
||||
an `IO`ish interface, the class knows what to do with these things. There's a
|
||||
*progress* formatter which prints dots for each command that is called, as
|
||||
well as a *pretty* formatter which prints the full command, it's output on
|
||||
standard out and standard error, as well as the final return status. It would
|
||||
be trivial to implement HTML formatters, or formatters that reported to your
|
||||
IRC room, or to email. I look forward to seeing more of these cropping up in
|
||||
the community.
|
||||
|
||||
#### Host Definition Access
|
||||
|
||||
If you didn't skim over the *Parallism* section above, you might have noticed we
|
||||
did something clever that wasn't possible in Capistrano v2; we accessed the
|
||||
`host` inside the execution block.
|
||||
|
||||
For a lot of reasons in Capistrano v2 is wasn't possible to do this, the block
|
||||
was essentially evaluated once and called verbatim on each host. This lead to
|
||||
disappointing missing features such as not being able to pull the host list
|
||||
out of Capistrano and examine the roles to do something like controlling chef
|
||||
solo, or similar.
|
||||
|
||||
In Capistrano v3 the `host` object is the same object that is created when a
|
||||
server is defined, and is internally used, for example to pass to an ERB
|
||||
template for rendering a last-deploy message that is dumped onto each server
|
||||
after a successful deployment. The last deploy log includes everything
|
||||
Capistrano knew about that server during the deployment.
|
||||
|
||||
> Users of Capistrano v2 may be familiar with the perenial `cap deploy:cleanup`
|
||||
problem which came to light when servers differed in their old releases list,
|
||||
imagine a scenario with two servers, one has been your bread-and-butter since
|
||||
you launched, it has hundreds of old releases from all your wonderful deploys
|
||||
over the months or years. The second server has been in the cluster for about
|
||||
a month, it didn't quite slot-in cleanly, so the list of old releases looks a
|
||||
bit weird, you deleted a few by hand, and anyway there might only be ten-or-so
|
||||
releases there.
|
||||
|
||||
> Now imagine that you call `cap deploy:cleanup`, old `capture()`
|
||||
implementations silently only ran on the first server that matched the
|
||||
properties defined, so server one returned a list of ~95 old timestamped
|
||||
release directories. Next Capistrano v2 would call `rm -rf
|
||||
release1..release95` on **both** servers, causing server two to err our, and
|
||||
leaving an undefined state on server one, as Capistrano would simply hang up
|
||||
both connections.
|
||||
|
||||
This cleanup routine can now be better implemented as follows (which is
|
||||
actually more or less the actual implenetation in the the new Gem):
|
||||
|
||||
{% highlight ruby %}
|
||||
desc "Cleanup all old releases (keeps #{fetch(:releases_to_keeo_on_cleanup)}
|
||||
old releases"
|
||||
task :cleanup do
|
||||
keep_releases = fetch(:releases_to_keeo_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
|
||||
{% 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
|
||||
are finished removing old releases the `task :cleanup` block will have
|
||||
finished.
|
||||
|
||||
Also in Capistrano v3 most path varaibles are [`Pathname`] objects, so they natively
|
||||
respond to things like `#basename`, `#expand_path`, `#join` and similar.
|
||||
|
||||
**Warning:** `#expand_path` probably won't do what you expect, it will execute
|
||||
on your *workstation* machine, and not on the remote host, so it's possible
|
||||
that it will return an error in the case of paths which exist remotely but not
|
||||
locally.
|
||||
|
||||
#### Host Properties
|
||||
|
||||
As the `host` object is now available to the task blocks, it made sense to make
|
||||
it possible to store arbitrarty values against them.
|
||||
|
||||
Enter `host.properties`. This is a simple [*OpenStruct*][] which can be used to
|
||||
store any additional properties which are important for your application.
|
||||
|
||||
An example of it's usage might be:
|
||||
|
||||
{% highlight ruby %}
|
||||
h = SSHKit::Host.new 'example.com'
|
||||
h.properties.roles ||= %i{wep app}
|
||||
{% endhighlight %}
|
||||
|
||||
#### More Expressive Command Language
|
||||
|
||||
In Capistrano v2, it wasn't uncommon to find commands such as:
|
||||
|
||||
{% highlight ruby %}
|
||||
task :precompile, :roles => lambda { assets_role }, :except => { :no_release => true } do
|
||||
run <<-CMD.compact
|
||||
cd -- #{latest_release} &&
|
||||
RAILS_ENV=#{rails_env.to_s.shellescape} #{asset_env} #{rake} assets:precompile
|
||||
CMD
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
In Capistrano v3 this looks more like this:
|
||||
|
||||
{% highlight ruby %}
|
||||
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, 'assets:precompile'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
{% 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
|
||||
you, environmental variables are capitalised and applied at the correct point
|
||||
(i.e between the `cd` and `rake` calls in this case).
|
||||
|
||||
Other options here include `as :a_user` and
|
||||
|
||||
#### Better *magic* Variable Support
|
||||
|
||||
In Capistrano v2 there were certain bits of magic where if calling a variable
|
||||
and NoMethodError would have been raised (for example the
|
||||
`latest_release_directory` varaible). This variable never existed on the
|
||||
global namespace, as a fall-back the list of `set()` variables would be
|
||||
consulted.
|
||||
|
||||
This magic lead to times when people were not recognising that magic variables
|
||||
were even being used. The magic variable system of Capistrano v2 did also
|
||||
include a way to `fetch(:some_variable, 'with a default value')` incase the
|
||||
variable might not be set already, but it wasn't widely used, and more often
|
||||
than not people just used things like `latest_release_directory` never knowing
|
||||
that behind the scenes an exception was raised, then rescued, and that
|
||||
`:latest_release_directory` in the variable map was actually a continuation
|
||||
that was evaluated the first time it was used, and the value then cached until
|
||||
the end of the script.
|
||||
|
||||
The system has now 100% less magic. If you set a variable using `set()`, it
|
||||
can be fetched with `fetch()`, if the value you set into the variable responds
|
||||
to `#call` then it will be executed in the current context whenever it is
|
||||
used, the values will not be cached, unless your continuation does some
|
||||
explicit caching. *Again, we are favoring clarity over micro optimisation*.
|
||||
|
||||
#### SSHKit
|
||||
|
||||
Many of the new features in Capistrano whch relate to logging, formatting,
|
||||
SSH, connection management and pooling, parallism, batch execution and more
|
||||
are from a library that fell out of the Capistrano v3 development process.
|
||||
|
||||
[*SSHKit*][] is a lower level toolkit, a level higher than *Net::SSH*, still
|
||||
but lacking the roles, environments, rollbacks and other higher level features
|
||||
from Capistrano.
|
||||
|
||||
SSHkit is ideal for use if you need to just connect to a machine and run some
|
||||
arbitrary command, for example:
|
||||
|
||||
{% highlight ruby %}
|
||||
# Rakefile
|
||||
require 'sshkit'
|
||||
desc "Check the uptime of example.com"
|
||||
task :uptime do |h|
|
||||
execute :uptime
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
There is much more than can be done with SSHKit, and we have quite an
|
||||
extensive [list of examples][]. For the most part with Capistrano v3, anything
|
||||
that happens inside of an `on()` block is happening in SSHkit, and the
|
||||
documentation from that library is the place to go to find more information.
|
||||
|
||||
#### Command Mapping
|
||||
|
||||
This is another feature from SSHKit, designed to remove a little ambiguity
|
||||
from preceedings, there is a so-called command map for commands.
|
||||
|
||||
When executing something like:
|
||||
|
||||
{% highlight ruby %}
|
||||
execute "git clone ........ ......."
|
||||
{% 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
|
||||
environmental variables. **This is by design.** This feature is designed to
|
||||
allow people to write non-trivial commands in [heredocs][] when the need
|
||||
arises.
|
||||
|
||||
The idiomatic way to write that command in Capistrano v3 is to use the
|
||||
separated variadaric method to specify the command:
|
||||
|
||||
{% highlight ruby %}
|
||||
execute :git, :clone, "........", "......."
|
||||
{% 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
|
||||
`git` ) are mapped to `/usr/bin/env ...`. Meaning that this command would be
|
||||
expanded to `/usr/bin/env git clone ...... ......` which is what happens when
|
||||
`git` is called without a full path, the `env` program is consulted (perhaps
|
||||
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:
|
||||
|
||||
{% highlight ruby %}
|
||||
SSHKit.config.command_map[:rake] = "bundle exec rake"
|
||||
SSHKit.config.command_map[:rails] = "bundle exec rails"
|
||||
{% endhighlight %}
|
||||
|
||||
There can also be a lamda or Proc applied in place of the mapping like so:
|
||||
|
||||
{% 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}"
|
||||
else
|
||||
hash[key] = "/usr/bin/env #{key}"
|
||||
end
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
Between these two options there should be quite powerful options to map
|
||||
commands in your environment without having to override internal tasks from
|
||||
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*:
|
||||
|
||||
{% 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}"
|
||||
else
|
||||
hash[key] = "/usr/bin/env #{key}"
|
||||
end
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
The above assumes that you have done something like `rbenv wrapper default
|
||||
myproject` which creates wrapper binaries which correctly set up the Ruby
|
||||
environment without requiring an interactive login shell.
|
||||
|
||||
#### Testing
|
||||
|
||||
The old test suite for Capistrano was purely unit tests, and didn't cover a
|
||||
wide varity of problem cases, specifically nothing in the `deploy.rb` (that is
|
||||
the actual *deployment* code) was tested at all; because of having our own DSL
|
||||
implementation, and other slightly odd design points, it was painful to test
|
||||
the actual *recipes*.
|
||||
|
||||
Testing has been a focus of Capistrano v3. The *integration* test suite uses
|
||||
Vagrant to boot a machine, configures certain scenarios using portable shell
|
||||
script, and then executes commands against them, deploying common
|
||||
configurations to typical Linux systems. This is slow to execute, but offers
|
||||
stronger guarantees that nothing is broken that we've ever been able to give
|
||||
before.
|
||||
|
||||
Capistrano v3 also offers a possibility to swap out backend implementations.
|
||||
This is interesting because for the purpose of testing your *own* recipes you
|
||||
can use a *printer* backend, and verify that the output matched what you
|
||||
expected, or use a stubbed backend upon which you can verify that calls were
|
||||
made, or not made as expected.
|
||||
|
||||
#### Arbitrary Logging
|
||||
|
||||
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:
|
||||
|
||||
{% highlight ruby %}
|
||||
on hosts do |host|
|
||||
f = '/some/file'
|
||||
if test("[ -d #{f} ]")
|
||||
execute :touch, f
|
||||
else
|
||||
info "#{f} already exists on #{host}!"
|
||||
end
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
### Upgrading
|
||||
|
||||
The best place to go here is the [upgrading documentation][] to get deeper
|
||||
into the specifics.
|
||||
|
||||
The simple version is to say that there is *no **direct** upgrade path*,
|
||||
versions two and three are incompatible.
|
||||
|
||||
This is partly by design, the old DSL was imprecise in places that would have
|
||||
made doing the right thing in most cases tricky, we opted to invest in more
|
||||
features and better reliability than investing in keeping a backwards
|
||||
compatible API.
|
||||
|
||||
There are a number of *gotchas* listed below, but the main points are the new
|
||||
names of the built-in roles, as well as that by default Capistrano v3 is
|
||||
platform agnostic, if you need Rails support, for migrations, asset pipeline
|
||||
and such like, then it's required to `require` the support files.
|
||||
|
||||
### Gotchas
|
||||
|
||||
#### Rake DSL Is Additive
|
||||
|
||||
In Capistrano v2 if you re-define a task then it replaces the original
|
||||
implemetation, this has been used by people to replace internal tasks
|
||||
piecemeal with their own implementations
|
||||
|
||||
#### `sudo` Behaviour
|
4
changes.html
Normal file
4
changes.html
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
layout: default
|
||||
title: "Recent Site Changes"
|
||||
---
|
66
css/capistrano.css
Normal file
66
css/capistrano.css
Normal file
|
@ -0,0 +1,66 @@
|
|||
a {
|
||||
text-decoration: none;
|
||||
color: #52C1DB;
|
||||
}
|
||||
|
||||
body, p, a {
|
||||
font-family: 'Open-Sans', sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
p, h1, h2, h3, h4, h5, h6 {
|
||||
color: #1C1B39;
|
||||
}
|
||||
|
||||
.header {
|
||||
height: 195px;
|
||||
background-color: #1C1B39;
|
||||
background-image: url('/images/CapistranoGraphicWireframe.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 275px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.header a {
|
||||
color: #52C1DB;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 1.3em 0 1em;
|
||||
padding: 1.3em;
|
||||
}
|
||||
|
||||
code, kbd, pre, samp {
|
||||
font-family: 'droid-sans-mono', monospace, serif;
|
||||
background-color: rgb(250, 250, 250);
|
||||
}
|
||||
|
||||
.header a.brand img {
|
||||
margin: 6.5em auto auto 7em;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5 h6 {
|
||||
font-family: 'Enriqueta', serif;
|
||||
}
|
||||
|
||||
.post-date {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 36pt;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 18pt;
|
||||
}
|
||||
|
||||
.nav.nav-list {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin: 1.3em 0 1em;
|
||||
padding: 1.3em;
|
||||
}
|
60
css/syntax.css
Normal file
60
css/syntax.css
Normal file
|
@ -0,0 +1,60 @@
|
|||
.highlight { background: #ffffff; }
|
||||
.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 */
|
86
documentation/getting-started/installation/index.markdown
Normal file
86
documentation/getting-started/installation/index.markdown
Normal file
|
@ -0,0 +1,86 @@
|
|||
---
|
||||
title: Installation
|
||||
layout: default
|
||||
---
|
||||
|
||||
Capistrano is bundled as a Ruby Gem. **It requires Ruby 1.9 or newer.**
|
||||
|
||||
Capistrano can be installed as a standalone Gem, or bundled into your
|
||||
application.
|
||||
|
||||
<div class="alert">
|
||||
It is recommended to fix the version number when using Capistrano, and is
|
||||
therefore recommended to use an appropriate bundler.
|
||||
</div>
|
||||
|
||||
### General Usage
|
||||
|
||||
The following commands will clone Capistrano at the latest `v3` revision, and
|
||||
will build the gem and install it locally. **The Gem is not yet availalble via
|
||||
Rubygems.org.**
|
||||
|
||||
{% highlight bash %}
|
||||
$ git clone -b v3 https://github.com/capistrano/capistrano.git
|
||||
$ cd capistrano
|
||||
$ gem build *.gemspec
|
||||
$ gem install *.gem
|
||||
{% endhighlight %}
|
||||
|
||||
### Usage in a Rails project
|
||||
|
||||
Add the following lines to the Gemfile, to the group `:development` ideally.
|
||||
|
||||
{% highlight ruby %}
|
||||
group :development do
|
||||
gem 'capistrano-rails', github: 'capistrano/capistrano-rails', branch: 'v3'
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
There will be a Gem released via [rubygems.org][rubygems], but as most people
|
||||
are still using Capistrano v2.x, the v3 release will not be pushed to
|
||||
[rubygems.org][rubygems] just yet give people a chance to lock their version
|
||||
in their `Gemfile`.
|
||||
|
||||
The *Capistrano-Rails* Gem includes extras specifically designed for Ruby on
|
||||
Rails, specifically:
|
||||
|
||||
* Asset Pipeline Support
|
||||
* Gem Bundler 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` these
|
||||
files:
|
||||
|
||||
{% highlight ruby %}
|
||||
require 'capistrano/rails/assets'
|
||||
require 'capistrano/rails/gem-bundler'
|
||||
require 'capistrano/rails/database-migrations'
|
||||
{% endhighlight %}
|
||||
|
||||
<div class="alert alert-info">
|
||||
<h5>Help! I was using Capistrano `v2.x` and I didn't want to upgrade!</h5>
|
||||
|
||||
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:
|
||||
|
||||
{% highlight ruby %}
|
||||
gem 'capistrano', '~> 2.15' # Or whatever patch release you are using
|
||||
{% endhighlight %}
|
||||
|
||||
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>
|
||||
|
||||
--
|
||||
[rubygems]: http://rubygems.org/
|
||||
[rubygems-pessimistic-operator]: http://docs.rubygems.org/read/chapter/16#page74
|
||||
[capistrano-rails-asset-pipeline-readme]: https://www.github.com/capistrano/asset-pipeline/bundler/README.md
|
||||
[capistrano-rails-database-migrations-readme]: https://www.github.com/capistrano/migrations/bundler/README.md
|
||||
[capistrano-rails-gem-bundler-readme]: https://www.github.com/capistrano/capistrano-rails/bundler/README.md
|
1
documentation/index.html
Normal file
1
documentation/index.html
Normal file
|
@ -0,0 +1 @@
|
|||
FUCK YOU JEKYLL
|
|
@ -0,0 +1,38 @@
|
|||
---
|
||||
title: Introductory Demo Video
|
||||
layout: default
|
||||
---
|
||||
|
||||
The video below was filmed on Mac OSX 10.8 using a more-or-less standard shell
|
||||
without much previous setup.
|
||||
|
||||
It covers using Capistrano to install an example Rails project on a previously
|
||||
unprepared server, covering all aspects of Github access, as well as
|
||||
privisioning the server using *Chef Solo* and Capistrano with *Rake*.
|
||||
|
||||
|
||||
|
||||
#### Show Notes
|
||||
|
||||
The *Chef Solo* recipes can be reached at [this repository at
|
||||
Github][capistrano-chef-solo-example-recipes], they rely on a fairly new
|
||||
version of *Chef Solo*, spefically any including the results of [this
|
||||
ticket][chef-issue-3365]. The aforementioned *Chef* issue adds environment
|
||||
support to *Chef Solo*.
|
||||
|
||||
The provisioning can also be done using any other mechanism, it's generally
|
||||
accepted however that there's not much point in automising your deploys,
|
||||
unless you are also automating provisioning of your servers for a known,
|
||||
consistent state.
|
||||
|
||||
Using `sudo` with any deployment can be tricky, so it's better to avoid it.
|
||||
Rebooting services without `sudo` is typically the first place people run into
|
||||
trouble using Capistrano. The [trouble shooting page for `sudo`
|
||||
problems][troubleshooting-sudo-password] may help.
|
||||
|
||||
**Note:** Some long sequences have been shortened (nobody needs to sit and watch me
|
||||
sitting and watching Ruby compile, for example!)
|
||||
|
||||
--
|
||||
[chef-issue-3365]: https://github.com/opscode/chef/pull/359
|
||||
[troubleshooting-sudo-password]: /troubleshooting/sudo-password/
|
5
documentation/upgrading/index.html
Normal file
5
documentation/upgrading/index.html
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: "Upgrading from v2.x.x"
|
||||
---
|
||||
|
||||
Lorem Ipsum
|
BIN
images/CapistranoAvatar.png
Normal file
BIN
images/CapistranoAvatar.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9 KiB |
BIN
images/CapistranoGraphic.png
Normal file
BIN
images/CapistranoGraphic.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
BIN
images/CapistranoGraphicWireframe.png
Normal file
BIN
images/CapistranoGraphicWireframe.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 65 KiB |
BIN
images/CapistranoLogo.png
Normal file
BIN
images/CapistranoLogo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.6 KiB |
35
index.markdown
Normal file
35
index.markdown
Normal file
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
layout: default
|
||||
title: A remote server automation and deployment tool written in Ruby.
|
||||
---
|
||||
|
||||
### A Simple Task
|
||||
|
||||
{% highlight ruby %}
|
||||
role :demo, %{example.com example.org, example.net}
|
||||
task :uptime do |host|
|
||||
on :demo, in: :parallel do
|
||||
uptime = capture(:uptime)
|
||||
puts "#{host.hostname} reports: #{uptime}"
|
||||
end
|
||||
end
|
||||
{% endhighlight %}
|
||||
|
||||
Capistrano extends the *Rake* DSL with methods specific to running commands
|
||||
`on()` servers.
|
||||
|
||||
### For Any Language
|
||||
|
||||
Capistrano is written in Ruby, but it can easily be used to deploy any
|
||||
language. Popular extensions add support for *Wordpress* blogs as well as
|
||||
*Symfony* and *Node.js* applications.
|
||||
|
||||
If your language has special deployment requirements, Capistrano can easily be
|
||||
extended to support them.
|
||||
|
||||
### Demo Video
|
||||
|
||||
<video id="demo" class="video-js vjs-default-skin" controls preload="auto" width="640" height="400" data-setup="{}">
|
||||
<source src="http://capistrano-screencasts.s3.amazonaws.com/Capistrano%20Introduction%20Video.mp4" type='video/mp4'>
|
||||
</video>
|
||||
|
Loading…
Reference in a new issue