DEPLOY MADE EASY
(even on Friday)
Riccardo Bini
@odracci
In the beginning
F
A
I
L
DEPLOYTOOLS
• Idephix
• puppet
• fabric
CAPISTRANO
Capistrano is an open source tool for running scripts on
multiple servers; its main use is deploying web applications. It
automates the process of making a new version of an
application available on one or more web servers, including
supporting tasks such as changing databases.
http://en.wikipedia.org/wiki/Capistrano
WHY?
One-click deploy
Deploy in transaction
Rollback
Automated tasks (minifing CSS/JS, DB migrations)
RECIPES
Capifony http://capifony.org
Railsless-deploy https://github.com/leehambley/railsless-deploy
Multistage https://github.com/capistrano/capistrano/wiki/2.x-Multistage-Extension
`-- /var/www/my-app.com
|-- current ! /var/www/my-app.com/releases/20131004131539
|-- releases
| `-- 20131004131539
| `-- 20131004150741
| `-- 20131004145325
`-- shared
|-- web
| `-- uploads
`-- config
`-- config.php
HOW IT WORKS
HOW IT WORKS
ssh to the server (my-app.com)
• create a new release path (/var/www/my-app.com/releases/...)
• pull the latest project version from the remote git repo
• copy the source code, pulled from git, into the release path
http://capifony.org
HOW IT WORKS
$ capify .
[add] writing './Capfile'
[add] making directory './config'
[add] writing './config/deploy.rb'
[done] capified!
SETUP
$ cap deploy:setup
# to deploy: cap -S branch=<branchname> deploy
set :application, "set your application name here"
set :repository, "git@github.com:odracci/#{application}.git"
set :scm, :git
server "my-app.com", :app, :web, :db, :primary => true
set :deploy_to, "/var/www/my-app.com"
set :branch, fetch(:branch, "master")
set :shared_children, ["web/uploads", "config"]
set :user, "vagrant"
set :group_writable, true
set :use_sudo, false
set :copy_exclude, [".git"]
set :deploy_via, :remote_cache
set :keep_releases, 5
ssh_options[:forward_agent] = true
default_run_options[:pty] = true
logger.level = Logger::MAX_LEVEL
# if you want to clean up old releases on each deploy uncomment this:
after "deploy:restart", "deploy:cleanup"
config/deploy.rb
$ cap <env> deploy
server "www.my-app.com", :app, :web, :db, :primary => true
set :deploy_to, "/var/www/my-app.com"
set :branch, fetch(:branch, "master")
MULTISTAGE
server "s.my-app.com", :app, :web, :db, :primary => true
set :deploy_to, "/var/www/my-app.com"
set :branch, fetch(:branch, "develop")
config/deploy/production.rb
config/deploy/staging.rb
command line
cap deploy # Deploys your project.
cap deploy:check # Test deployment dependencies.
cap deploy:cleanup # Clean up old releases.
cap deploy:cold # Deploys and starts a `cold' application.
cap deploy:create_symlink # Updates the symlink to the most recently deployed...
cap deploy:migrate # Run the migrate rake task.
cap deploy:migrations # Deploy and run pending migrations.
cap deploy:pending # Displays the commits since your last deploy.
cap deploy:pending:diff # Displays the `diff' since your last deploy.
cap deploy:restart # Blank task exists as a hook into which to install...
cap deploy:rollback # Rolls back to a previous version and restarts.
cap deploy:rollback:code # Rolls back to the previously deployed version.
cap deploy:setup # Prepares one or more servers for deployment.
cap deploy:start # Blank task exists as a hook into which to install...
cap deploy:stop # Blank task exists as a hook into which to install...
cap deploy:symlink # Deprecated API.
cap deploy:update # Copies your project and updates the symlink.
cap deploy:update_code # Copies your project to the remote servers.
cap deploy:upload # Copy files to the currently deployed version.
cap invoke # Invoke a single command on the remote servers.
cap shell # Begin an interactive Capistrano session.
cap -T
namespace :deploy do
task :start do
end
task :stop do
end
task :restart, :roles => :app, :except => { :no_release => true } do
run "sudo /etc/init.d/httpd restart"
end
end
OverrideTasks
namespace :config do
desc "Upload config/config.php to remote server"
task :to_remote do
upload("config/config.php", "#{shared_path}/config/config.php", :via => :scp)
end
end
$ cap config:to_remote
CustomTasks
WTF
[my-app.com] executing command
** [my-app.com :: out] Permission denied (publickey).
** [my-app.com :: out]
** [my-app.com :: out] fatal: The remote end hung up unexpectedly
** [my-app.com :: out]
command finished in 2769ms
*** [deploy:update_code] rolling back
WTF
$ ssh-add
namespace :deploy do
	 desc 'Show deployed revision'
	 task :revision, :roles => :app do
	 	 run "#{try_sudo} cat #{current_path}/REVISION"
	 end
end
WTF
$ cap deploy:revision
#server "server1, :app, :web, :db, :primary => true
role :app, "server1", "server2"
role :web, "server1", "server2"
role :db, "dbserver", :primary => true
SCALING WEB APPS
$ cap deploy:setup
THANKS
Riccardo Bini
@odracci
github.com/odracci
QUESTIONS?

Deploy made easy (even on Friday)

  • 1.
    DEPLOY MADE EASY (evenon Friday) Riccardo Bini @odracci
  • 2.
  • 4.
  • 5.
  • 6.
    CAPISTRANO Capistrano is anopen source tool for running scripts on multiple servers; its main use is deploying web applications. It automates the process of making a new version of an application available on one or more web servers, including supporting tasks such as changing databases. http://en.wikipedia.org/wiki/Capistrano
  • 7.
    WHY? One-click deploy Deploy intransaction Rollback Automated tasks (minifing CSS/JS, DB migrations)
  • 8.
  • 9.
    `-- /var/www/my-app.com |-- current! /var/www/my-app.com/releases/20131004131539 |-- releases | `-- 20131004131539 | `-- 20131004150741 | `-- 20131004145325 `-- shared |-- web | `-- uploads `-- config `-- config.php HOW IT WORKS
  • 10.
    HOW IT WORKS sshto the server (my-app.com) • create a new release path (/var/www/my-app.com/releases/...) • pull the latest project version from the remote git repo • copy the source code, pulled from git, into the release path http://capifony.org
  • 11.
  • 12.
    $ capify . [add]writing './Capfile' [add] making directory './config' [add] writing './config/deploy.rb' [done] capified! SETUP $ cap deploy:setup
  • 13.
    # to deploy:cap -S branch=<branchname> deploy set :application, "set your application name here" set :repository, "git@github.com:odracci/#{application}.git" set :scm, :git server "my-app.com", :app, :web, :db, :primary => true set :deploy_to, "/var/www/my-app.com" set :branch, fetch(:branch, "master") set :shared_children, ["web/uploads", "config"] set :user, "vagrant" set :group_writable, true set :use_sudo, false set :copy_exclude, [".git"] set :deploy_via, :remote_cache set :keep_releases, 5 ssh_options[:forward_agent] = true default_run_options[:pty] = true logger.level = Logger::MAX_LEVEL # if you want to clean up old releases on each deploy uncomment this: after "deploy:restart", "deploy:cleanup" config/deploy.rb
  • 14.
    $ cap <env>deploy server "www.my-app.com", :app, :web, :db, :primary => true set :deploy_to, "/var/www/my-app.com" set :branch, fetch(:branch, "master") MULTISTAGE server "s.my-app.com", :app, :web, :db, :primary => true set :deploy_to, "/var/www/my-app.com" set :branch, fetch(:branch, "develop") config/deploy/production.rb config/deploy/staging.rb command line
  • 15.
    cap deploy #Deploys your project. cap deploy:check # Test deployment dependencies. cap deploy:cleanup # Clean up old releases. cap deploy:cold # Deploys and starts a `cold' application. cap deploy:create_symlink # Updates the symlink to the most recently deployed... cap deploy:migrate # Run the migrate rake task. cap deploy:migrations # Deploy and run pending migrations. cap deploy:pending # Displays the commits since your last deploy. cap deploy:pending:diff # Displays the `diff' since your last deploy. cap deploy:restart # Blank task exists as a hook into which to install... cap deploy:rollback # Rolls back to a previous version and restarts. cap deploy:rollback:code # Rolls back to the previously deployed version. cap deploy:setup # Prepares one or more servers for deployment. cap deploy:start # Blank task exists as a hook into which to install... cap deploy:stop # Blank task exists as a hook into which to install... cap deploy:symlink # Deprecated API. cap deploy:update # Copies your project and updates the symlink. cap deploy:update_code # Copies your project to the remote servers. cap deploy:upload # Copy files to the currently deployed version. cap invoke # Invoke a single command on the remote servers. cap shell # Begin an interactive Capistrano session. cap -T
  • 16.
    namespace :deploy do task:start do end task :stop do end task :restart, :roles => :app, :except => { :no_release => true } do run "sudo /etc/init.d/httpd restart" end end OverrideTasks
  • 17.
    namespace :config do desc"Upload config/config.php to remote server" task :to_remote do upload("config/config.php", "#{shared_path}/config/config.php", :via => :scp) end end $ cap config:to_remote CustomTasks
  • 18.
  • 19.
    [my-app.com] executing command **[my-app.com :: out] Permission denied (publickey). ** [my-app.com :: out] ** [my-app.com :: out] fatal: The remote end hung up unexpectedly ** [my-app.com :: out] command finished in 2769ms *** [deploy:update_code] rolling back WTF $ ssh-add
  • 20.
    namespace :deploy do desc 'Show deployed revision' task :revision, :roles => :app do run "#{try_sudo} cat #{current_path}/REVISION" end end WTF $ cap deploy:revision
  • 21.
    #server "server1, :app,:web, :db, :primary => true role :app, "server1", "server2" role :web, "server1", "server2" role :db, "dbserver", :primary => true SCALING WEB APPS $ cap deploy:setup
  • 22.
  • 23.