All notes
Capistra

Quick start

github.com: capistrano.

bundle exec cap install:

├── Capfile
├── config
│   ├── deploy
│   │   ├── production.rb
│   │   └── staging.rb
│   └── deploy.rb
└── lib
    └── capistrano
            └── tasks

# list all available tasks
bundle exec cap -T

# Install two stages: staging and production.
bundle exec cap install
# To customize the stages
bundle exec cap install STAGES=local,sandbox,qa,production

# 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

# lists all config variable before deployment tasks
bundle exec cap production deploy --print-config-variables

Code walkthrough

Version: capistrano-2.14.2

cli

Command line scripts are under lib/capistrano/cli/.

default_sysconf
# "/etc/capistrano.conf"

default_dotfile
# "/Users/i337146/.caprc"

:recipes # ["Capfile"]
:actions

:vars # Set by -s
:pre_vars # Set by -S

configuration

execution

rubydoc.info: execution.

"lib/capistrano/configuration/execution.rb".



current_task ⇒ Object
# Returns the TaskDefinition object for the currently executing task.

servers

rubyDoc.info: servers.

"lib/capistrano/configuration/servers.rb".



find_servers_for_task(task, options = {}) ⇒ Object
# Identifies all servers that the given task should be executed on.

Recipes

standard

There is also a "standard" recipe: "lib/capistrano/recipes/standard.rb", which defines tasks "invoke" and "shell":


# Note: invoke must use filters to specify the target nodes. Both role filter or host filter is OK.
cap COMMAND=uptime HOSTS=foo.capistano.test invoke
# Note: The quotes are not allowed such as: ROLES='app,web'.
cap ROLES=app,web SUDO=1 COMMAND="tail -f /var/log/messages" invoke

cap shell

deploy

lib/capistrano/recipes/deploy.rb defines tasks:
deploy:default. Only work for applications that have already been deployed once.
  deploy:update. wcfNote: use update instead of update_code!
    -- transaction
    deploy:update_code
      strategy.deploy!
      finalize_update
    -- transaction ends
  deploy:restart
deploy:cold. Used in first-time deployment.
  deploy:update
  deploy:migrate
  deploy:start

deploy:setup
deploy:upload
deploy:symlink
# rollback namespace is used internally. So is 'pending'.
rollback:revision
rollback:code

task :update do
  transaction do
    update_code
    create_symlink
  end
end

task :restart, :roles => :app, :except => { :no_release => true } do
  # Empty Task to overload with your platform specifics
end

Helper functions

lib/capistrano/configuration/namespaces.rb defines:
namespace
desc
task

lib/capistrano/configuration/roles.rb defines:
role
server

lib/capistrano/configuration/variables.rb defines:
set
unset
fetch
exists?
reset!

lib/capistrano/configuration/actions/invocation.rb defines:
parallel
invoke_command
run. Execute the given command on all servers that are the target of the current task.
  :roles, :hosts
  run("! ls /var/log/debug.*", roles: [:app, :worker])
sudo

lib/capistrano/recipes/deploy.rb defines:
try_sudo
try_runner
run_locally. logs the command then executes it locally. returns the command output as a string
with_env(name, value). Temporarily sets an environment variable, yields to a block, and restores the value when it is done.

role, server



########## role

role :db,  "db1.example.com", "db2.example.com"
role :db,  "master.example.com", :primary => true
role :app, "app1.example.com", "app2.example.com"

# You can also encode the username and port number for each host in the server string, if needed:
role :web,  "[email protected]"
role :file, "files.example.com:4144"
role :db,   "[email protected]:1234"

# Lastly, username and port number may be passed as options. Note that the options apply to all servers defined
role :web, "web2", "web3", :user => "www", :port => 2345

########## server

# An alternative way to associate servers with roles.
server "master.example.com", :web, :app

set

github.com: capistrano-2.x-docs: set.

It is the primary way of defining variables that can be accessed anywhere within a Capistrano configuration.



########## set(name, value)
set :keep_releases, 10
set :ssh_options, { :user => "bob", :port => 1234 }

########## set(name, &block)
# The block will not be evaluated immedately. The first time the variable is referenced, the block will be invoked.
# It's return value is cached, the block will not be invoked again. It's only invoked once.

x = 0
set(:demonstration) { x += 1 }

puts x             #<-- prints "0"
puts demonstration #<-- prints "1"
puts x             #<-- prints "1"
puts demonstration #<-- prints "1"
puts x             #<-- prints "1"

# Best used to input password
set(:root_password) { Capistrano::CLI.password_prompt("Root password: ") }
task :backup_database, :roles => :db do
  run "do_backup --user=root --password=#{root_password}"
end

Why we can access set variables directly in cap config? May be because of "method_missing_with_variables".

Commands

with_env

"lib/capistrano/recipes/deploy.rb": with_env(name, value) Temporarily sets an environment variable, yields to a block, and restores the value when it is done.

rubydoc.info: capistrano - with_env.