Deploy Rails App

2018-03-01 by Ray Chou

1 Web Server

1.1 Apache vs Nginx

它們只能提供靜態檔案,如果加上 modules,也能提供像 PHP 寫的動態 web apps。

Apache 比較受歡迎,而且功能比較多;Nginx 比較小也比較快,但是功能比較少。

單靠 Apache 或 Nginx 都不能直接提供 Ruby web apps,還要跟某些附件組合在一起才行。

Apache 跟 Nginx 也能當做 reverse proxies 來用,也就是說,當它們收到一個 HTTP 請求進來的時候,會把它轉給另一個 server,這個 server 也能以 HTTP 交談。當這個 server 回應一個 HTTP response,Apache/Nginx 會把這個 response 回傳到 client 端。

註:網路上 Deploy Rails App 相關文章大多使用 Nginx

參考 "A Web server vs. an app server" by Justin Weiss

2 App Server

目前所有的 Ruby app servers 都能以 HTTP 交談,不過有些 app servers 可以直接公開在 Internet 的 port 80,其他的則不行。

可以直接公開到 Internet 的 App servers:Phusion Passenger, Rainbows

不能直接公開到 Internet 的 App servers:Unicorn, Thin, Puma.

為什麼有些 app servers 必須放在 reverse proxy 的後面?

  • 某些 app servers 一個 process 一次只能處理一個 request。如果你想要同時處理兩個 requests,那你需要執行多個 app server instances,每為都為同一個 Ruby app 提供服務。這些 app server processes 的集合稱為 app server cluster。然後你要設定 Apache 或 Nginx 為這個 cluster 提供 reverse proxy。Apache/Nginx 會將 requests 分散到這個 cluster 裡的 instances。
  • Web server 可以對 requests 以及 responses 做 buffer,以防這個 app server 受到「緩慢的 client 端」影響。有時候某些 HTTP client 端不能很快的傳送或接收資料。當你的 app server 在等待 client 端傳送完整的 request 或接收完整的 response 的時候,你不會希望你的 app server 其他什麼事都不能做。Apache 和 Nginx 非常擅於同時處理許多事,因為它們不是 multithreaded 就是 evented。
  • 大部份的 app servers 也能處理靜態檔案,但並不是特別擅長。而 Apache 和 Nginx 做起來很快。
  • 通常會設定 Apache/Nginx 直接處理靜態檔案,但是把其他 request 轉給 app server,這是很好的安全措施。Apache 和 Nginx 非常成熟,可以保護 app server 不受到一些可能是惡意的 requests 損害。

2.1 比較

Unicorn vs. Puma vs. Passenger: which app server is right for you? 2017 by Derek

重點:Passenger 要付費的企業版才有 Multithread 功能。

2.2 Puma

Puma: A modern, concurrent web server for Ruby.

"How To Deploy a Rails App with Puma and Nginx on Ubuntu 14.04", 2015-04-01 by by Mitchell Anicas

Rails Server with Apache + Puma (via reverse proxy) 2015-01-18 by Deniel

3 Rack

Rack 讓任何一個 app servers 都可以執行你的 Rails app.

你可以把 Rack 想成 Ruby web frameworks (例如 Rails) 和 app servers 都會說的一種共同語言。因為彼此都會同個語言,所以 Unicorn 跟 Rails 不必知道對方是什麼東西就可以交談。

4 Capistrano

前面提到的 deployment 都是指的如何在一部伺服器上啟動一個 Ruby app.

但在這之前還有許多準備工作要做,例如:

  • 將程式碼上傳到 server 上
  • 安裝相關的 libraries
  • 設定或 migrating 資料庫
  • 起動或停止相關的服務
  • 其他設定

在 Capistrano 的語彙中,deployment 指的就是這些準備工作。Capistrano 並不是一個 application server,而是一個處理這些準備工作的自動化工具。你告訴 Capistrano 你的 server 在哪裡,以及每當你要 deploy 一個新版 app 的時候要執行哪些命令,Capistrano 會為你將 Rails app 上傳到 server 上,並執行你所指定的命令。

Capistrano 總是要跟 application server 搭配使用。它不能取代 application servers。同樣的,application servers 也不能取代 Capistrano,它們可以和 Capistrano 搭配使用。

當然你也可以不使用 Capistrano. 如果你喜歡自己用 FTP 上傳 Ruby app,然後每次手動執行相同的步驟,那當然可以這麼做。其他人則是厭倦了,所以他們用 Capistrano 來自動化這些步驟。