使用 Capistrano 部署總結

簡介

Capistrano 是一個 Ruby 程序,它提供高級的工具集來部署你的 Web應用到服務器上。Capistrano 允許你通過 SSH 從源代碼控制倉庫(SVN 或 Git)複製代碼到服務器,並執行如重啓 Web服務器、操作緩存、重命名文件、遷移數據庫等部署前/後的功能。利用 Capistrano一次也可部署多臺機器。

安裝 Capistrano

爲了安裝 Capistrano,你的電腦需要已安裝 Ruby 和 RubyGems。

  1. # gem list Capistrano -a -r http://ruby.taobao.org/
  2. *** REMOTE GEMS ***
  3. capistrano (3.2.1, 3.2.0, 3.1.0, 3.0.1, 3.0.0, 2.15.5, 2.15.4, 2.15.3, 2.15.2, 2.15.1, 2.15.0, 2.14.2, 2.14.1, 2.13.5, 2.12.0, 2.11.2, 2.9.0, 2.8.0, 2.7.0, 2.6.0, 2.5.21, 2.5.20, 2.5.19, 2.5.18, 2.5.17, 2.5.16, 2.5.15, 2.5.14, 2.5.13, 2.5.12, 2.5.11, 2.5.10, 2.5.9, 2.5.8, 2.5.7, 2.5.6, 2.5.5, 2.5.4, 2.5.3, 2.5.2, 2.5.1, 2.5.0, 2.4.3, 2.4.2, 2.4.1, 2.4.0, 2.3.0, 2.2.0, 2.1.0, 2.0.0, 1.4.2, 1.4.1, 1.4.0, 1.3.1, 1.3.0, 1.2.0, 1.1.0)
  4. capistrano-af83 (0.4.7, 0.4.6, 0.4.5, 0.4.4, 0.4.3, 0.4.2, 0.4.1, 0.4.0, 0.3.8, 0.3.2, 0.3.1, 0.3.0, 0.2.4, 0.2.3, 0.2.2, 0.2.1, 0.2.0, 0.1.9, 0.1.8, 0.1.7, 0.1.6, 0.1.5, 0.1.4, 0.1.3, 0.1.2, 0.1.1, 0.1.0)
  5. capistrano-akamai (0.0.1)
  6. capistrano-alice (0.0.7, 0.0.6, 0.0.5, 0.0.4, 0.0.3, 0.0.2, 0.0.1)
  7. capistrano-asgroup (0.0.1)

上面的命令列出了目前capistrano所有的版本及其相關的插件(插件還有很多,這裏我沒粘全),可以看到目前capistrano的最新版本爲3.2.1 。不過由於webistrano環境所使用的是2.6.0 。本篇還是以2.6.0的版本進行安裝和總結。

注:capistrano 3.X.X 版本和 capistrano 2.X.X之間已經發生了比較大的變化 。這有點類似於python3與python2的區別。

安裝方法:

  1. $ gem install capistrano -v 2.6.0
  2. //如果需要安裝capistrano擴展,再增加下面的操作
  3. $ gem install capistrano-ext

如果你遇到了問題或想要了解更多細節,可以參考官方的 Capistrano 入門指南,或找到使 Capistrano 工作的各種組件

注:安裝時,會自動安裝依賴包,請確認 net-ssh 的版本號爲2.7.0  ,不然執行任何deploy操作時會遇到類似如下的ssh認證報錯

  1. [deploy:update_code] exception while rolling back: Capistrano::ConnectionError, connection failed for: ... (Net::SSH::AuthenticationFailed: Authentication failed for user

具體可以參看github上的net-ssh項目的issues部分 。

創建項目

在終端中導航到你的應用根目錄,並執行以下命令:

  1. $ sudo capify .
  2. [add] writing './Capfile'
  3. [add] making directory './config'
  4. [add] writing './config/deploy.rb'
  5. [done] capified!
  6. $ tree
  7. .
  8. ├── Capfile
  9. └── config
  10. └── deploy.rb

在capistrano 3.x.x的版本中,此處已經不能使用這樣的方法創建項目,應該使用下面的操作:

  1. $ capify .
  2. --------------------------------------------------------------------------------
  3. Capistrano 3.x is incompatible with Capistrano 2.x.
  4. This command has become `cap install` in Capistrano 3.x
  5. For more information see http://www.capistranorb.com/
  6. --------------------------------------------------------------------------------
  7. $ sudo cap install
  8. mkdir -p config/deploy
  9. create config/deploy.rb
  10. create config/deploy/staging.rb
  11. create config/deploy/production.rb
  12. mkdir -p lib/capistrano/tasks
  13. Capified
  14. $ tree
  15. .
  16. ├── Capfile
  17. ├── config
  18.    ├── deploy
  19.       ├── production.rb
  20.       └── staging.rb
  21.    └── deploy.rb
  22. └── lib
  23. └── capistrano
  24. └── tasks

也不難看出,兩者的目錄結構也已經發生了一些變化。個人嘗試了下3.x.x版本,發現其功能和細節較2.x.x 做了很多優化。如果不使用古老的webistrano做web前端,建議使用新版本。由於webistrano 已經三年多沒更新(作者也已宣佈不再更新),所以不確定其與capistrano 3.x.x 的兼容性 。

創建的項目中一個特殊的 Capfile 文件,Capfile 將幫助 Capistrano 正確加載你的 deploy.rb模板,而deploy.rb文件定義了模塊、namespace、task等,在部署過程中,只需要按主機組執行相應的task即可完成相應的操作。

編寫 Capistrano模板

1、配置deploy.rb文件

以下deploy.rb
文件中一些詳細的分析

  1. require 'bundler/capistrano' #添加之後部署時會調用bundle install, 如果不需要就可以註釋掉
  2. require "capistrano/ext/multistage" #多stage部署所需
  3. set :stages, %w(development production)
  4. set :default_stage, "development"
  5. set :application, "crm_app_end" #應用名稱
  6. set :repository, "https://test.361way.com/svn/trunk"
  7. set :keep_releases, 5 #只保留5個備份
  8. set :deploy_to, "/var/www/#{application}" #部署到遠程機器的路徑
  9. set :user, "user1" #登錄部署機器的用戶名
  10. set :password, "user1" #登錄部署機器的密碼, 如果不設部署時需要輸入密碼
  11. default_run_options[:pty] = true #pty: 僞登錄設備
  12. #default_run_options[:shell] = false #Disable sh wrapping
  13. set :use_sudo, true #執行的命令中含有sudo, 如果設爲false, 用戶所有操作都有權限
  14. set :runner, "user2" #以user2用戶啓動服務
  15. set :svn_username, "xxxx"
  16. set :scm, :subversion #注意subversion前有冒號,不能少
  17. # Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`
  18. #set :deploy_via, :copy #如果SCM設爲空, 也可通過直接copy本地repo部署
  19. #set :domain, "crm.abc.com" #custom define
  20. role :web, "192.168.0.13", "192.168.0.117" # Your HTTP server, Apache/etc
  21. role :app, "192.168.0.13", "192.168.0.117" # This may be the same as your `Web` server
  22. role :db, "192.168.0.13", :primary => true # This is where Rails migrations will run
  23. #role :db, "your slave db-server here"
  24. #
  25. namespace :deploy do
  26. desc "remove and destory this app"
  27. task :destory, :roles => :app do
  28. run "cd #{deploy_to}/../ && #{try_sudo} mv #{application} /tmp/#{application}_#{Time.now.strftime('%Y%d%m%H%M%S')}" #try_sudo 以sudo權限執行命令
  29. end
  30. after "deploy:update", "deploy:shared:setup" #after, before 表示在特定操作之後或之前執行其他任務
  31. namespace :shared do
  32. desc "setup shared folder symblink"
  33. task :setup do
  34. run "cd #{deploy_to}/current; rm -rf shared; ln -s #{shared_path} ."
  35. end
  36. end
  37. after "deploy:setup", "deploy:setup_chown"
  38. desc "change owner from root to user1"
  39. task :setup_chown do
  40. run "cd #{deploy_to}/../ && #{try_sudo} chown -R #{user}:#{user} #{application}"
  41. end
  42. task :start do
  43. run "cd #{deploy_to}/current && ./crmd.sh start"
  44. #try_sudo "cd #{deploy_to}/current && ./restart.sh"
  45. end
  46. task :stop do
  47. run "cd #{deploy_to}/current && ./crmd.sh stop"
  48. end
  49. task :restart do
  50. run "cd #{deploy_to}/current && ./crmd.sh restart"
  51. end
  52. end

上面關於環境部分這裏特別說下,如果有多個stage要部署,則在config下創建deploy文件夾, 在該文件夾下有各stages文件, 文件名和 set :stages, %w(development production) 對應, 如development.rb production.rb,在各文件中設置相應變量即可,

  1. set :stages, ["staging", "production"]
  2. set :default_stage, "staging"

production.rb 設置類似如下:

  1. set :deploy_to, "/var/www/#{application}"
  2. # The hostnames to deploy to.
  3. role :web, "devel.example.com"
  4. # Specify one of the web servers to use for database backups or updates.
  5. # This server should also be running Drupal.
  6. role :db, "devel.example.com", :primary => true
  7. # The username on the target system, if different from your local username
  8. # ssh_options[:user] = 'alice'
  9. # The path to drush
  10. set :drush, "cd #{current_path} ; /usr/bin/php /data/lib/php/drush/drush.php"

同樣development.rb:

  1. server "my_fancy_server.com", :app, :web, :db, :primary => true
  2. set :deploy_to, "/var/www/fancy_shoes_development"

實際應用中,我們也可以配置在不同環境中使用同一主機中使用不同的目錄,也可以配置不同的環境裏包含着不同的主機。在多環境中,執行部署的命令需要指定環境:

  1. cap production deploy:...

在2.x.x 的多環境配置中使用cap發佈也可以不指環境,這需要在配置中指定其中一個環境爲默認環境 。在3.x.x中,默認創建的demo項目中,就已經創建好了deploy目錄,並生成了production和staging兩個環境文件,而且在執行時默認強制需要指定發佈的環境,所以3.x.x的默認結構更清晰 

2、驗證配置的執行deploy

全部準備好後,先試試我們的 recipe,以便讓 Capistrano
在服務器上創建初始的目錄結構。從你的應用根目錄執行下列命令:

  1. $ cap deploy:setup

當你執行該命令時,Capistrano 將 SSH 到你的服務器,進入你在 deploy_to 變量中所指定的目錄,並創建特殊的 Capistrano 目錄結構。如果遇到權限或 SSH
訪問錯誤,你將獲得錯誤消息。當命令執行時仔細看看 Capistrano 的輸出。

在我們使用 Capistrano 做實際部署之前的最後一步是,確保 setup
命令在服務器上全都設置正確。使用以下命令進行簡單驗證:

  1. $ cap deploy:check

該命令將檢查你的本機環境及服務器,並定位問題。如果你看到錯誤消息,修復後再運行此命令。一旦你執行cap deploy:check 沒有錯誤,則可繼續處理。

部署過程中我們還會用到下面的語句(需要在deploy.rb裏事先進行定義task):

  1. $cap deploy:setup #建立部署路徑
  2. $cap deploy:update #部署
  3. $cap deploy:start #啓動服務
  4. $cap deploy:stop #停止服務
  5. $cap deploy:restart #重啓服務
  6. $cap deploy:rollback #回滾

提示與技巧

使用遠端緩存改進性能

Capistrano
的工作方式在每次部署時都將創建新的倉庫克隆及導出。那必將很慢,通過添加一些擴展選項到
deploy.rb recipe 則可提速。添加下列內容到 deploy.rb 文件描述 scm 設置的位置:

  1. set :deploy_via, :remote_cache

此命令使 Capistrano 在服務器上只克隆/導出倉庫一次,然後在每次部署時使用 svn
up
 或 git pull 代替。如果你經常部署,你將發現提速明顯。

添加定製的部署鉤子(Hook)

Capistrano 顯然比通過 SSH
複製文件要高級。你可以配置事件或命令以便在文件複製完成後執行,如重啓 Web
服務器、執行定製的腳本等。Capistrano 稱這些爲“任務”。例如,添加以下代碼到
deploy.rb 文件:

  1. namespace :deploy do
  2. task :restart, :roles => :web do
  3. run "touch #{ current_path }/tmp/restart.txt"
  4. end
  5. task :restart_daemons, :roles => :app do
  6. sudo "monit restart all -g daemons"
  7. end
  8. end

Capistrano 中的任務非常強大,我們在本指南中僅接觸到表皮。你可以創建任務在部署
前、部署後或單獨操作服務器。這可以是任何維護類型:重啓進程、清理文件、發送
郵件通知、執行數據庫遷移、運行腳本等等。

我們的示例包括兩個定製任務。“restart”任務是內建於 Capistrano
中的,將在部署完成後自動執行。我們使用由 Passenger 驅動的現代 Rails 應用技術
touch tmp/restart.txt,你的 Web 服務器可能需要不同的命令。

我們的第二個示例任務是“restart_daemons”,Capistrano
不會默認執行此定製任務。爲了讓它運行,我們需要添加一個 hook:

  1. after "deploy", "deploy:restart_daemons"

此命令告訴 Capistrano 在我們的部署操作完成後執行任務。其他可用的 hook 是
before,將在文件複製之前執行任務。

關於 before 及 after hook,你可以閱讀官方的 Capistrano 文檔:

將 Git 分支與環境關聯

因爲我們有兩個服務器環境(臨時和生產),你可能想要綁定 Git
分支到這些環境。這樣,你可以自動部署 staging 分支到臨時環境,master
分支到生產環境。簡單添加下列內容到 production.rb:

  1. set :branch, 'production'

並添加以下內容到 staging.rb

  1. set :branch, 'staging'

現在每次你執行 cap deploy 時,Capistrano 將從你的 staging 分支(因爲 staging
是我們的默認環境)部署代碼。如果你運行 cap production deploy,Capistrano
將從你的 master 分支部署代碼。

參考文檔:

largetalk的csdn博客

capistrano部署drupal應用

dl528888 51cto博客

使用capistrano部署web應用

github wiki頁

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章