最近几天通过对webistrano和capistrano的搭建和了解,开始在公司的内部测试平台上应用webistrano 。目前需要部署的是个resin应用,需要通过webistrano实现的目标:

  • 目录与环境的自动创建
  • 自动代码check ( svn或git )
  • 配置文件的自动修改
  • resin服务的web启停

一、project type模板

这里使用的的模板为 webistrano项目配置 中的模板文件,如下:

 1$ cat resin_web.rb
 2module Webistrano
 3  module Template
 4    module ResinWeb
 5      CONFIG = Webistrano::Template::Base::CONFIG.dup.merge({
 6      }).freeze
 7      DESC = <<-'EOS'
 8        Template for use with resin projects that update  files and restart resin.
 9        The basic (re)start/stop tasks of Capistrano are overrided with restartstartstop tasks.
10      EOS
11      TASKS = Webistrano::Template::Base::TASKS + <<-'EOS'
12         namespace :deploy do
13           task :restart, :roles => :app, :except => { :no_release => true } do
14             run "#{try_sudo} setsid /etc/init.d/resin restart"
15           end
16           task :start, :roles => :app, :except => { :no_release => true } do
17             run "#{try_sudo} setsid /etc/init.d/resin start"
18           end
19           task :stop, :roles => :app, :except => { :no_release => true } do
20             run "#{try_sudo} setsid /etc/init.d/resin stop"
21           end
22         end
23      EOS
24    end
25  end
26end

该模板同样适用于tomcat项目,只需要将其中的脚本名称修改掉即可。

注:上面的setsid 也可以使用nohup ,这两个不加的情况在start时,会出现在ps里查看时,程序启动后又自动关闭了(由于webistrano远程过来的主进程运行完退出终目后,子进程也终止了,使用nohup和setsid可以解决该问题)。

二、recipes 配置

在发布项目时,会遇到使用svn或git checkout到远程目录时没有写入权限的问题,引了下原因,是因为capistrano在check时没有使用#{try_sudo}导致的,又不想去修改capistrano的源代码(相对麻烦),可以通过在recipes里增加task 解决code update时的权限问题。

另外在项目发布时,还会遇到需要删除.svn或.git 的问题自动更改配置文件的问题,这里的recipes主要就是为了解决以上三个问题,如果有其他问题,也可以在此基础上进行增加task ,代码如下:

 1namespace :resin do
 2  desc "change_permi"
 3  task :change_permi do
 4    run "#{try_sudo} chown -R  #{runner}:#{runner} #{deploy_to}"
 5  end
 6  desc "del_svn"
 7  task :del_svn do
 8    run " #{try_sudo} rm -rf `find #{latest_release} -type d -name .svn` "
 9    run "cd #{latest_release} && #{try_sudo} rm -rf public tmp log"
10    run "mv #{latest_release}/WEB-INF/classes/config.properties #{latest_release}/WEB-INF/classes/config.properties.bak"
11  end
12  desc "replace_conf"
13  task :replace_conf do
14     resin_config =<<-EOF
15ymconvHost=172.20.0.43
16#ymconvHost=hou.ymtrack.com
17ymconvPort=8080
18ymconvRoute=ymconvhttpdao
19redis.host=localhost
20redis.port=6378
21urlsyncDelay=1000
22    EOF
23    put resin_config, "#{latest_release}/WEB-INF/classes/config.properties"
24  end
25end
26before 'deploy:update','resin:change_permi'
27after 'deploy:update','resin:del_svn','resin:replace_conf'

需要注意的是这里文件是通过先写到一个类似变量里,再put上去的 。在此之前我试图通过cat EOF的方式直接写入文件发现是行不通的。

注:在del_svn中的mv 语句可以不要,后面的 replace_conf中的put语句在存在原文件时,会自动覆盖原文件。这里便于理解,我并没有删除。

一点题外话

capistrano里的语法十分灵活,比如有多个shell 语句需要执行时,可以利用上例中的put语句写入到文件再执行,也可以使用each 定义一个task逐条执行,如下:

1task :aaaa do
2    [
3    "mkdir -p /tmp/src",
4    "cd /tmp/src && wget http://nginx.org/download/nginx-1.6.0.tar.gz",
5    "cd /tmp/src && tar xvzf nginx-1.6.0.tar.gz"
6    ].each {|cmd| run cmd}
7    end

需要注意两点:1、每条命令后面的逗号不能少 ;2、每条命令完,相当于退出再执行下一条 ,如上面的例子中,如果我用的是root用户,后面两条命令如果不加前面的cd 语句部分,nginx就会下载的/root目录 ,并解压到/root 目录 。

上面两步配置完成后,在web界面上做stage、host、recipes、roles的关联后,在stage界面依次执行 deploy:setup —-> deploy:update —–> deploy:start ,即可以完成一个resin项目会环境部署到启动的所有步骤。