本课时讲解如何在 linux 服务器上部署 Rails 项目。
现在,我们完成了一个简单的 Rails 项目,我们把它部署到一台 linux 服务器上。
为什么原则 Linux 服务器,原因很简单:方便。网络上有很多 Rails 部署的文章和问题解答,我们这里不做资料大搜罗,只讲讲部署的思路。
Linux 我们选择常用的 CentOS 或者 Ubuntu 操作系统。有一些服务器会预制一些软件,比如 apache,mysql(除了 client 还会默认安装 server),这里我选择一台只安装了操作系统的云服务器。
在我们安装,调试和部署环节中,最重要的工具是 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,建议新开一个终端窗口进行登陆测试。
从服务器连接代码仓库,比如 github 或者 bitbucket,还是国内的 gitcafe,原理都是一样,需要把 公钥粘贴到账户的 “SSH Keys” 中,然后使用命令行测试,这里给出常用的测试命令:
ssh -T git@github.com
ssh -T git@bitbucket.org
ssh -T git@gitcafe.com
如果提示成功,说明你可以正常的使用 ssh 形式连接代码仓库了。
在我们第一章的讲解中,已经在本地安装了 RVM,服务器的安装是相同的步骤,只是要注意的是,我们已经使用 deploy 用户安装了 ssh,也用这个账号来安装 rvm,并且正常运行 ruby。
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 通信。
为了更多的收集配置方法,我在 这里 建立了一个代码仓库,大家可查看各种配置方式。在 这里 还有其他的一些配置方式摘要。
puma,unicorn,passenger 是常用的 Rails Server,这里我们使用 puma。
gem 'puma'
安装这之后,我们有两个命令,puma
和 pumactl
。当 rails s
时,自动使用的是puma 启动,为了在服务器上启动,我们增加配置文件 config/puma.rb
。
在服务器启动 puma,使用 pumactl
命令,来进行 start/stop/restart
操作。
pumactl -F config/puma.rb start/stop/restart
为了方便部署新开发的代码,我们需要自动部署工具,常用的是 capistrano 和 mina。这里我们使用 mina 来部署代码。
mina 的代码在 这里。
我们先 mina setup
必备的部署目录,以及需要的 public/assets
,log
,tmp
等目录。
然后只需 mina deploy
即可部署最新的代码。同时,在 deploy 中包装了 puma 启动的命令,使用时为 mina puma:start/stop/restart
。
如果有一些需要定期执行的 rake,或者定期清理 log,tmp,过期缓存等,需要执行 crontab 操作,为了方便编写该语法,可以使用 whenever。
wheneverize .
[add] writing `./config/schedule.rb'
编辑完 schedule.rb
后,运行 whenever
查看结果,并将命令粘贴到 crontab -e
中。
说明:
本章目的是介绍部署思路,如果有部署问题,可以搜索到很多解决方案,而且,Ruby China 社区 有大量经验分享,这是国内质量最高的 Ruby 社区,其中有很多经验贴。
如果有问题通过搜索无法解决,可以在 Ruby 社区发帖询问,发帖时,请仔细阅读 本帖。