2014-06-07 13:44:15 -04:00
# Capistrano [![Build Status](https://travis-ci.org/capistrano/capistrano.svg?branch=master)](https://travis-ci.org/capistrano/capistrano) [![Code Climate](http://img.shields.io/codeclimate/github/capistrano/capistrano.svg)](https://codeclimate.com/github/capistrano/capistrano) <a href="http://codersclan.net/?repo_id=325&source=small"><img src="http://img.shields.io/badge/get-support-blue.svg"></a>
2013-02-01 04:19:14 -05:00
2013-06-07 11:45:39 -04:00
## Requirements
2013-06-30 11:37:17 -04:00
* Ruby >= 1.9 (JRuby and C-Ruby/YARV are supported)
2013-06-07 11:45:39 -04:00
2014-01-14 15:09:59 -05:00
## Support
2014-01-14 14:58:26 -05:00
2014-03-02 19:05:48 -05:00
Need help with getting Capistrano up and running? Got a code problem you want to get solved quickly?
2014-01-14 14:58:26 -05:00
2014-01-19 12:57:51 -05:00
Get < a href = "http://codersclan.net/?repo_id=325&source=link" > Capistrano support on CodersClan.< / a >
2014-01-14 14:58:26 -05:00
2014-01-19 12:57:51 -05:00
< a href = "http://codersclan.net/?repo_id=325&source=big" > < img src = "http://www.codersclan.net/gs_button/?repo_id=325" width = "200" > < / a >
2014-01-14 14:58:26 -05:00
2013-02-01 04:19:14 -05:00
## Installation
Add this line to your application's Gemfile:
2013-05-28 13:00:13 -04:00
``` ruby
2014-04-16 03:13:31 -04:00
gem 'capistrano', '~> 3.2.0'
2013-05-28 13:00:13 -04:00
```
2013-02-01 04:19:14 -05:00
And then execute:
2013-10-11 20:38:38 -04:00
``` sh
2013-10-22 02:50:45 -04:00
$ bundle install
2013-05-28 13:00:13 -04:00
```
2013-02-01 04:19:14 -05:00
2013-02-01 09:41:51 -05:00
Capify:
2013-10-08 04:37:25 -04:00
*make sure there's no "Capfile" or "capfile" present*
2013-10-11 20:38:38 -04:00
``` sh
2013-10-22 02:50:45 -04:00
$ bundle exec cap install
2013-05-28 13:00:13 -04:00
```
2013-02-08 06:15:27 -05:00
This creates the following files:
2013-05-28 13:00:13 -04:00
```
├── Capfile
├── config
│ ├── deploy
│ │ ├── production.rb
│ │ └── staging.rb
│ └── deploy.rb
└── lib
└── capistrano
└── tasks
```
2013-02-08 06:15:27 -05:00
To create different stages:
2013-10-11 20:38:38 -04:00
``` sh
2013-10-22 02:50:45 -04:00
$ bundle exec cap install STAGES=local,sandbox,qa,production
2013-05-28 13:00:13 -04:00
```
2013-02-01 04:19:14 -05:00
2013-02-01 09:41:51 -05:00
## Usage
2013-02-01 04:19:14 -05:00
2013-10-11 20:38:38 -04:00
``` sh
2014-04-21 18:47:32 -04:00
$ bundle exec cap -T
2013-03-10 16:43:39 -04:00
2013-10-22 02:50:45 -04:00
$ bundle exec cap staging deploy
$ bundle exec cap production deploy
2013-03-15 07:35:49 -04:00
2013-10-22 02:50:45 -04:00
$ bundle exec cap production deploy --dry-run
$ bundle exec cap production deploy --prereqs
$ bundle exec cap production deploy --trace
2013-05-28 13:00:13 -04:00
```
2013-03-15 07:35:49 -04:00
2013-05-28 13:00:13 -04:00
## Tasks
2013-03-10 16:43:39 -04:00
2013-06-13 11:23:34 -04:00
``` ruby
server 'example.com', roles: [:web, :app]
server 'example.org', roles: [:db, :workers]
desc "Report Uptimes"
task :uptime do
on roles(:all) do |host|
2014-02-13 08:58:33 -05:00
execute :any_command, "with args", :here, "and here"
2013-11-11 14:48:55 -05:00
info "Host #{host} (#{host.roles.to_a.join(', ')}):\t#{capture(:uptime)}"
2013-06-13 11:23:34 -04:00
end
end
```
2013-02-08 04:15:10 -05:00
2014-02-13 09:46:33 -05:00
**Note**:
2014-02-13 08:58:33 -05:00
2014-02-13 09:46:33 -05:00
**tl;dr**: `execute(:bundle, :install)` and `execute('bundle install')` don't behave identically!
`execute()` has a subtle behaviour. When calling `within './directory' { execute(:bundle, :install) }` for example, the first argument to `execute()` is a *Stringish* with ** *no whitespace***. This allows the command to pass through the [SSHKit::CommandMap ](https://github.com/capistrano/sshkit#the-command-map ) which enables a number of powerful features.
2014-03-08 13:30:32 -05:00
When the first argument to `execute()` contains whitespace, for example `within './directory' { execute('bundle install') }` (or when using a heredoc), neither Capistrano, nor SSHKit can reliably predict how it should be shell escaped, and thus cannot perform any context, or command mapping, that means that the `within(){}` (as well as `with()` , `as()` , etc) have no effect. There have been a few attempts to resolve this, but we don't consider it a bug although we acknowledge that it might be a little counter intuitive.
2013-02-08 04:15:10 -05:00
## Before / After
Where calling on the same task name, executed in order of inclusion
2013-05-28 13:00:13 -04:00
``` ruby
# call an existing task
before :starting, :ensure_user
2013-02-08 04:15:10 -05:00
2013-05-28 13:00:13 -04:00
after :finishing, :notify
2013-02-08 04:15:10 -05:00
2013-05-28 13:00:13 -04:00
# or define in block
before :starting, :ensure_user do
#
end
2013-02-08 04:15:10 -05:00
2013-05-28 13:00:13 -04:00
after :finishing, :notify do
#
end
```
2013-02-08 04:15:10 -05:00
2013-11-12 14:23:26 -05:00
If it makes sense for your use case (often, that means *generating a file* )
2013-06-13 11:23:34 -04:00
the Rake prerequisite mechanism can be used:
``` ruby
desc "Create Important File"
file 'important.txt' do |t|
sh "touch #{t.name}"
end
desc "Upload Important File"
task :upload => 'important.txt' do |t|
on roles(:all) do
upload!(t.prerequisites.first, '/tmp')
end
end
```
The final way to call out to other tasks is to simply `invoke()` them:
``` ruby
2014-03-02 19:05:48 -05:00
namespace :example do
task :one do
on roles(:all) { info "One" }
end
task :two do
invoke "example:one"
on roles(:all) { info "Two" }
end
2013-06-13 11:23:34 -04:00
end
```
This method is widely used.
## Getting User Input
2013-06-13 11:34:52 -04:00
``` ruby
2013-06-13 11:23:34 -04:00
desc "Ask about breakfast"
task :breakfast do
2013-11-18 17:13:53 -05:00
ask(:breakfast, "pancakes")
2013-06-13 11:23:34 -04:00
on roles(:all) do |h|
2013-11-05 13:22:27 -05:00
execute "echo \"$(whoami) wants #{fetch(:breakfast)} for breakfast!\""
2013-06-13 11:23:34 -04:00
end
end
2013-06-13 11:34:52 -04:00
```
2013-06-13 11:23:34 -04:00
Perfect, who needs telephones.
2014-04-21 17:06:45 -04:00
When using `ask` to get user input, you can pass `echo: false` to prevent the input from being displayed:
```ruby
2014-04-27 00:35:37 -04:00
ask(:database_password, "default", echo: false)
2014-04-21 17:06:45 -04:00
```
2013-08-02 05:44:15 -04:00
2014-04-14 10:27:27 -04:00
## Using password authentication
2014-04-15 17:04:28 -04:00
Password authentication can be done via `set` and `ask` in your deploy environment file (e.g.: config/deploy/production.rb)
2014-04-14 10:27:27 -04:00
```ruby
2014-04-15 17:04:28 -04:00
set :password, ask('Server password', nil)
2014-04-14 10:27:27 -04:00
server 'server.domain.com', user: 'ssh_user_name', port: 22, password: fetch(:password), roles: %w{web app db}
```
2013-08-02 05:44:15 -04:00
## Running local tasks
Local tasks can be run by replacing `on` with `run_locally`
``` ruby
2014-01-10 17:45:20 -05:00
desc 'Notify service of deployment'
2013-08-02 05:44:15 -04:00
task :notify do
run_locally do
with rails_env: :development do
rake 'service:notify'
end
end
end
```
2014-01-10 17:45:20 -05:00
Of course, you can always just use standard ruby syntax to run things locally
``` ruby
desc 'Notify service of deployment'
task :notify do
%x('RAILS_ENV=development bundle exec rake "service:notify"')
end
```
Alternatively you could use the rake syntax
``` ruby
desc "Notify service of deployment"
task :notify do
sh 'RAILS_ENV=development bundle exec rake "service:notify"'
end
```
2013-03-08 10:55:29 -05:00
## Console
2013-06-13 11:34:52 -04:00
**Note:** Here be dragons. The console is very immature, but it's much more
cleanly architected than previous incarnations and it'll only get better from
here on in.
2013-06-13 10:26:38 -04:00
Execute arbitrary remote commands, to use this simply add
`require 'capistrano/console'` which will add the necessary tasks to your
2013-05-28 13:00:13 -04:00
environment:
2013-03-08 10:55:29 -05:00
2013-10-11 20:38:38 -04:00
``` sh
2013-10-22 02:50:45 -04:00
$ bundle exec cap staging console
2013-05-28 13:00:13 -04:00
```
2013-03-08 10:55:29 -05:00
2013-06-13 11:23:34 -04:00
Then, after setting up the server connections, this is how that might look:
2013-10-11 20:38:38 -04:00
``` sh
2013-10-22 02:50:45 -04:00
$ bundle exec cap production console
2013-06-13 11:23:34 -04:00
capistrano console - enter command to execute on production
production> uptime
INFO [94db8027] Running /usr/bin/env uptime on leehambley@example.com:22
DEBUG [94db8027] Command: /usr/bin/env uptime
DEBUG [94db8027] 17:11:17 up 50 days, 22:31, 1 user, load average: 0.02, 0.02, 0.05
INFO [94db8027] Finished in 0.435 seconds command successful.
production> who
INFO [9ce34809] Running /usr/bin/env who on leehambley@example.com:22
DEBUG [9ce34809] Command: /usr/bin/env who
DEBUG [9ce34809] leehambley pts/0 2013-06-13 17:11 (port-11262.pppoe.wtnet.de)
INFO [9ce34809] Finished in 0.420 seconds command successful.
```
## A word about PTYs
2013-11-12 14:23:26 -05:00
There is a configuration option which asks the backend driver to ask the remote host
2013-06-13 11:23:34 -04:00
to assign the connection a *pty* . A *pty* is a pseudo-terminal, which in effect means
2014-03-19 09:10:38 -04:00
*tell the backend that this is an __interactive__ session*. This is normally a bad idea.
2013-06-13 11:23:34 -04:00
Most of the differences are best explained by [this page ](https://github.com/sstephenson/rbenv/wiki/Unix-shell-initialization ) from the author of *rbenv* .
**When Capistrano makes a connection it is a *non-login* , *non-interactive* shell.
This was not an accident!**
It's often used as a band aid to cure issues related to RVM and rbenv not loading login
and shell initialisation scripts. In these scenarios RVM and rbenv are the tools at fault,
or at least they are being used incorrectly.
Whilst, especially in the case of language runtimes (Ruby, Node, Python and friends in
particular) there is a temptation to run multiple versions in parallel on a single server
and to switch between them using environmental variables, this is an anti-pattern, and
2013-11-12 14:23:26 -05:00
symptomatic of bad design (e.g. you're testing a second version of Ruby in production because
2013-07-03 07:16:59 -04:00
your company lacks the infrastructure to test this in a staging environment).
2013-06-13 11:23:34 -04:00
2013-02-08 06:15:27 -05:00
## Configuration
2013-02-08 04:15:10 -05:00
2013-06-30 11:46:43 -04:00
The following variables are settable:
2013-11-01 11:53:31 -04:00
| Variable Name | Description | Notes |
|:---------------------:|----------------------------------------------------------------------|-----------------------------------------------------------------|
2013-12-23 12:17:15 -05:00
| `:repo_url` | The URL of your scm repository (git, hg, svn) | file://, https://, ssh://, or svn+ssh:// are all supported |
| `:branch` | The branch you wish to deploy | This only has meaning for git and hg repos, to specify the branch of an svn repo, set `:repo_url` to the branch location. |
| `:scm` | The source control system used | `:git` , `:hg` , `:svn` are currently supported |
2013-11-07 10:25:25 -05:00
| `:tmp_dir` | The (optional) temp directory that will be used (default: /tmp) | if you have a shared web host, this setting may need to be set (i.e. /home/user/tmp/capistrano). |
2013-02-08 04:15:10 -05:00
2013-10-25 11:42:35 -04:00
__Support removed__ for following variables:
| Variable Name | Description | Notes |
|:---------------------:|---------------------------------------------------------------------|-----------------------------------------------------------------|
| `:copy_exclude` | The (optional) array of files and/or folders excluded from deploy | Replaced by Git's native `.gitattributes` , see [#515 ](https://github.com/capistrano/capistrano/issues/515 ) for more info. |
2014-09-14 14:53:02 -04:00
## Host and Role Filtering
Capistrano enables the declaration of servers and roles, each of which may have properties
associated with them. Tasks are then able to use these definitions in two distinct ways:
2014-09-24 23:12:14 -04:00
* To determine _configurations_ : typically by using the `roles()` , `release_roles()` and
`primary()` methods. Typically these are used outside the scope of the `on()` method.
2014-09-14 14:53:02 -04:00
2014-09-24 23:12:14 -04:00
* To _interact_ with remote hosts using the `on()` method
An example of the two would be to create a `/etc/krb5.conf' file containing the list of
available KDC's by using the list of servers returned by `roles(:kdc)` and then uploading
it to all client machines using `on(roles(:all)) do upload!(file) end`
2014-09-14 14:53:02 -04:00
A problem with this arises when _filters_ are used. Filters are designed to limit the
actual set of hosts that are used to a subset of those in the overall stage, but how
2014-09-24 23:12:14 -04:00
should that apply in the above case?
If the filter applies to both the _interaction_ and _configuration_ aspects, any configuration
files deployed will not be the same as those on the hosts excluded by the filters. This is
almost certainly not what is wanted, the filters should apply only to the _interactions_
ensuring that any configuration files deployed will be identical across the stage.
Another type of filtering is done by defining properties on servers and selecting on that
basis. An example of that is the 'no_release' property and it's use in the
`release_roles()` method. To distinguish these two types of filtering we name them:
* On-Filtering
Specified in the following ways:
* Via environment variables HOSTS and ROLES
* Via command line options `--hosts` and `--roles`
* Via the `:filter` variable set in a stage file
* Property-Filtering
These are specified by options passed to the `roles()` method (and implicitly in methods
like `release_roles()` and `primary()` )
2014-09-24 19:31:18 -04:00
To increase the utility of On-Filters they can use regular expressions:
* If the host name in a filter doesn't match `/^[-A-Za-z0-9.]+$/` (the set of valid characters
for a DNS name) then it's assumed to be a regular expression.
* Since role names are Ruby symbols they can legitimately contain any characters. To allow multiple
of them to be specified on one line we use the comma. To use a regexp for a role filter begin
and end the string with '/'. These may not contain a comma.
2014-09-24 23:12:14 -04:00
When filters are specified using comma separated lists, the final filter is the _union_ of
all of the components. However when multiple filters are declared the result is the
_intersection_.
2014-09-14 14:53:02 -04:00
2013-06-07 11:45:39 -04:00
## SSHKit
2013-06-13 11:23:34 -04:00
2013-10-22 15:00:00 -04:00
[SSHKit ](https://github.com/leehambley/sshkit ) is the driver for SSH
2013-11-12 14:23:26 -05:00
connections behind the scenes in Capistrano. Depending on how deep you dig, you
2013-06-13 11:23:34 -04:00
might run into interfaces that come directly from SSHKit (the configuration is
a good example).
2013-06-30 11:33:59 -04:00
2014-04-22 11:36:44 -04:00
## Testing
Capistrano has two test suites: an RSpec suite and a Cucumber suite. The
RSpec suite handles quick feedback unit specs. The Cucumber features are
an integration suite that uses Vagrant to deploy to a real virtual
server. In order to run the Cucumber suite you will need to install
[Vagrant ](http://www.vagrantup.com/ ) and Vagrant supported
virtualization software like
[VirtualBox ](https://www.virtualbox.org/wiki/Downloads ).
```
# To run the RSpec suite
$ rake spec
# To run the Cucumber suite
$ rake features
# To run the Cucumber suite and leave the VM running (faster for subsequent runs)
$ rake features KEEP_RUNNING=1
```
2014-03-03 21:18:49 -05:00
## License
2013-06-30 11:33:59 -04:00
2014-03-03 21:18:49 -05:00
MIT License (MIT)
2013-10-16 04:16:06 -04:00
Copyright (c) 2012-2013 Tom Clements, Lee Hambley
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.