Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Deployment with Capistrano

張旭
March 22, 2016

Deployment with Capistrano

張旭

March 22, 2016
Tweet

More Decks by 張旭

Other Decks in Programming

Transcript

  1. 簡單地使用 Git 的部署手法: 1. 在本機開發,修改程式檔案。 2. 執行 git push 遞交變更。

    3. 登入伺服器,在專案目錄執行 git pull 更新。 4. 視需求修改伺服器上的設定檔。 5. 視需要重啟服務以載入新的設定值。
  2. 簡單地使用 Git 的部署手法 (劣勢): • .git 目錄有曝露的風險 • Git Repository

    的金鑰管理 • 手動修改或重載,繁瑣易出錯 • 主機數量增加時,重複工作與出錯率都倍增
  3. EXAMPLE Rails - rake db:migrate RAILS_ENV=development - rake assets:precompile RAILS_ENV=production

    - touch tmp/restart.txt Yii 2 - composer install - yii migrate CodeIgniter - composer install - gulp TASK_NAME
  4. Ruby, RubyGems, rbenv Ruby 是一款程式語言,演進相當快速,版本眾多。 RubyGems 是套件管理工具,管理 Ruby 語言開發的套件。 -

    如同 npm 之於 NodeJS - 如同 Pip 之於 Python - 如同 Composer 之於 PHP rbenv 則是管理不同版本的 Ruby 的工具,顧名思義。 - 如同 nvm 之於 NodeJS - 如同 virtualenv 之於 Python - 如同 phpbrew 之於 PHP
  5. 檢查主機是否已經有 Ruby 環境 $ which ruby # 檢查是否已安裝 Ruby $

    which gem # 檢查是否已安裝 RubyGems 套件管理工具
  6. Mac 主機安裝與設定 Ruby 環境 $ brew update $ brew install

    rbenv ruby-build $ rbenv install 2.3.0 $ rbenv global 2.3.0 $ rbenv rehash
  7. Ubuntu 主機安裝與設定 Ruby 環境 $ sudo apt-get update # 參考

    https://github.com/sstephenson/rbenv#installation https://github.com/sstephenson/ruby-build#readme $ rbenv install 2.3.0 $ rbenv global 2.3.0 $ rbenv rehash
  8. ❖ Tips 1. 執行 gem install 之前,先編輯 ~/.gemrc 寫入: install:

    --no-rdoc --no-ri update: --no-rdoc --no-ri 2. 安裝新的 gem 之後,執行 rbenv rehash 重新載入。
  9. 使用 RubyGems 安裝 Capistrano $ gem install capistrano # 安裝

    Capistrano 主程式 $ gem install capistrano-hipchat # 安裝 Capistrano HipChat 外掛 $ gem install capistrano-composer $ gem install capistrano-rails $ gem install capistrano-ssh-doctor $ gem install capistrano-db-tasks
  10. 初始化 Capistrano $ cd my_project $ cap install # 初始化

    Capistrano 環境建立必要的設定檔 $ cap --tasks # 顯示目前可以執行的 Capistrano 任務 $ cap --help # 顯示基本的使用方法 $ git status # 偷看一下多出了哪些檔案
  11. Capistrano 設定檔 (1) ├── Capfile └── config/ ├── deploy.rb └──

    deploy/ ├── production.rb └── staging.rb http://capistranorb.com/documentation/getting-started/configuration/
  12. Capistrano 設定檔 (2) • Capfile 是基礎設施宣告,宣告要引用的外掛、自訂任務等。 • deploy.rb 是一個全域的變數設定檔,裡面的設定會被各個 Stage

    引用。 • Stage 指不同的部署環境,各別對應到 config/deploy/stage_name.rb, 例如 staging.rb 跟 production.rb。 • Stage 是可以自訂或更名的,例如 staging.rb 可以改成 dev.rb。
  13. Capfile # 初始化程式 require 'capistrano/setup' # 載入預設的部署流程 require 'capistrano/deploy' #

    載入其他外掛 require 'capistrano/hipchat' # 從 lib/capistrano/tasks 載入其他自定義的任務 Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
  14. deploy.rb (1) # 限定 Capistrano 的版本 lock '3.4.0' set :application,

    'my_app_name' # 設定版本控制工具以及專案的 Git 程式庫路徑,注意遠端主機對程式庫的讀取權限問題 set :scm, :git set :repo_url, '[email protected]:me/my_repo.git' # 設定部署到遠端主機的目錄,使用 絕對路徑,做為程式部署時的根目錄 set :deploy_to, '/path/to/project/directory/' # 利用 ask 函式,搭配 git 指令抓取當前所在的 branch 做為要部署的版本 ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp
  15. deploy.rb (2) # 將要共享的檔案或目錄分別添加到 :linked_files 跟 :linked_dirs 變數中 # 多個檔案或目錄可以用逗號

    (,) 區隔 # 注意!路徑是相對路徑,用以在 current 目錄底下建立 symbolic link # 真正的檔案或目錄需要使用者實際手動在 shared 目錄下建立 (後面會提到) set :linked_files, fetch(:linked_files, []).push('path/to/file') set :linked_dirs, fetch(:linked_dirs, []).push('path/to/directory') # 定義 Capistrano 在遠端主機內運作時的環境變數 set :default_env, { MY_VAR1: "my_value1", MY_VAR2: "my_value2" } # 需要保留的舊版本數量,預設是 5 set :keep_releases, 2
  16. deploy.rb (3) # 在預設的部署流程中添加自訂的任務 namespace :deploy do desc 'description of

    my_task' task :my_task do # roles 是所要部署的主機角色,通常定義在 stage_name.rb 中 on roles(:role_name) do # do something end end after 'deploy:finished', 'deploy:my_task' end
  17. staging.rb 與 production.rb # 通常會在 stage_name.rb 中設定不同的目標主機與登入資訊 # staging.rb server

    'dev.server.my', user: 'deploy', roles: %w{app web}, port: 22 # production.rb server 'prod1.server.my', user: 'admin', roles: %w{web}, port: 8022 server 'prod2.server.my', user: 'admin', roles: %w{app}, port: 8022 # 所有在 deploy.rb 中的設定,都可以在這裡覆寫或擴充, # 但任務 (Tasks) 的覆寫需要使用 .clear_actions 函數,請參考: http://capistranorb.com/documentation/advanced-features/overriding-capistrano-tasks/
  18. Capistrano 部署出去的目錄結構 (1) ├─ current -> /path/to/project/directory/releases/20150908300022/ ├─ releases/ │

    ├── 20150807250011/ # {YYYYMMDDhhmmss} │ ├── 20150903080022/ ├─ repo/ │ └── <版本控制軟體的原始檔案> ├─ revisions.log └─ shared/ └── <linked_files 跟 linked_dirs 實際存放的地方>
  19. Capistrano 部署出去的目錄結構 (2) • current 是一個 symbolic link,指向 releases 內的當前發佈目錄。

    • releases 存放每次部署所產生的目錄,其源自於 repo。 • repo 是一個 Bare Git Repository,部署時使用 git archive 指令,從裡面取 出檔案放到 releases 目錄之下。 • revisions.log 是一個版本記錄檔,記錄每次部署所對應的 git hash。 • shared 存放共享的檔案跟目錄,如果有設定,在每個 releases 內的目錄都會 有 symbolic link 指向 shared 內的檔案或目錄。最常見的就是 config 檔、 upload 目錄、tmp 目錄、cache 目錄等。
  20. 執行 Capistrano 部署與還原 $ cap staging deploy $ cap staging

    deploy:rollback $ cap production deploy $ cap production deploy:rollback # rollback 實際上是將 current 指向 releases 底下前一版的目錄而已,非常快速。