上一篇:rails3项目解析之5——rails on windows
在那山的这边海的那边有一群部署员
他们辛苦又没钱
他们忙碌又危险
他们一天到晚坐在那里不停地在上传
有了问题就赶紧查网线~~
哦 苦逼的部署员
哦 苦逼的部署员
只要一改代码他们就要重新发一遍
出点问题打击一大片
由于年代太过久远,我确实已经忘记了以前在java下面是肿么部署的了。隐约记得好象不是个轻松活。貌似要打各种包,上传各种文件,重启各种服务,对付各种问题。后来ant好象可以做自动部署,但得写一大坨xml文件,也忘了是不是好用了。
无数的实践已经证明并将继续证明,手动部署是一项十分坑爹的运动,仅次于跨个110米的栏就被人牵手两次。因为根据墨菲定律(Murphy's Law)最广为人知的变体表述,“会出错的终将出错”。人是一种很奇妙的生物,模糊计算的能力无比强大,精确执行的能力却又惨不忍睹。周岁的婴儿能够辨认出各种挤眉弄眼表情的妈妈,再严谨的成人却也无法保证连续100次做同一件事情而不出错。
那好,就把精确而繁琐的任务交给计算机来执行吧。
1、选型
在rails下自动部署工具一般会有两个选择:capistrano和vlad。前者貌似出得比较早,名声也大一点,后者据说做了一些改进,使用起来更为简单。忘了当时为什么没选vlad了,可能是capistrano印象比较深刻,各种插件相对还算齐全,所以在这个问题上也并没有太多的犹豫。使用vlad的同学,你们的选择也是正确的,不必过于纠结。
2、原理
从capistrano的gemspec可以看到,它使用了net-ssh、net-scp、net-sftp等各种net工具。因此,它的原理就是使用ssh依次登录各个服务器,按照事先规定的流程,拷贝文件,执行shell命令,等等。
3、需求
3.1 首先,安全性是第一位的。经验告诉我们,安全措施不到位会搞出人命,无论是人命++还是人命--。要求执行自动部署命令的用户名是普通用户,不在admin组,而且不被授予任何的sudo权限。避免别人通过网站漏洞取得权限之后啥事都能干了。
3.2 可以在多个环境进行部署。可以简单地根据命令参数,选择是在测试环境中发布,还是在产品环境中发布。
3.3 和bundle整合良好。rails越来越多地依赖bundle来进行gem管理,因此要融入bundle来做一些工作。
3.4 部署命令尽量简单易记,用最简单的20%的命令完成80%的部署任务。
3.5 配置文件中不出现任何的明文和密文密码。
4、具体配置
大体按照配置文件的自然顺序,逐一简单描述。
4.1 多环境部署
多环境部署需要用到capistrano的一个插件capistrano-ext,里面有一个ext叫multistage,可以符合我们的需求。
capistrano的主配置文件是config/deploy.rb,在该文件中添加
require 'capistrano/ext/multistage'
set :stages, %w(alpha production)
set :default_stage, 'alpha'
然后在config/deploy目录下添加两个文件:alpha.rb和production.rb,针对不同的环境作相应配置。
这样,就形成了两个发布环境,alpha用于内部测试,production是产品环境,是正式运营服务器。
可以使用如下命令进行发布:
cap deploy
因为已经设置default_stage为alpha,所以当省略环境名称的时候,即是发布至alpha服务器组。
如果要发布至产品环境,可加入一个参数显式指定环境:
cap production deploy
4.2 服务器组配置
以production.rb为例:
# 设置执行相关命令时的RAILS_ENV。
set :rails_env, 'production'
# 设置该环境在scm中的代码分支名。
set :branch, 'production'
# 设置服务器角色,no_release代表不再重复发布代码。
role :app, '192.168.1.30', '192.168.1.40', '192.168.1.50', '192.168.1.60', '192.168.1.70', '192.168.1.80'
role :web, '192.168.1.30', '192.168.1.40', :no_release => true
role :bg, '192.168.1.50', '192.168.1.60', :no_release => true
role :db, '192.168.1.90', :primary => true, :no_release => true
4.3 服务器路径
# 应用名
set :application, 'xxx'
# 发布根路径
set :root_path, '/xxx'
# 代码发布路径
set :deploy_to, "#{root_path}/web"
# 存储代码中共用的文件,例如database.yml、payment.yml等。
set :project, "#{deploy_to}/shared/project"
# 通过远程缓存发布
set :deploy_via, :remote_cache
deploy_via :remote_cache可以在服务端保持一个缓冲池,当每次发布的时候,先git pull到服务端缓冲池中,然后再cp至发布路径,这样不必每次都git clone,可以节省很多时间。
4.4 用户
# 执行发布的用户名
set :user, 'www'
# 不使用sudo
set :use_sudo, false
4.5 代码库
set :scm, :git
set :repository, 'ssh://git@192.168.1.188/xxx/xxx.git'
设置git路径,并指定使用ssh协议来进行传输。ssh权限使用公钥系统进行管理。有发布权限的开发人员,只需在本地配置好公钥,便可进行发布,而且不必输入密码,也不用在capistrano的配置文件中设置密码。
4.6 扩展bundle
require 'bundler/capistrano'
set :bundle_flags, '--quiet'
bundle自带capistrano的task,引用一下就可以了,倒也省事。quiet是安静模式,避免看见满屏的信息。
引用bundle支持后,每次update_code更新完代码之后,都自动执行bundle:install安装新增和改变的gem。
为了节省bundle:install的时间,提高发布效率,需要做一个小小的改进:
namespace :bundle do
task :prepare, :roles => :app do
# 链接文件,而不必每次都重新生成
run "ln -sfT #{project}/.bundle #{latest_release}/.bundle"
run "ln -sf #{project}/Gemfile.lock #{latest_release}/Gemfile.lock"
# 指定执行update
run "cd #{latest_release} && bundle update" if exists?(:update)
end
end
如果Gemfile中rails版本更改,自动bundle:install会产生依赖失败,因此,如果rails版本更改,则需要传入-s update=true参数,触发bundle update语句,先升级rails再执行后续流程。
扩展bundle后,项目所依赖的gem就不再安装到ruby的系统路径下,而是安装到发布路径,而且owner是用户www。以后如果需要登录到服务器上执行诸如rake命令,都需要在前面加bundle exec,以把当前命令置入bundle环境执行。
4.7 自定义任务
namespace :deploy do
task :start do ; end
task :stop do ; end
# 重启服务,适用于passenger
task :restart, :roles => :web do
run "touch #{current_path}/tmp/restart.txt"
# rails 3.1首次访问时间较长,发布成功后先访问一下,进行初始化
run "curl -s -o /dev/null 127.0.0.1"
end
task :links, :roles => :app do
# 建立配置文件链接
# 因为这两个文件中的信息比较敏感,因此代码库中是不保存的,真实的文件只保存在服务器上
run "ln -sf #{project}/config/database.yml #{latest_release}/config/database.yml"
run "ln -sf #{project}/config/payment.yml #{latest_release}/config/payment.yml"
# 建立文件目录链接,可以按照自己的需求添加
run "ln -sfT #{root_path}/file/ckeditor_assets #{latest_release}/public/ckeditor_assets"
end
task :bg, :roles => :bg do
# 因为使用了resque作为后台任务,所以每次代码发布后,有可能会更改了后台任务的执行代码,因此需要杀掉resque相关的进程,再由monitor自动重启,让resque使用最新的代码。
run "ruby #{current_path}/script/resque.rb kill"
end
end
另外,rails 3.1需要先预编译一下,提高asset pipeline的效率。因此可以设置
task :precompile, :roles => :web do
run "cd #{current_path} && #{rake} RAILS_ENV=#{rails_env} assets:precompile"
end
capistrano刚出的2.8.0的版本,貌似已经加入了自动precompile的任务。不过因为我已经被离职,已不方便再拿人家的服务器做小白鼠了。有兴趣的同学可以自行体验。
4.8 回调
可以设置各种回调,指定各项task执行的顺序:
after 'deploy:finalize_update', 'bundle:prepare'
before 'deploy:symlink', 'deploy:links'
after 'deploy:update', 'deploy:migrate', 'deploy:bg', 'deploy:precompile'
5、常用命令
# 发布
cap deploy
# 数据迁移
cap deploy:migrate
# 发布后发现有重大问题,需要立刻回滚至上一个正确版本。
cap deploy:rollback
# 上面的命令都是发布至默认的alpha测试环境的,如果要发布至产品环境,则在cap后加入production即可
cap production deploy
cap production deploy:rollback
6、常用维护任务
capistrano可以做一些常用的服务器维护任务,例如apt-get install等。因为如果在服务器数量太多的情况下,在本地敲一个命令就能够完成全部服务器的升级,也能节省不少的时间。
namespace :apt do
task :install, :roles => :app do
set :user, 'xxx'
default_run_options[:pty] = true
sudo "apt-get -y install #{fetch(:name)}"
end
task :upgrade, :roles => :app do
set :user, 'xxx'
default_run_options[:pty] = true
sudo "apt-get update"
sudo "apt-get -y upgrade"
sudo "apt-get -y dist-upgrade"
end
end
需要注意的是,因为是系统维护,所以这里的执行用户,就得是admin组里的管理用户了。pty选项是为了开启交互模式,以输入sudo密码。
fetch(:name)是接收命令行传入的apt包名称。完整命令如下:
cap apt:install -s name=mongodb-10gen
不过在执行服务器批量维护命令时一定要慎重,必须在测试服务器上全面测试以确保一切顺利,避免新版本的apt包引起可能的潜在问题。
分享到:
相关推荐
《Web开发敏捷之道——应用Rails进行敏捷Web开发》是一本深度探讨如何利用Ruby on Rails框架进行高效、敏捷的Web应用程序开发的专业书籍。该书涵盖了从初学者到高级开发者所需的各种知识,旨在帮助读者掌握敏捷开发...
《敏捷Web开发与Rails》第三版Beta:深入解析与核心知识点 标题与描述明确指出了本书的主题——敏捷Web开发与Rails框架的结合。这是一部专为Rails 2版本设计的书籍,作者团队包括了Sam Ruby、Dave Thomas、David ...
- **DRY原则**(Don't Repeat Yourself):这一原则贯穿于整个Rails框架之中,旨在通过自动化工具和模板减少代码冗余。 - **约定优于配置**(Convention Over Configuration):Rails提供了一系列默认配置,开发人员...
- **Scrum和Kanban**:书中介绍了两种流行的敏捷项目管理框架——Scrum和Kanban的基本概念和实施步骤。 - **持续集成(CI)**:为了保证软件质量,书中讲解了如何设置持续集成环境,自动进行构建和测试。 - **版本控制...
- **Scrum和Kanban**:本书介绍了两种流行的敏捷管理方法——Scrum和Kanban,并探讨了它们在Rails项目中的具体应用。 - **持续集成**:强调频繁地将代码合并到共享库中,以便快速发现并解决问题。 - **测试驱动开发...
- **实战应用**:通过一个实际项目——在线音乐商店的开发过程,展示了如何将理论知识应用于实际的Rails开发中。这个例子覆盖了从需求分析到最终部署的整个流程。 - **源码解析**:最后,本书还介绍了一些探索Rails...
【标题解析】:“毕业设计——多用户博客系统”这一标题表明这是一个针对计算机科学与技术专业学生的毕业设计项目,主要涉及的是构建一个支持多个用户的博客平台。这个系统可能包含用户注册、登录、发布博客、评论、...
《项目自动化之道——如何建构、部署、监控Java应用》一书聚焦于Java应用的自动化实践,涵盖了从构建到部署再到监控的全过程,提供了详细的指导和最佳实践。自动化不仅可以显著减少人工错误,还能极大地提高开发效率...
《国土:基于Rails的开源论坛社区系统——深入探讨与实践》 国土,一款基于Ruby China社区的开源论坛系统,以其高效、灵活的特性在开发者群体中受到广泛关注。它充分利用了Ruby on Rails框架的力量,为创建互动性强...
《PA-2.0: 个人助理2.0项目的深入解析》 PA-2.0,全称为“个人助理2.0”,是一个由专业团队精心打造的基于Rails框架的应用程序。这个项目旨在提供一个智能化、高效能的个人助手服务,通过先进的技术手段,帮助用户...
需要注意的是,尽管Delphi在Web应用开发上具备一定的能力,但其Web开发工具和组件可能不如某些专门针对Web开发的语言和框架(如Ruby on Rails、Django等)广泛使用和更新频繁。然而,对于已经熟悉Delphi环境的开发者...
这些标签突出了项目的目的——作为教育工具,帮助学生或学习者掌握企业级电子商城的开发技术,包括但不限于前端界面设计、后端服务构建、数据库管理、用户认证与安全、购物车逻辑、支付接口集成等。同时,"使用"标签...
《Chats.zip——开源消息应用解析》 Chats.zip是一个开源的即时通讯应用程序,它代表了现代技术在社交沟通领域的创新应用。开源项目的特性使得它不仅是一个产品,更是一个技术学习与分享的平台,允许开发者深入研究...
3. **Redmine集成:** Redmine是一个基于Ruby on Rails的开源项目管理工具,提供问题跟踪、版本控制、文档管理和项目报告等功能。Clockit的集成扩展了Redmine的功能,增强了时间管理能力。 4. **JavaScript编程:**...
Java局域网通信——飞鸽传书源代码 28个目标文件 内容索引:JAVA源码,媒体网络,飞鸽传书 Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java...
【MyBlogV6】是一个可能代表博客系统的项目版本,标题中的"V6"暗示这是该系统的一个迭代版本,可能是为了引入新的功能、优化性能或修复已知问题。描述中的"要被更新"提示我们,这个版本即将面临升级或维护,这在软件...
首先,我们关注的是项目的核心语言——Ruby。Ruby是一种面向对象的脚本语言,以其简洁、优雅的语法和强大的元编程能力而闻名。在SISLEGIS-site中,Ruby可能被用来构建动态网页、处理服务器端逻辑以及管理数据。...
8. **部署与运维**:Ruby应用通常部署在如Heroku或AWS等云平台上,利用如Capistrano等工具进行自动化部署。此外,还可能使用Docker容器化技术,提高部署的灵活性和一致性。 通过以上分析,我们可以看出"car_trader...
- 自动化脚本:易于集成到自动化部署脚本中。 #### 三、目标读者 - Drupal开发者:无论是新手还是有经验的开发者,都能从中受益。 - 网站管理员:希望提高日常管理工作效率的人员。 - 技术团队成员:负责维护...
负载均衡和自动化部署也是大型在线服务必须考虑的问题,如使用GitLab CI/CD进行持续集成和持续部署。 总的来说,"online_converter"项目展示了如何利用Ruby和相关技术栈构建一个商业级的在线服务,涵盖了文件处理、...