Capistrano
Install
on ubuntu 14, just sudo apt-get install capistrano
Setup Target Server
setup a deploy
user:
sudo adduser deploy
sudo adduser deploy sudo
su deploy
then ssh-copy-id deploy@remote-host
to setup ssh connection
Structure
root path is defined by :deploy_to
, then structure is like this:
├── current -> /var/www/my_app_name/releases/20150120114500/
├── releases
│ ├── 20150080072500
│ ├── 20150090083000
│ ├── 20150100093500
│ ├── 20150110104000
│ └── 20150120114500
├── repo
│ └── <VCS related data>
├── revisions.log
└── shared
└── <linked_files and linked_dirs>
Configuration
variables can be either global or stage:
- global:
config/deploy.rb
- stage:
config/deploy/<stage_name>.rb
set variable
set :application, 'value'
# or lambda
set :application, -> { "SomeThing_#{fetch :other_config}" }
get variable
fetch :application
fetch(:special_thing, 'some_default_value')
see here for list of pre-defined variables.
Initialize
$ cd my-project
$ capify .
looks like this:
├── Capfile
├── config
│ ├── deploy
│ │ ├── production.rb
│ │ └── staging.rb
│ └── deploy.rb
└── lib
└── capistrano
└── tasks
Capfile
will automatically include any tasks from *.rake
files in lib/capistrano/tasks
.
configuration
create a config/deploy/staging.rb
Capistrano breaks down common tasks into a notion of roles, for example web
, app
, and db
.
set :stage, :staging
# ==================
Supports bulk-adding hosts to roles, the primary
server in each group is considered to be the first
unless any hosts have the primary property set.
role :app, %w{example.com} role :web, %w{example.com} role :db, %w{example.com}# Extended Server Syntax
# ======================
# This can be used to drop a more detailed server
# definition into the server list. The second argument
# is something that quacks like a hash and can be used
# to set extended properties on the server.
server 'example.com', roles: %w{web app}, my_property: :my_value
Servers can be defined in two ways, implicitly using the simple role
syntax and explicitly using the extended server
syntax.
for more specific ssh parameters:
# using simple syntax
role :web, %w{hello@world.com example.com:1234}
# using extended syntax (which is equivalent)
server 'world.com', roles: [:web], user: 'hello'
server 'example.com', roles: [:web], port: 1234
The deploy.rb
is a place where the configuration common to each environment can be specified, normally the repository URL and the user as whom to deploy are specified here.
set :application, 'rails3-bootstrap-devise-cancan-demo'
set :repo_url, 'https://github.com/capistrano/rails3-bootstrap-devise-cancan'
set :branch, 'master'
Tasks
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
local tasks
replace on
with run_locally
:
desc 'Notify service of deployment'
task :notify do
run_locally do
with rails_env: :development do
rake 'service:notify'
end
end
end
Before / After Hooks
# 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
other way to call other tasks is to use invoke()
:
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