mirror of
https://github.com/capistrano/capistrano
synced 2023-03-27 23:21:18 -04:00
cleanup readme
This commit is contained in:
parent
8c83291c2b
commit
1fe453a278
1 changed files with 31 additions and 268 deletions
299
README.md
299
README.md
|
@ -1,16 +1,26 @@
|
|||
# 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>
|
||||
|
||||
## Requirements
|
||||
## Documentation
|
||||
|
||||
* Ruby >= 1.9.3 (JRuby and C-Ruby/YARV are supported)
|
||||
Check out the [online documentation](http://capistranorb.com) of Capistrano 3 hosted via this [repository](https://github.com/capistrano/capistrano.github.io).
|
||||
|
||||
## Support
|
||||
|
||||
Need help with getting Capistrano up and running? Got a code problem you want to get solved quickly?
|
||||
|
||||
Get <a href="http://codersclan.net/?repo_id=325&source=link">Capistrano support on CodersClan.</a>
|
||||
Get <a href="http://codersclan.net/?repo_id=325&source=link">Capistrano support on CodersClan.</a> <a href="http://codersclan.net/?repo_id=325&source=big"><img src="http://www.codersclan.net/gs_button/?repo_id=325" width="150"></a>
|
||||
|
||||
<a href="http://codersclan.net/?repo_id=325&source=big"><img src="http://www.codersclan.net/gs_button/?repo_id=325" width="200"></a>
|
||||
## Requirements
|
||||
|
||||
* Ruby >= 1.9.3 (JRuby and C-Ruby/YARV are supported)
|
||||
|
||||
Capistrano support these source code version control systems out of the box:
|
||||
|
||||
* Git 1.8 or higher
|
||||
* Mercurial
|
||||
* SVN
|
||||
|
||||
Binaries for these VCS might be required on the local and/or the remote systems.
|
||||
|
||||
## Installation
|
||||
|
||||
|
@ -55,280 +65,26 @@ $ bundle exec cap install STAGES=local,sandbox,qa,production
|
|||
## Usage
|
||||
|
||||
``` sh
|
||||
# list all available tasks
|
||||
$ bundle exec cap -T
|
||||
|
||||
# deploy to the staging environment
|
||||
$ bundle exec cap staging deploy
|
||||
|
||||
# deploy to the production environment
|
||||
$ bundle exec cap production deploy
|
||||
|
||||
# simulate deploying to the production environment
|
||||
# does not actually do anything
|
||||
$ bundle exec cap production deploy --dry-run
|
||||
|
||||
# list task dependencies
|
||||
$ bundle exec cap production deploy --prereqs
|
||||
|
||||
# trace through task invocations
|
||||
$ bundle exec cap production deploy --trace
|
||||
```
|
||||
|
||||
## Tasks
|
||||
|
||||
``` ruby
|
||||
server 'example.com', roles: [:web, :app]
|
||||
server 'example.org', roles: [:db, :workers]
|
||||
desc "Report Uptimes"
|
||||
task :uptime do
|
||||
on roles(:all) do |host|
|
||||
execute :any_command, "with args", :here, "and here"
|
||||
info "Host #{host} (#{host.roles.to_a.join(', ')}):\t#{capture(:uptime)}"
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
**Note**:
|
||||
|
||||
**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.
|
||||
|
||||
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.
|
||||
## Before / After
|
||||
|
||||
Where calling on the same task name, executed in order of inclusion
|
||||
|
||||
``` ruby
|
||||
# call an existing task
|
||||
before :starting, :ensure_user
|
||||
|
||||
after :finishing, :notify
|
||||
|
||||
|
||||
# or define in block
|
||||
before :starting, :ensure_user do
|
||||
#
|
||||
end
|
||||
|
||||
after :finishing, :notify do
|
||||
#
|
||||
end
|
||||
```
|
||||
|
||||
If it makes sense for your use case (often, that means *generating a file*)
|
||||
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
|
||||
namespace :example do
|
||||
task :one do
|
||||
on roles(:all) { info "One" }
|
||||
end
|
||||
task :two do
|
||||
invoke "example:one"
|
||||
on roles(:all) { info "Two" }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
This method is widely used.
|
||||
|
||||
## Getting User Input
|
||||
|
||||
``` ruby
|
||||
desc "Ask about breakfast"
|
||||
task :breakfast do
|
||||
ask(:breakfast, "pancakes")
|
||||
on roles(:all) do |h|
|
||||
execute "echo \"$(whoami) wants #{fetch(:breakfast)} for breakfast!\""
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
Perfect, who needs telephones.
|
||||
|
||||
When using `ask` to get user input, you can pass `echo: false` to prevent the input from being displayed:
|
||||
|
||||
```ruby
|
||||
ask(:database_password, "default", echo: false)
|
||||
```
|
||||
|
||||
## Using password authentication
|
||||
|
||||
Password authentication can be done via `set` and `ask` in your deploy environment file (e.g.: config/deploy/production.rb)
|
||||
|
||||
```ruby
|
||||
set :password, ask('Server password', nil)
|
||||
server 'server.domain.com', user: 'ssh_user_name', port: 22, password: fetch(:password), roles: %w{web app db}
|
||||
```
|
||||
|
||||
## Running local tasks
|
||||
|
||||
Local tasks can be run by replacing `on` with `run_locally`
|
||||
|
||||
``` ruby
|
||||
desc 'Notify service of deployment'
|
||||
task :notify do
|
||||
run_locally do
|
||||
with rails_env: :development do
|
||||
rake 'service:notify'
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
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
|
||||
```
|
||||
## Console
|
||||
|
||||
**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.
|
||||
|
||||
Execute arbitrary remote commands, to use this simply add
|
||||
`require 'capistrano/console'` which will add the necessary tasks to your
|
||||
environment:
|
||||
|
||||
``` sh
|
||||
$ bundle exec cap staging console
|
||||
```
|
||||
|
||||
Then, after setting up the server connections, this is how that might look:
|
||||
|
||||
``` sh
|
||||
$ bundle exec cap production console
|
||||
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.
|
||||
```
|
||||
|
||||
## VCS Requirements
|
||||
|
||||
Capistano requires modern versions of Git, Mercurial and Subversion
|
||||
respectively (if you are using that particular VCS). Git requirement is at
|
||||
least version 1.8.x. Mercurial and Subversion, any modern version should
|
||||
suffice.
|
||||
|
||||
## A word about PTYs
|
||||
|
||||
There is a configuration option which asks the backend driver to ask the remote host
|
||||
to assign the connection a *pty*. A *pty* is a pseudo-terminal, which in effect means
|
||||
*tell the backend that this is an __interactive__ session*. This is normally a bad idea.
|
||||
|
||||
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
|
||||
symptomatic of bad design (e.g. you're testing a second version of Ruby in production because
|
||||
your company lacks the infrastructure to test this in a staging environment).
|
||||
|
||||
## Configuration
|
||||
|
||||
The following variables are settable:
|
||||
|
||||
| Variable Name | Description | Notes |
|
||||
|:---------------------:|----------------------------------------------------------------------|-----------------------------------------------------------------|
|
||||
| `:repo_url` | The URL of your scm repository (git, hg, svn) | file://, https://, ssh://, or svn+ssh:// are all supported |
|
||||
| `:repo_tree` | The subtree of the scm repository to deploy (git, hg) | Only implemented for git and hg repos. Extract just this tree |
|
||||
| `: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 |
|
||||
| `: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). |
|
||||
|
||||
__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. |
|
||||
|
||||
## 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:
|
||||
|
||||
* To determine _configurations_: typically by using the `roles()`, `release_roles()` and
|
||||
`primary()` methods. Typically these are used outside the scope of the `on()` method.
|
||||
|
||||
* 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`
|
||||
|
||||
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
|
||||
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()`)
|
||||
|
||||
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.
|
||||
|
||||
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_.
|
||||
|
||||
## SSHKit
|
||||
|
||||
[SSHKit](https://github.com/leehambley/sshkit) is the driver for SSH
|
||||
connections behind the scenes in Capistrano. Depending on how deep you dig, you
|
||||
might run into interfaces that come directly from SSHKit (the configuration is
|
||||
a good example).
|
||||
|
||||
## Testing
|
||||
|
||||
Capistrano has two test suites: an RSpec suite and a Cucumber suite. The
|
||||
|
@ -370,6 +126,13 @@ tty](https://github.com/capistrano/stats/blob/77c9993d3ee604520712261aa2a70c90f3
|
|||
allow us to differentiate between many members of the same team deploying the
|
||||
same project vs. many people on many projects.
|
||||
|
||||
## SSHKit
|
||||
|
||||
[SSHKit](https://github.com/leehambley/sshkit) is the driver for SSH
|
||||
connections behind the scenes in Capistrano. Depending on how deep you dig, you
|
||||
might run into interfaces that come directly from SSHKit (the configuration is
|
||||
a good example).
|
||||
|
||||
## License
|
||||
|
||||
MIT License (MIT)
|
||||
|
|
Loading…
Reference in a new issue