Vlad the Deployer #2

by winson, 4 months ago.

Vlad the Deployer這玩意兒簡單又好用,就算有一百台主機分散在全世界,我想透過它來部署、更新系統也是輕而易舉。

但是在實務操作面,還是有幾個問題:

第一、它預設使用Apache,那麼頗受好評的輕量級網頁伺服器lighttpd怎麼辦呢?

第二、它預設執行環境為Production,那麼我要如何在Development環境下跑呢?

第三、每一台主機位址都不同,要在哪裡設定呢?

最簡單的方式是用namespace,如下:

namespace :macmini do
  task :settings do
    set :domain,      "tw.myrails.com" 
    set :rails_env,   "development" 
    set :web_command, "/etc/init.d/lighttpd" 
  end

  setup_tasks
end

namespace :macpro do
  task :settings do
    set :domain,    "us.myrails.com" 
    set :rails_env, "production" 
  end

  setup_tasks
end
看到沒?上述三個疑問一下解決掉,包括不同主機位置、不同執行環境與不同的網頁伺服器!!

設定很簡單,麻煩就麻煩在最後一行的setup_tasks,這還得另外生一個module去對付他,而且內容都是毫無意義的程式碼:

module VladHelper
  def setup_tasks
    desc "Setup Vlad the Deployer on Mac mini." 
    remote_task :setup => :settings do
      Rake::Task["vlad:setup"].invoke
      Rake::Task["vlad:migrate"].invoke
    end

    desc "Deploy everything to Mac mini." 
    remote_task :deploy => [:update, :start]

    desc "Update source code to Mac mini." 
    remote_task :update => :settings do
        Rake::Task["vlad:update"].invoke
    end

    desc "Retart web servers on Mac mini." 
    remote_task :start => :settings do
      Rake::Task["vlad:start_app"].invoke
      Rake::Task["vlad:start_web"].invoke
    end

    desc "Migrate dev database on Mac mini." 
    remote_task :migrate => :settings do
      Rake::Task["vlad:migrate"].invoke
    end
  end
end
除非要讓update, migrate, start等指令執行跟原本vlad不同的動作,否則特地去撰寫一個module來處理,是相當無意義的。

使用namespace的好處是,可以讓rake指令更有意義,原先的指令是這樣:

rake vlad:setup vlad:update vlad:migrate vlad:start
用了namespace之後,變成這樣:
rake macmini:setup macmini:update macmini:migrate macmini:start
以及
rake macpro:setup macpro:update macpro:migrate macpro:start

我比較偏好另一種方式,請修改以下檔案及設定:

Rakefile

namespace "vlad" do
  desc "Setup vlad deploy target." 
  task :target

  rule "" do |task|
    if task.to_s.match(/vlad:target:([a-z_-]+)/i)
      override_path = File.join(RAILS_ROOT, 'config', "deploy.#{$1}.rb")
      Kernel.load override_path if File.exists? override_path
    end
  end
end
deploy.rb
set :deploy_to,   "/home/winson/projects" 
set :repository,  "http://svn.myrails.com/projects/"
deploy.macmini.rb
set :domain, "tw.myrails.com" 
set :rails_env, "development" 
set :web_command, "/etc/init.d/lighttpd"
deploy.macpro.rb
set :domain, "us.myrails.com" 
set :rails_env, "production"
這種方式把共通的設定保留在deploy.rb,而將個別的設定獨立出來成為deploy.macmini.rb以及deploy.macpro.rb兩個檔案,實際操作也很簡單,如下:
rake vlad:target:macmini vlad:setup vlad:update vlad:migrate vlad:start
以及
rake vlad:target:macpro vlad:setup vlad:update vlad:migrate vlad:start
指令完全一樣,差就差在vlad:target。

往後當我程式改好,送上Subversion之後,只要敲下rake指令,各地的主機就開始自動拉下最新的程式碼、備份、重開mongrel以及lighttpd,真是輕鬆愉快。

該怎麼說呢?這就是人生吧。