搭建工具介绍

Ruby on Rails作为一款十分优秀的web开发框架,在当前web领域中慢慢占据了越来越重要,秉承rails快速开发的特点,很多快速部署rails的方案也越来越多。这篇文章中所选的方案是我个人认为十分优秀的部署方案。这套部署方案的结构是,nginx作为反向代理服务器负责负载均衡,mina作为自动化部署工具,puma作为rails的web服务器

nginx

nginx是一款优秀的代理服务器,其高效的性能已经得到了业界的广泛认可,相信作为web开发人员不会没听说过他的大名

mina

mina是一款由ruby开发的自动化部署工具,其目的是为了简化每次rails代码提交时的部署,一键完成部署,杜绝了提交到git服务器后,又去服务器上git pull的情况

puma

puma是一款专门针对rails的并发服务器,相对于passengerpuma可配置面更广,而且性能比passenger更高,是rails web服务器的不二之选

部署前言

由于这篇文章需要很多铺垫,包括rails的安装下载,git的配置等等,需要读者自己去查阅资料或者查阅之前我写过的一些文章,如果期间有什么问题,请留言。。

mina

首先在你的rails项目的Gemfile中加上

rubygem mina

运行bundle 安装 mina,接着在你的rails项目根目录初始化mina

mina init

这是在你项目的config目录下会有一个deploy.rb,配置deploy.rb,列出重点部分,每一行的解释会附在代码的注释里

ruby#服务器地址,是使用ssh的方式登录服务器
set :domain, 'root@192.168.0.103'
#服务器中项目部署位置
set :deploy_to, '/var/www/ruby_sample'
#git代码仓库
set :repository, 'https://github.com/gameFu/ruby_sample.git'
#git分支
set :branch, 'master'# 中括号里的文件 会出现在服务器项目附录的shared文件夹中,这里加入了secrets.yml,环境密钥无需跟开发计算机一样
set :shared_paths, ['config/database.yml', 'log', 'config/secrets.yml']# 这个块里面的代码表示运行 mina setup时运行的命令
task :setup => :environment do# 在服务器项目目录的shared中创建log文件夹queue! %[mkdir -p "#{deploy_to}/#{shared_path}/log"]queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/log"]# 在服务器项目目录的shared中创建config文件夹 下同queue! %[mkdir -p "#{deploy_to}/#{shared_path}/config"]queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/config"]queue! %[touch "#{deploy_to}/#{shared_path}/config/database.yml"]queue! %[touch "#{deploy_to}/#{shared_path}/config/secrets.yml"]# puma.rb 配置puma必须得文件夹及文件queue! %[mkdir -p "#{deploy_to}/shared/tmp/pids"]queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/tmp/pids"]queue! %[mkdir -p "#{deploy_to}/shared/tmp/sockets"]queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/tmp/sockets"]queue! %[touch "#{deploy_to}/shared/config/puma.rb"]queue  %[echo "-----> Be sure to edit 'shared/config/puma.rb'."]# tmp/sockets/puma.statequeue! %[touch "#{deploy_to}/shared/tmp/sockets/puma.state"]queue  %[echo "-----> Be sure to edit 'shared/tmp/sockets/puma.state'."]# log/puma.stdout.logqueue! %[touch "#{deploy_to}/shared/log/puma.stdout.log"]queue  %[echo "-----> Be sure to edit 'shared/log/puma.stdout.log'."]# log/puma.stdout.logqueue! %[touch "#{deploy_to}/shared/log/puma.stderr.log"]queue  %[echo "-----> Be sure to edit 'shared/log/puma.stderr.log'."]queue  %[echo "-----> Be sure to edit '#{deploy_to}/#{shared_path}/config/database.yml'."]
end#这个代码块表示运行 mina deploy时执行的命令
desc "Deploys the current version to the server."
task :deploy => :environment doto :before_hook doenddeploy do#重新拉git服务器上的最新版本,即使没有改变invoke :'git:clone'#重新设定shared_path位置invoke :'deploy:link_shared_paths'invoke :'bundle:install'invoke :'rails:db_migrate'invoke :'rails:assets_precompile'invoke :'deploy:cleanup'to :launch doqueue "mkdir -p #{deploy_to}/#{current_path}/tmp/"# queue "chown -R www-data #{deploy_to}"queue "touch #{deploy_to}/#{current_path}/tmp/restart.txt"endend
end

这样一来mina的基本配置就完成,接下来只要将你开发环境的项目上传到git服务器,然后运行下面的命令就完成了

mina deploy

完成部署后,你就可以在指定的服务器目录下看到你的项目,目录结构如下

  • current -当前版本目录也就是项目目录
  • last_version -版本号
  • releases/ -过去的版本
  • scm/
  • shared/ 先前shared_path所设定另外拉出来的文件都在这里
  • tmp/

这里需要注意的几点
1.shared_path里面的文件不仅仅是表示这些文件会在服务器目录中出现在另外的目录里,也表示这些文件或者目录不会受到git版本库的控制,也就是说这些文件的配置必须在你服务器中手动去配置,这两个文件包括database.yml和secrets.yml,在shared/config目录下
2.针对deploy最好在服务器创建一个使用者,并针对他创建一个ssh authorized_keys,这里直接使用了root身份,参考centos7 服务器部署ssh证书授权登录,这样做能避免每次部署的时候都需要输入服务器账号密码

可能会遇到的问题

由于生产环境一般会搭配类似于postgresql等成熟数据库,这里我就举出一个搭建postgresql,首先是启动数据库时(centos 7下),如果遇到问题请使用下面的命令就能看到详细的错误信息

systemctl status postgresql-9.4.service -l

然后在跑mina deploy时可能会报类似于这样的一个错误

 Gem::LoadError: Specified 'postgresql' for database adapter, but the gem is not loaded. Add `gem 'pg'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord).

从错误信息上能很明显的看出是因为没有安装pg这个包导致的,但是有一种情况是明明在项目的Gemfile上写上了pg但还是跑不过,造成这个的原因,可能是由于你的服务器环境缺少了pg的头文件导致的,如果是在centos下,只需要执行下面命令就能解决

yum install postgresql-libs
yum install postgresql-devel

Puma

首先在你的Gemfile里加上

rubygem puma

然后在config目录下手动创建一个puma.rb文件,配置puma.rb文件

ruby#!/usr/bin/env puma#rails的运行环境
environment 'production'
threads 2, 64
workers 4#项目名
app_name = "ruby_sample"
#项目路径
application_path = "/var/www/#{app_name}"
#这里一定要配置为项目路径下地current
directory "#{application_path}/current"#下面都是 puma的配置项
pidfile "#{application_path}/shared/tmp/pids/puma.pid"
state_path "#{application_path}/shared/tmp/sockets/puma.state"
stdout_redirect "#{application_path}/shared/log/puma.stdout.log", "#{application_path}/shared/log/puma.stderr.log"
bind "unix://#{application_path}/shared/tmp/sockets/#{app_name}.sock"
activate_control_app "unix://#{application_path}/shared/tmp/sockets/pumactl.sock"#后台运行
daemonize true
on_restart doputs 'On restart...'
end
preload_app!

这里需要注意的地方

  • threads - puma的线程数,第一个参数是最小的线程数,第二个参数是最大线程数
  • bind - 这个指定的是puma运行时产生的socket,后面nginx会用到
  • 这里所有对应的目录是在deploy配置中配置的,如果需要更改配置目录,deploy.rb也需要相应的更改

Nginx

下载安装nginx后,打开nginx的配置文件nginx.conf进行配置

nginx  worker_processes  1;error_log  /var/log/nginx/error.log warn;pid        /var/run/nginx.pid;events {worker_connections  1024;}http {include       /etc/nginx/mime.types;default_type  application/octet-stream;log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log  /var/log/nginx/access.log  main;sendfile        on;#tcp_nopush     on;keepalive_timeout  65;#gzip  on;#include /etc/nginx/conf.d/*.conf;upstream deploy {server unix:///var/www/ruby_sample/shared/tmp/sockets/ruby_sample.sock;}server {listen 80;server_name your.server.domain.ip; # change to match your URLroot /var/www/ruby_sample/current/public; # I assume your app is located at this locationlocation / {proxy_pass http://deploy; # match the name of upstream directive which is defined aboveproxy_set_header Host $host;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}location ~* ^/assets/ {# Per RFC2616 - 1 year maximum expiryexpires 1y;add_header Cache-Control public;# Some browsers still send conditional-GET requests if there's a# Last-Modified header or an ETag header even if they haven't# reached the expiry date sent in the Expires header.add_header Last-Modified "";add_header ETag "";break;}}}

这里只需要注意的是

  • upstream中 server 要配置成你在puma中bind的 socket就行了
  • root要设置成你服务器项目的根目录,也就是puma.rb中的 directory

接下里只需要重启nginx服务器,整个rails的环境就搭建完成了

  nginx -s reload

如果完成了配置后访问站点是504,那么可能是两种情况,一是服务器防火墙问题,二是rails环境密钥的问题,请在使用passenger在Centos7部署nginx+Ruby on Rails中寻找答案

Ruby on Rails 终极部署方案 nginx+mina+puma相关推荐

  1. keepalive+nginx实现负载均衡高可用_高可用、负载均衡 集群部署方案:Keepalived + Nginx + Tomcat...

    前言:初期应用较小,一般以单机部署为主,即可满足业务的需求,随着业务的不断扩大,单机部署的模式无法承载这么大的业务量,需要进行服务集群化的部署,本文主要介绍服务器Tomcat多实例部署,搭载Keepa ...

  2. 视频教程-Ruby on Rails打造企业级RESTful API项目实战我的云音乐-Ruby/Rails

    Ruby on Rails打造企业级RESTful API项目实战我的云音乐 任苹蜻,爱学啊创始人 & CEO,曾就职于某二车手公司担任Android工程师后离职创办爱学啊,我们的宗旨是:人生 ...

  3. bdd cucumber_如何使用BDD构建坚如磐石的Ruby on Rails应用

    bdd cucumber by Marko Anastasov 通过Marko Anastasov 如何使用BDD构建坚如磐石的Ruby on Rails应用 (How to build rock-s ...

  4. 用Ruby on Rails实现适应各种平台的在线Office文档预览

    前言 在许多Web应用中都需要预览文档的功能.而用户可能用不同的设备访问Web应用,可能是装有Windows系统的PC台式机,也有可能是iOS系统的iPad.一般来说,要预览的文档通常是主流的Offi ...

  5. 用 Ruby on Rails 实现适应各种平台的在线 Office 文档预览

    http://ruby-china.org/topics/17309 前言 在许多Web应用中都需要预览文档的功能.而用户可能用不同的设备访问Web应用,可能是装有Windows系统的PC台式机,也有 ...

  6. Ruby on Rails的核心特性是什么?

    Ruby on Rails好像一直处于争论的风口浪尖.大多数争论的核心是其所宣称的令人惊异的生产力.作者Bruce Tate已经开始理解Rails并不是一个更好的工具,而是一个不同类型的工具.本文研究 ...

  7. 一个使用Ruby on Rails开发LBS网站的简单实例

    一个使用Ruby on Rails开发LBS网站的简单实例 cheungmine 2011-7 这几天一直在学习使用Ruby on Rails(RoR),想建立一个功能全面一点的LBS(Locatio ...

  8. 范凯谈Ruby on Rails项目实践

    Summary 在本次采访中,JavaEye站长范凯结合自己的实际开发经验,分享了在使用Ruby on Rails的过程中所应注意的事项,比如选择RoR的原因.用RoR开发的优势.网站的配置和部署.所 ...

  9. ruby oracle数据,从 Ruby on Rails 连接到 Oracle

    开发人员:Ruby on Rails 从 Ruby on Rails 连接到 Oracle 作者:Obie Fernandez 了解如何从一个 Rails 应用程序连接到 Oracle 和与其相关的验 ...

最新文章

  1. Nginx中worker connections问题的解决方法
  2. python访问服务器注册表,如何在Python中使用写入权限打开Windows注册表
  3. C和C++Everything教程的简介
  4. 可以发外链的网站_企业网站上线后,何提升网站排名?
  5. 【Auto.js】使用命令删除图片后,更新图库缓存
  6. SAP Fiori 应用 My Appointment - Belonging to me, Search by team, Search by group
  7. javafx中的tree_JavaFX中的塔防(4)
  8. ajax参数中有加号,浅谈在js传递参数中含加号(+)的处理方式
  9. java中forward和redirect_好程序员Java教程分享:Forward和Redirect的区别
  10. 【软件工程导论题型大总结】画图题总结
  11. 导出java applet_Java Applet基础——输出HelloWorld
  12. oracle中锁表语句,oracle查询锁表解锁语句
  13. VoIP的落地通信模型和要考虑几个大的方面问题及基本概念和交互流程整理
  14. 电脑快捷键大全 Ctrl
  15. 双循环背景下的全球供应链机遇与挑战
  16. linux 模拟误码率,基于System View的比特误码率测试的仿真研究
  17. DevOps-持续集成持续部署二
  18. 解决Edge默认打开PDF内存不足
  19. HTML5(李炎恢)学习笔记一 ------------- HTML5的概述
  20. java测试题一附答案,Java考试题30道(附答案)

热门文章

  1. day21-python模块
  2. 数据库事务处理差异:可提交读和重复读区别
  3. 配置管理-SVN使用指南-Linux
  4. ★教师工资为什么这么低?
  5. 汇编中16进制的写法问题
  6. 使用cocoaPods一键集成第三方登录(新浪微博,qq,微信)
  7. C#中JSON和对象之间互相转换功能示例
  8. MFC:通过代码简单理解进程间的通讯机制——共享内存
  9. C#中的继承与多态还有接口
  10. c#读取string类型的xml格式的字符串