本文基于Capistrano 2版本,文中的命令不一定适用于Capistrano 3。
什么是Capistrano?
简单地讲,Capistrano是一个gem
。对于不太熟悉Ruby的朋友来说,gem
就是一套按照一定规范打包好的Ruby代码,可以类比Java里面的Package。
实际上,Capistrano是专门用来部署rails程序的一套工具。
为什么用它?
Rails应用程序的部署方案十分灵活,适应于不同的生产服务器场景。在实际生产中,rails程序中包含的各类gem和生产服务器上的gem往往版本不一致,这就为部署增加了一些难度。
利用Capistrano进行部署,就能很容易解决这个问题。同时,使用Capistrano部署rails程序,更有一种“敏捷”的感觉。
在进行Rails开发过程中,一个重要的工具就是版本控制,而我们经常用Git。用过Heroku的开发者,或者有静态博客的朋友都能感受到一点——把版本控制与部署方案融合到一起非常方便。幸运的是,Capistrano对包括Git在内的各类版本控制有非常好的支持。本文中,我将使用Git作为版本控制软件,与Capistrano一起工作,进行项目部署。
如何部署?
利用Capistrano部署Rails程序,可以分为下面四个步骤。
配置部署服务器
对应用程序进行版本控制
远程部署应用程序
版本控制推进部署
配置部署服务器
对生产服务器的基本配置,包括Web静态服务器、数据库、版本控制搭建、防火墙等的控制不在本文讨论范围内。它们之中任何一点拿出来都够写一本书了。
首先,要在部署服务器可以访问到的地方创建一个新的版本库。
读者可以在公司/实验室里搭建GitLab,或者连接到GitHub上。如果是自己搭建GitLab,其实完全可以把Git服务器和生产服务器放在同一台机器上。可以通过以下命建立Server端的远程版本库,也可以通过访问Git服务器的Web界面自行操作。
$ mkdir -p ~/git/project.git
$ cd ~/git/project.git
$ git --bare init
值得注意的是,即使是把Git Server和Web Server放在同一台机器上,Capistrano也是通过Web服务的形式访问Git。这里可以配置公钥来简化整个流程。
$ test -e ~/.ssh/id_dsa.pub || ssh-keygen -t dsa
$ cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
还有一件非常重要的事情:Capistrano将在应用程序目录名和Rails子目录中插入名为current
的目录,其中包括public
子目录。在用Capistrano部署好的项目中,目录结构类似下面的样子(current
是当前部署的版本,releases
是该分支下根据版本生成的曾经的项目,shared
中是各个版本共享的资源):
$ ls project
> current releases shared
而这个public
目录就是我们熟悉的Rails程序中静态资源目录;也就是说,不论你用Apache或Ngnix还是其他Web服务器来部署静态资源,需要把这个目录设置为根目录。以Apache配置为例:
DocumentRoot /home/project/current/public/
到此为止,对服务器的预先配置就已经完成了,接下来的工作都可以在开发环境中完成。
对应用进行版本控制
最开始,要在项目的Gemfile中加入Capistrano gem:
...
gem 'capistrano'
...
然后执行命令bundle install
来安装gem。接下来执行一条很重要的命令,它的作用是把项目中用到的gem及其版本号都记录下来:
$ bundle pack
//然后可以做一个版本记录,并推送到远程库
$ git add .
$ git commit -m "install capistrano & bundle gems"
$ git push origin master
以上,已经完成了项目gem整理。接下来我们要把项目代码放入生产环境。
远程部署应用程序
接下来的过程,我们可以先猜测一下:
把代码pull到服务器的DocumentRoot
在生产服务器上生成数据库
安装gem
重启Passenger
……
这些事情,可以想到的话,就可以手动来做;但是等下,要Capistrano是做什么的……
没错,到了这一步,就可以显示Capistrano的威力了:自动化部署。以上的事情可以全交给它来做,当然前提是要写一份自动化部署的脚本。
首先,在开发环境的项目根目录中执行命令:
$ capify
[add] writing './Capfile'
[add] writing './config/deploy.rb'
[done] capified!
//Capistrano3中使用下面的命令
$ cap install
现在多出来了两个文件:Capfile
和deploy.rb
,前者是Capistrano对Rakefile的模拟,不需要改动,后者是一个自动化的脚本,需要编辑的就是这个。这个文件里需要用到一些Capistrano的DSL,可以看这里参考。在此给出一份比较简单的脚本作为参考,它是上面命令生成的默认脚本。
# config valid only for Capistrano 3.1
lock '3.1.0'
set :application, 'my_app_name'
set :repo_url, 'git@example.com:me/my_repo.git'
namespace :deploy do
desc 'Restart application'
task :restart do
on roles(:app), in: :sequence, wait: 5 do
# Your restart mechanism here, for example:
# execute :touch, release_path.join('tmp/restart.txt')
end
end
after :publishing, :restart
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
# Here we can do anything such as:
# within release_path do
# execute :rake, 'cache:clear'
# end
end
end
end
在修改好:application
、:repo_url
等值后,就可以开始进行部署了。
第一次部署的时候,请运行:
$ cap deploy:setup
之后会要求输入服务器密码。连接成功后会在生产服务器上生成必要的目录。
如果想测试配置,看还有没有别的问题,可以运行:
$ cap deploy:check
一旦解决完所有问题,就可以运行下面的命令,进行数据库生成,并完成部署:
$ cap deploy:migrate
$ cap deploy
至此,就已经把项目部署到生产服务器上了。
版本控制推进部署
已经部署完了么?
并不是这样的,不要忽视掉最开始强调版本控制的用意。Capistrano能让你在持续开发的情况下进行版本推进部署,而操作非常简单。每次做好提交、并把版本库推送到远端后,就可以运行cap deploy
进行部署。
如果有某些原因,需要回到上一个部署的版本,执行命令:
$ cap deploy:rollback
这就完了?
没错!整个部署的过程就是这样。
如果想掌握关于它的高级用法,可以看Wiki文档。
本文只是以Rails为例讲解了Capistrano的用法,实际上它还可以用来部署其他语言写的Web应用程序,比如Java、PHP、Python等,读者有兴趣的话可以继续探索下去。