關於從 Heroku 跳到 Render 這件事情

前言

Heroku 一直以來是我滿愛用的後端平台,可是 Heroku 在 2022/11/28 停止了免費方案,因此不得不將網站從 Heroku 轉移到他處,所以這一篇將會介紹一下如何轉到 Render.com 以及為什麼選擇了 Render。

Heroku

Heroku

Heroku 是一個非常老牌的 PaaS 平台,許多人都很愛用,甚至練習的專案、小型專案都會選擇 Heroku 來部署,因為它的部署方式非常簡單,通常只要一個指令就可以完成,而且 Heroku 也提供了免費方案,讓大家可以免費使用,雖然免費方案有一些限制存在,但是作為學習或是練習的專案,免費方案已經足夠了。

可惜的是 Heroku 在 2022/11/28 停止了免費方案,因此許多人不得不將自己的網站從 Heroku 轉移到他處。

那麼為什麼 Heroku 停止了免費方案呢?其主要原因可以看一下這篇文章:Heroku’s Next Chapter

其中這邊的核心重點,我也擷取出來

Our product, engineering, and security teams are spending an extraordinary amount of effort to manage fraud and abuse of the Heroku free product plans.

這邊我也簡單快速翻譯一下上面這句話:

我們的產品、工程和安全團隊花了大量的精力來管理 Heroku 免費方案的詐騙和濫用。

因此 Heroku 才會停止免費方案。

Render.com

Render.com

Render 是什麼呢?基本上你如果是一名工程師,只要你查詢 Render 通常會出現各種與 Render.com 無關的資訊(就我自己查是這樣),因此通常我在 Google 搜尋時,反而會打「Render.com」,這樣比較可以找到 Render。

那麼 Render.com 跟 Heroku 一樣都是 PaaS 平台,雖然兩家提供的服務都很類似,但是在兩者還是有本質上的差異,舉例來講 Render 提供了免費方案,而 Heroku 則是停止了免費方案(廢話),以及 Render 部署的方式是使用 Docker,而 Heroku 則是使用 Git。

那麼 Render 部署的方式是使用 Docker 的狀況下,會影響到我們的專案部署嗎?我們專案要因此特別去寫 Dockerfile 嗎?答案是不用,因為 Render 在你部署專案時,會自動幫你建立 Dockerfile,並且將專案部署到 Docker 上,因此你不需要特別去寫 Dockerfile,只是部署流程會有一點點不同而已。

部署專案到 Render

接下來將會一步一步帶你部署你的 Node.js 專案到 Render 上囉。

範例程式碼

首先這邊我先提供一份範例程式碼,如果你有自己想要部署的程式碼也可以,因為這一份範例程式碼是使用 Express 產生器產生的,因此你也可以直接取用來測試。

GitHub:2022-express-example

拿到後建議你上傳到你的 GitHub 儲存庫內,因為我們會透過 GitHub 儲存庫來部署到 Render。

註冊 Render 帳號

接著麻煩請你到「Render.com」網站註冊帳號,基本上 Render 有提供滿多種的方式的,因此你可以選擇你要的方式註冊

註冊

這邊我就直接選擇 GitHub 登入,登入後你應該會看到 Render 的後台介面,接著就可以準備來部署專案囉

Render 後台

畫面上有東西是因為我本身就已經有部署一些專案到 Render 上了。

建立一個伺服器

接著一點一下上方的「New +」 應該會看到一推的新增類型

New

第一個基本上就是單純的靜態網頁,如果你是想要部署靜態網頁的話可以選「Static Site」,但是我們要部署的是一個有後端的 Node.js 專案,因此我們選擇「Web Service」

Web Service

接著你應該會進入「Create a new Web Service」的畫面,然後就在「Connect a repository」找到你要部署的專案,如果你發現你的專案沒有出現在列表上,那麼你可以點一下旁邊的「Configure account」進入到 GitHub 頁面調整一下權限,因為有可能是你的 GitHub 帳號在註冊時沒有給予 Render 權限,因此你可以在這邊重新給予權限

Configure account

到 GitHub 之後,你就可以在底下選擇你要「All repositories」還是「Only select repositories」,而這邊我是選擇「Only select repositories」,選好你要部署的儲存庫後,按下 Save 按鈕,就會被自動回到 Render 頁面就可以看到它出現在你的列表上了

Only select repositories

接著就在「Connect a repository」區塊選擇你要部署的專案,並按下 「Connect」 按鈕

Connect

按下後,你會跳到一些伺服器的設定頁面,例如這台伺服器你要叫什麼名字、主機位置、專案語言、編譯指令等等,這邊我也附上圖片,你可以參考一下

Web Setting

注意:Build Command 建議你要打完整的「npm install」而不是「npm」,這樣是會出現錯誤的。

接下來下方會有個方案選擇,這邊我們選「Free」

Free

到這邊,其實你就可以按下「Create Web Service」了,但是我們實際專案開發上還有一個步驟要做,也就是專案的環境變數設定,因此假設你有環境變數要設定的話,就請不要按下「Create Web Service」而是「Advanced」

Advanced

按下之後,你就可以看到有一個按鈕叫做「Add Environment Variable」,按下之後就可以新增你的環境變數了

Add Environment Variable

新增完之後,就可以按下「Create Web Service」,按下後你就會看到你的專案正在被部署到 Render

部署中

部署過程會稍微慢一點,因為它需要將你的專案打包成 Docker Image,並且部署到 Render 的伺服器上,所以會稍微慢一點。

當你看到「node ./bin/www」的時候,就代表你的專案已經部署完成了

部署完成

接著你就可以透過上方網址來看看你的專案是否正常運作啦~

專案網址

那麼這邊我也附上我部署的專案網址:「https://two022-express-example.onrender.com/」(何時刪掉我也不知道,只是示範而已。)

最後這邊我也附上翻譯畫面:

主機畫面

注意事項

這邊要注意一下 Render 跟 Heroku 一樣,一段時間沒有任何請求時,主機將會進入休眠狀態,所以你的專案第一次請求時,可能會需要稍微等一下,才會回應你的請求,以官方文件解釋是 15 分鐘內沒有任何請求的話就會進入睡眠模式,再次甦醒約需要等 30 秒左右

Web Services on the free instance type are automatically spun down after 15 minutes of inactivity. When a new request for a free service comes in, Render spins it up again so it can process the request.
This can cause a response delay of up to 30 seconds for the first request that comes in after a period of inactivity.

除此之外 Render 每月提供 750 小時的免費主機時間,理論上是滿夠用的,但是要注意一下,我發現 Render 在計算上是採用一整個帳號的時間,所以如果你有多個專案,那麼你的專案就會共用這 750 小時的時間,那麼你可能會在一個月內就用完這 750 小時的時間唷。

如果你想知道你目前 Free Plan 的使用情況,可以在 Render 的 Dashboard 上點你的頭像選「Billing」或是到「點這邊」也可以看到哩

結論

或許有人會問那為什麼不考慮使用 Fly.io、Vercel 等等之類的服務呢?其實就主要看你需求為主,Fly.io 我自己摸了一下是有點不太習慣,而 Vercel 則是採用 Serverless 的方式,所以終究還是要看你需求為主哩。

除此之外,這邊我也推薦一篇文章給你參考,讓你選擇最適合你的 PaaS 主機服務:

最後的最後來簡單結論一下 Render 比較需要注意的地方

休眠時間

這一天其實與原本的 與 Heroku 相同,15 分鐘內如果沒有任何請求將會進入休眠模式,再次甦醒需要 30 秒左右

免費時數共用

Render 的免費時數 750 小時是整個帳號共用的(我印象 Heroku 好像是分開的),什麼意思呢?舉例來講:你有三台主機,三台主機的開機都開了 24H,代表著 24 * 3 = 72 小時,那麼你的免費時數就會減少 72 小時,而不是一台主機 750 小時,所以你被扣除的時數是 750 - 72 = 678 小時。

而免費時數的重置時間是在每個月 1 號。

編譯時間與開機時間是分開的

這邊也要注意 render 的免費時數裡面包含了開機時間、編譯時間

  • 開機時間免費時數共 750 小時
  • 編譯時間免費時數共 400 小時

而你也可以在這邊看到你的免費時數使用情況。

Image

部署速度

這陣子測試下來有發現部署的時間跟速度忽快忽慢

1
2
3
4
5
6
Dec 14 10:33:08 PM  ==> Deploying...
Dec 14 10:55:52 PM ==> Detected Node version 16.15.0
Dec 14 10:55:52 PM ==> Starting service with 'pnpm run start'
Dec 14 10:55:59 PM
Dec 14 10:55:59 PM > [email protected] start /opt/render/project/src
Dec 14 10:55:59 PM > node app.js

然後就有去查一下,結論是免費帳號的部署速度是比較慢的,可以詳見這篇

這邊也擷取核心重點

Free plans are noted as having slower deploys than paid plans, that’s one of the limitations of Free Plans

當然部署很慢的原因還是有很多種,只是有可能其中一個原因會是免費計畫的關係哩。

必須有一個 HTTP Endpoint

這是什麼意思呢?以 Node.js 來講,就是你必須有一個 HTTP Server,例如:Express,這樣子 Render 才能夠知道你的服務是什麼,也才能夠將請求導向你的服務。

因此如果你沒有 HTTP Server,那麼你會發現你部署後 Render 會一直卡在 Deploying 狀態,接著過一段時間後就被標注為 Failed。

而通常這種狀況比較常見於一些機器人的專案上,例如 Discord Bot 就不會需要 HTTP Server,所以為了解決這個問題,就會建議你引入 Express,可參考我先前開源的 Discord Bot - 妙麗·格蘭傑專案。

部署機器人

如果你是部署類似 Discord Bot 這類型的機器人,以官方建議來講,會建議你使用「Background Worker」(需付費)來部署,否則你是有很高機率發生機器人會同時啟動兩次的情況而導致發送兩次訊息。

我自己也有注意到這件事情,可是基本上這個問題在每一次部署後的,一小時內都會發生機器人同時發送兩次訊息的狀況,但是過了一段時間後就不會再發生,恢復只會發送一次訊息,所以我就沒有去付費使用「Background Worker」。

但是如果你是部署類似 Discord Bot 這類型的機器人,我建議你還是使用「Background Worker」來部署,這樣子就可以避免機器人同時發送兩次訊息的狀況。

其他限制

其他限制的話,其實可以在官方文件上找到,但那些限制我就比較沒遇到,因此就只附上官方文件給你參考哩。

參考文獻

Liker 讚賞

這篇文章如果對你有幫助,你可以花 30 秒登入 LikeCoin 並點擊下方拍手按鈕(最多五下)免費支持與牡蠣鼓勵我。
或者你可以也可以請我「喝一杯咖啡(Donate)」。

Buy Me A Coffee Buy Me A Coffee

Google AD

撰寫一篇文章其實真的很花時間,如果你願意「關閉 Adblock (廣告阻擋器)」來支持我的話,我會非常感謝你 ヽ(・∀・)ノ