ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 6.5 生产环境部署 ## 概要: 本课时讲解如何在 linux 服务器上部署 Rails 项目。 ## 知识点: 1. linux 1. ssh 1. rvm 1. nginx 1. puma 1. mina 1. 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](http://nginx.org/) 是目前应用最广的 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 通信。 为了更多的收集配置方法,我在 [这里](https://github.com/liwei78/rails4-puma-mina-nginx-deploy) 建立了一个代码仓库,大家可查看各种配置方式。在 [这里](https://github.com/liwei78/linux-doc) 还有其他的一些配置方式摘要。 ### 6.5.5 Puma [puma](http://puma.io),[unicorn](http://unicorn.bogomips.org/),[passenger](https://www.phusionpassenger.com/) 是常用的 Rails Server,这里我们使用 [puma](https://github.com/puma/puma)。 ~~~ gem 'puma' ~~~ 安装这之后,我们有两个命令,`puma` 和 `pumactl`。当 `rails s` 时,自动使用的是puma 启动,为了在服务器上启动,我们增加配置文件 `config/puma.rb`。 在服务器启动 puma,使用 `pumactl` 命令,来进行 `start/stop/restart` 操作。 ~~~ pumactl -F config/puma.rb start/stop/restart ~~~ ### 6.5.6 Mina 为了方便部署新开发的代码,我们需要自动部署工具,常用的是 [capistrano](https://github.com/capistrano/capistrano) 和 [mina](http://mina-deploy.github.io/mina/)。这里我们使用 mina 来部署代码。 mina 的代码在 [这里](https://github.com/liwei78/rails-practice-code/blob/master/chapter_6/shop/config/deploy.rb)。 我们先 `mina setup` 必备的部署目录,以及需要的 `public/assets`,`log`,`tmp` 等目录。 然后只需 `mina deploy` 即可部署最新的代码。同时,在 deploy 中包装了 puma 启动的命令,使用时为 `mina puma:start/stop/restart`。 ### 6.5.7 Crontab 如果有一些需要定期执行的 rake,或者定期清理 log,tmp,过期缓存等,需要执行 crontab 操作,为了方便编写该语法,可以使用 [whenever](https://github.com/javan/whenever)。 ~~~ wheneverize . [add] writing `./config/schedule.rb' ~~~ 编辑完 `schedule.rb` 后,运行 `whenever` 查看结果,并将命令粘贴到 `crontab -e` 中。 说明: 本章目的是介绍部署思路,如果有部署问题,可以搜索到很多解决方案,而且,[Ruby China 社区](https://ruby-china.org/topics) 有大量经验分享,这是国内质量最高的 Ruby 社区,其中有很多经验贴。 如果有问题通过搜索无法解决,可以在 Ruby 社区发帖询问,发帖时,请仔细阅读 [本帖](https://ruby-china.org/topics/24325)。