牛骨文教育服务平台(让学习变的简单)

6.5 生产环境部署

概要:

本课时讲解如何在 linux 服务器上部署 Rails 项目。

知识点:

  1. linux
  2. ssh
  3. rvm
  4. nginx
  5. puma
  6. mina
  7. crontab

正文

现在,我们完成了一个简单的 Rails 项目,我们把它部署到一台 linux 服务器上。

6.5.1 Linux 服务器

为什么原则 Linux 服务器,原因很简单:方便。网络上有很多 Rails 部署的文章和问题解答,我们这里不做资料大搜罗,只讲讲部署的思路。

Linux 我们选择常用的 CentOS 或者 Ubuntu 操作系统。有一些服务器会预制一些软件,比如 apache,mysql(除了 client 还会默认安装 server),这里我选择一台只安装了操作系统的云服务器。

6.5.2 SSH

6.5.2.1 开发机器连接服务器

在我们安装,调试和部署环节中,最重要的工具是 ssh。

SSH 为 Secure Shell 的缩写,由 IETF 的网络工作小组(Network Working Group)所制定;SSH 为建立在应用层和传输层基础上的安全协议。SSH 是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。SSH最初是UNIX系统上的一个程序,后来又迅速扩展到其他操作平台。SSH在正确使用时可弥补网络中的漏洞。SSH客户端适用于多种平台。几乎所有UNIX平台—包括HP-UX、Linux、AIX、Solaris、Digital UNIX、Irix,以及其他平台,都可运行SSH。(百度百科)

我们现在自己的开发机器上,创建 ssh:

ssh-keygen -t rsa

这样,在 ~/.ssh/ 目录下创建了两个文件:id_rsa(私钥),id_rsa.pub(公钥)。公钥放置在我们管理的服务器上,私钥是我们连接服务器的关键,如果有必要,需要在其他地方做一个备份,如果开发机器损坏或丢失,而服务器又无法连接的话,会造成巨大的损失和时间浪费。当然,一般云服务器会提供应急的 web 管理界面,如果出现刚才讲述的情形,我们重新创建一份私钥和公钥,并且替换服务器上的公钥即可。

现在,我们在服务器上创建一个部署项目的账号,deploy:

useradd deploy

注意,我们登录这个账号,并且也创建一份 ssh 的公钥和私钥,为什么?因为我们的开发机器需要连接github,bitbucket 这种代码仓库,它也是要通过 ssh 连接的。所以我们连接的形式是:

开发机器 ---ssh---> 服务器 ---ssh---> 代码仓库

现在,我们把公钥传递到服务器上:

scp ./ssh/id_rsa.pub deploy@domain:/~/.ssh/authorized_keys

authorized_keys 是公钥在服务器上的新名字,这个名字可以改掉。

为了避免每次登陆服务器都输入密码(也是防止密码被暴力破解),我们配置下服务器的 sshd。这个文件通常在 /etc/ssh/sshd_config

AuthorizedKeysFile      .ssh/authorized_keys [1]
PermitEmptyPasswords    no [2]
PermitRootLogin         no [3]
PasswordAuthentication  no [4]

[1] 这是一种适合多用户的配置,比如,多个开发者登陆服务器,sshd 会校验每个登陆账户下的 .ssh/authorized_keys。

[2] 禁止空密码访问,这是默认的

[3] 禁止 root 访问,当我们开通服务器时,这个选项默认是 yes,这样我们可以使用 root 登陆。当设置完 ssh 后,建议第一时间关闭它。

[4] 不使用密码校验,这是 ssh 会自动读取、开发机器上的私钥校验,如果成功匹配,则自动登陆服务器。

设置完后,重启 sshd 服务:

/etc/init.d/sshd restart

这时,我不建议立刻退出当前的 shell,建议新开一个终端窗口进行登陆测试。

6.5.2.2 服务器连接代码仓库

从服务器连接代码仓库,比如 github 或者 bitbucket,还是国内的 gitcafe,原理都是一样,需要把 公钥粘贴到账户的 “SSH Keys” 中,然后使用命令行测试,这里给出常用的测试命令:

ssh -T git@github.com
ssh -T git@bitbucket.org
ssh -T git@gitcafe.com

如果提示成功,说明你可以正常的使用 ssh 形式连接代码仓库了。

6.5.3 RVM

在我们第一章的讲解中,已经在本地安装了 RVM,服务器的安装是相同的步骤,只是要注意的是,我们已经使用 deploy 用户安装了 ssh,也用这个账号来安装 rvm,并且正常运行 ruby。

6.5.4 Nginx

Nginx 是目前应用最广的 web 服务器之一。关于 linux 的论述也有很多,我们这里只关注它和 Rails 项目的部署。

我们下载目前的 stable 版本,1.8.0,安装之后,我们为 Rails 项目建立一个配置,这个配置通常放置在 sites-enabled 中方便维护,不过要确保,该目录内的配置已经加载到 nginx 中:

/.../nginx/conf/nginx.conf

http {
  include ../sites-enabled/*.conf;
}

Nginx 和 Rails 的通信有两种方式,tcp 和 socket。现在我们使用 socket 通信。

为了更多的收集配置方法,我在 这里 建立了一个代码仓库,大家可查看各种配置方式。在 这里 还有其他的一些配置方式摘要。

6.5.5 Puma

pumaunicornpassenger 是常用的 Rails Server,这里我们使用 puma

gem "puma"

安装这之后,我们有两个命令,pumapumactl。当 rails s 时,自动使用的是puma 启动,为了在服务器上启动,我们增加配置文件 config/puma.rb

在服务器启动 puma,使用 pumactl 命令,来进行 start/stop/restart 操作。

pumactl -F config/puma.rb start/stop/restart

6.5.6 Mina

为了方便部署新开发的代码,我们需要自动部署工具,常用的是 capistranomina。这里我们使用 mina 来部署代码。

mina 的代码在 这里

我们先 mina setup 必备的部署目录,以及需要的 public/assetslogtmp 等目录。

然后只需 mina deploy 即可部署最新的代码。同时,在 deploy 中包装了 puma 启动的命令,使用时为 mina puma:start/stop/restart

6.5.7 Crontab

如果有一些需要定期执行的 rake,或者定期清理 log,tmp,过期缓存等,需要执行 crontab 操作,为了方便编写该语法,可以使用 whenever

wheneverize .
[add] writing `./config/schedule.rb"

编辑完 schedule.rb 后,运行 whenever 查看结果,并将命令粘贴到 crontab -e 中。

说明:

本章目的是介绍部署思路,如果有部署问题,可以搜索到很多解决方案,而且,Ruby China 社区 有大量经验分享,这是国内质量最高的 Ruby 社区,其中有很多经验贴。

如果有问题通过搜索无法解决,可以在 Ruby 社区发帖询问,发帖时,请仔细阅读 本帖