本課時(shí)講解如何在 linux 服務(wù)器上部署 Rails 項(xiàng)目。
現(xiàn)在,我們完成了一個(gè)簡(jiǎn)單的 Rails 項(xiàng)目,我們把它部署到一臺(tái) linux 服務(wù)器上。
為什么原則 Linux 服務(wù)器,原因很簡(jiǎn)單:方便。網(wǎng)絡(luò)上有很多 Rails 部署的文章和問題解答,我們這里不做資料大搜羅,只講講部署的思路。
Linux 我們選擇常用的 CentOS 或者 Ubuntu 操作系統(tǒng)。有一些服務(wù)器會(huì)預(yù)制一些軟件,比如 apache,mysql(除了 client 還會(huì)默認(rèn)安裝 server),這里我選擇一臺(tái)只安裝了操作系統(tǒng)的云服務(wù)器。
在我們安裝,調(diào)試和部署環(huán)節(jié)中,最重要的工具是 ssh。
SSH 為 Secure Shell 的縮寫,由 IETF 的網(wǎng)絡(luò)工作小組(Network Working Group)所制定;SSH 為建立在應(yīng)用層和傳輸層基礎(chǔ)上的安全協(xié)議。SSH 是目前較可靠,專為遠(yuǎn)程登錄會(huì)話和其他網(wǎng)絡(luò)服務(wù)提供安全性的協(xié)議。利用 SSH 協(xié)議可以有效防止遠(yuǎn)程管理過程中的信息泄露問題。SSH最初是UNIX系統(tǒng)上的一個(gè)程序,后來又迅速擴(kuò)展到其他操作平臺(tái)。SSH在正確使用時(shí)可彌補(bǔ)網(wǎng)絡(luò)中的漏洞。SSH客戶端適用于多種平臺(tái)。幾乎所有UNIX平臺(tái)—包括HP-UX、Linux、AIX、Solaris、Digital UNIX、Irix,以及其他平臺(tái),都可運(yùn)行SSH。(百度百科)
我們現(xiàn)在自己的開發(fā)機(jī)器上,創(chuàng)建 ssh:
ssh-keygen -t rsa
這樣,在 ~/.ssh/ 目錄下創(chuàng)建了兩個(gè)文件:id_rsa(私鑰),id_rsa.pub(公鑰)。公鑰放置在我們管理的服務(wù)器上,私鑰是我們連接服務(wù)器的關(guān)鍵,如果有必要,需要在其他地方做一個(gè)備份,如果開發(fā)機(jī)器損壞或丟失,而服務(wù)器又無法連接的話,會(huì)造成巨大的損失和時(shí)間浪費(fèi)。當(dāng)然,一般云服務(wù)器會(huì)提供應(yīng)急的 web 管理界面,如果出現(xiàn)剛才講述的情形,我們重新創(chuàng)建一份私鑰和公鑰,并且替換服務(wù)器上的公鑰即可。
現(xiàn)在,我們?cè)诜?wù)器上創(chuàng)建一個(gè)部署項(xiàng)目的賬號(hào),deploy:
useradd deploy
注意,我們登錄這個(gè)賬號(hào),并且也創(chuàng)建一份 ssh 的公鑰和私鑰,為什么?因?yàn)槲覀兊拈_發(fā)機(jī)器需要連接github,bitbucket 這種代碼倉庫,它也是要通過 ssh 連接的。所以我們連接的形式是:
開發(fā)機(jī)器 ---ssh---> 服務(wù)器 ---ssh---> 代碼倉庫
現(xiàn)在,我們把公鑰傳遞到服務(wù)器上:
scp ./ssh/id_rsa.pub deploy@domain:/~/.ssh/authorized_keys
authorized_keys 是公鑰在服務(wù)器上的新名字,這個(gè)名字可以改掉。
為了避免每次登陸服務(wù)器都輸入密碼(也是防止密碼被暴力破解),我們配置下服務(wù)器的 sshd。這個(gè)文件通常在 /etc/ssh/sshd_config:
AuthorizedKeysFile .ssh/authorized_keys [1]
PermitEmptyPasswords no [2]
PermitRootLogin no [3]
PasswordAuthentication no [4]
[1] 這是一種適合多用戶的配置,比如,多個(gè)開發(fā)者登陸服務(wù)器,sshd 會(huì)校驗(yàn)每個(gè)登陸賬戶下的 .ssh/authorized_keys。
[2] 禁止空密碼訪問,這是默認(rèn)的
[3] 禁止 root 訪問,當(dāng)我們開通服務(wù)器時(shí),這個(gè)選項(xiàng)默認(rèn)是 yes,這樣我們可以使用 root 登陸。當(dāng)設(shè)置完 ssh 后,建議第一時(shí)間關(guān)閉它。
[4] 不使用密碼校驗(yàn),這是 ssh 會(huì)自動(dòng)讀取、開發(fā)機(jī)器上的私鑰校驗(yàn),如果成功匹配,則自動(dòng)登陸服務(wù)器。
設(shè)置完后,重啟 sshd 服務(wù):
/etc/init.d/sshd restart
這時(shí),我不建議立刻退出當(dāng)前的 shell,建議新開一個(gè)終端窗口進(jìn)行登陸測(cè)試。
從服務(wù)器連接代碼倉庫,比如 github 或者 bitbucket,還是國內(nèi)的 gitcafe,原理都是一樣,需要把 公鑰粘貼到賬戶的 “SSH Keys” 中,然后使用命令行測(cè)試,這里給出常用的測(cè)試命令:
ssh -T git@github.com
ssh -T git@bitbucket.org
ssh -T git@gitcafe.com
如果提示成功,說明你可以正常的使用 ssh 形式連接代碼倉庫了。
在我們第一章的講解中,已經(jīng)在本地安裝了 RVM,服務(wù)器的安裝是相同的步驟,只是要注意的是,我們已經(jīng)使用 deploy 用戶安裝了 ssh,也用這個(gè)賬號(hào)來安裝 rvm,并且正常運(yùn)行 ruby。
Nginx 是目前應(yīng)用最廣的 web 服務(wù)器之一。關(guān)于 linux 的論述也有很多,我們這里只關(guān)注它和 Rails 項(xiàng)目的部署。
我們下載目前的 stable 版本,1.8.0,安裝之后,我們?yōu)?Rails 項(xiàng)目建立一個(gè)配置,這個(gè)配置通常放置在 sites-enabled 中方便維護(hù),不過要確保,該目錄內(nèi)的配置已經(jīng)加載到 nginx 中:
/.../nginx/conf/nginx.conf
http {
include ../sites-enabled/*.conf;
}
Nginx 和 Rails 的通信有兩種方式,tcp 和 socket?,F(xiàn)在我們使用 socket 通信。
為了更多的收集配置方法,我在 這里 建立了一個(gè)代碼倉庫,大家可查看各種配置方式。在 這里 還有其他的一些配置方式摘要。
puma,unicorn,passenger 是常用的 Rails Server,這里我們使用 puma。
gem 'puma'
安裝這之后,我們有兩個(gè)命令,puma 和 pumactl。當(dāng) rails s 時(shí),自動(dòng)使用的是puma 啟動(dòng),為了在服務(wù)器上啟動(dòng),我們?cè)黾优渲梦募?config/puma.rb。
在服務(wù)器啟動(dòng) puma,使用 pumactl 命令,來進(jìn)行 start/stop/restart 操作。
pumactl -F config/puma.rb start/stop/restart
為了方便部署新開發(fā)的代碼,我們需要自動(dòng)部署工具,常用的是 capistrano 和 mina。這里我們使用 mina 來部署代碼。
mina 的代碼在 這里。
我們先 mina setup 必備的部署目錄,以及需要的 public/assets,log,tmp 等目錄。
然后只需 mina deploy 即可部署最新的代碼。同時(shí),在 deploy 中包裝了 puma 啟動(dòng)的命令,使用時(shí)為 mina puma:start/stop/restart。
如果有一些需要定期執(zhí)行的 rake,或者定期清理 log,tmp,過期緩存等,需要執(zhí)行 crontab 操作,為了方便編寫該語法,可以使用 whenever。
wheneverize .
[add] writing `./config/schedule.rb'
編輯完 schedule.rb 后,運(yùn)行 whenever 查看結(jié)果,并將命令粘貼到 crontab -e 中。
說明:
本章目的是介紹部署思路,如果有部署問題,可以搜索到很多解決方案,而且,Ruby China 社區(qū) 有大量經(jīng)驗(yàn)分享,這是國內(nèi)質(zhì)量最高的 Ruby 社區(qū),其中有很多經(jīng)驗(yàn)貼。
如果有問題通過搜索無法解決,可以在 Ruby 社區(qū)發(fā)帖詢問,發(fā)帖時(shí),請(qǐng)仔細(xì)閱讀 本帖。