部署 ASP.NET Core 2.1 應用程式到 Heroku 平台

這篇筆記會說明如何將 ASP.NET Core 2.1 應用程式部署到 Heroku 平台,以及完成這些操作所需要知道的(最低限度)的基礎知識。包括:
  • Heroku 是什麼,以及 Heroku 平台的免費方案有哪些限制。
  • 建立一個最基本的 ASP.NET Core 2.1 Web API 應用程式(直接用 Visual Studio 2017 附的範本),並且把它部署到 Heroku 平台。
  • 順便提及使用 docker image 來部署 ASP.NET Core 2.1 應用程式到 Heroku 平台所碰到的狀況。

開發環境:Windows 10 + Visual Studio 2017 + Docker CE v18.05
應用程式:ASP.NET Core 2.1。

關於 Heroku

Heroku 是一個雲端平台,開發人員可以利用它來建置和部署應用程式。我才剛接觸,懂的不多:
  • 支援多種程式語言。目前內建的程式語言並未包含 C#,但我們可以透過第三方工具或上傳 docker image 的方式來部署 .NET 應用程式。
  • 有免費和付費方案,詳情參見 https://www.heroku.com/pricing。注意免費方案有個限制:只要 30 分鐘內沒有任何動靜就會休眠(下一個使用者應會感受到 app 明顯反應遲鈍)。
  • 欲使用 Heroku,必須在本機安裝它的 CLI(命令列)工具。(本文沒有說明安裝此工具的步驟)

除了應用程式的部署和運行環境,Heroku 也有提供資料服務,內建的服務有 PostgreSQL、Redis、和 Kafka。至於其他資料庫系統,如 MySQL、MongoDB  等,則可以到 Heroku 市集裡面找找看有沒有合用的第三方套件。

這裡再多提一點 Heroku 內建的 PostgreSQL 資料庫服務。其產品名稱是 Heroku Postgres,免費和付費的方案都有。各方案的價位、運算能力和限制,官方網站上面都有說明。我的需求非常陽春,故只關注免費方案。

Heroku Postgres 的免費方案叫做 hobby-dev,而最便宜的付費方案叫做 hobby-basic。在寫這篇筆記時,免費的 hobby-dev 方案有下列限制:
  • 最多可儲存 10,000 筆資料。
  • 當資料總筆數達 7,000 時,資料庫的擁有者(你)會收到系統發送的 email,通知你資料筆數快要達到免費方案的限制了。
  • 當資料筆數超過限制,新增資料時便會失敗,但讀取、修改、和刪除操作都可以正常執行。當資料筆數減少至免費方案的限制以下時,等下一次系統檢查資料筆數限制(最久可能要等個幾分鐘),便可以繼續新增資料。
  • 最大同時連線數量為 20。
  • 沒有 in-memory 快取。
  • 不支援 fork/follow(資料庫的複製與主從關係)。
  • 不支援「昂貴查詢」。
  • 每個月最多 4 個小時的停機時間(downtime)。
  • 沒有資料庫 logs。

其實我目前還沒有用到資料庫,只是先大概調研一下而已。接下來,還是趕緊動手試試它的部署程序,實際感受一下它是否夠方便,以及可能會碰到什麼狀況。

註冊 Heroku 帳號的部分,這裡省略不寫。底下會說明如何在 Heroku 平台上建立應用程式,以及如何把本機(開發機器)上面的 ASP.NET Core 2.1 應用程式部署到 Heroku。

Step 1: 在 Heroku 平台上建立 app

在個人入口的頁面可以找到建立 app 的連結,如下圖:

在建立 app 的頁面,只需要填寫 app 名稱,並選擇地區:


圖中的 Add to pipeline 連結可以順便指定應用程式的「管線」。若有建立管線,在部署 app 的時候可讓你區分 staging 和 production 環境。從官方文件看來,我們可以隨時建立管線,並將應用程式加入新建立的管線。目前我選擇先不建立管線。

點一下[Create app],便會建立應用程式,然後進入應用程式的部署設定頁,裡面會顯示你的應用程式目前所使用的部署方法。參考下圖:


如圖中所示,部署方法有四種:Heroku Git、GitHub、Dropbox、Container Registry。我使用預設的 HerokuGit。下方會告訴你必須使用 Heroku CLI 工具來下指令,而且連指令都幫你寫好了,真貼心。

按照網頁上的指示,我先在本機安裝了 Heroku CLI,然後執行命令: "heroku login"。接著建立 git repo:

cd d:\work\Heroku
md ministep
cd ministep
git init
heroku git:remote -a ministep

這樣,開發環境的基本設定就完成了。其中的 "ministep" 就是先前在 Heroku 後台管理頁面中建立的 app 名稱。
註:成功執行 "heroku login" 命令之後,在 Windows 環境下,你的 Heroku 使用者帳號和密碼會存放在目前的 Windows 使用者個人資料夾底下的 _netrc 檔案(Linux 則是 .netrc)。

Step 2: 建立 ASP.NET Core 應用程式

在 ministep 目錄底下建立一個子目錄:source。開啟 Visual Studio 2017,在 source 目錄下建立一個 ASP.NET Core 應用程式專案。我把這個專案命名為 Ministep.Web,底下是建立專案過程中的螢幕截圖。


如果要使用 Docker image 來部署 ASP.NET Core 應用程式,可以在建立專案時勾選「Enable Docker Support」。(稍後會解釋為何沒使用 docker 來部署)

專案建立完成後,一行程式碼都不改動,先試試能否在 Visual Studio 執行此應用程式。如果一切順利,應該會在瀏覽器中開啟位址 "https://localhost:44354/api/values",並顯示以下內容:

["value1","value2"]


Step 3: 部署

一開始,我是打算用 Docker image 來部署。我參考了這篇文章:Deploy ASP.NET Core 2.0 apps on Heroku,也爬了一些討論串,但仍碰到一些狀況。有些狀況是怎麼想都想不到,例如執行命令 "heroku container:login" 時顯示失敗(結束代碼為 1)。結果,竟然是因為我用 Cmder 來執行命令所致(詳見 issue #1)。一路排除了幾個障礙,看到下圖的執行結果,以為終於到達彼岸:


果然我還是 too young too simple,最後卡在這個命令:

docker push registry.heroku.com/ministep/web

錯誤訊息如下圖:


看到 HTTP 500,我已經沒力了 Orz

顧及肝臟的健康,我決定暫且放棄 Docker 這條路,改用其他工具來部署。

我從 Heroku 市集裡面找到一個第三方工具:Heroku .NET Core Buildpack。用法非常簡單,過程也相當順利:首先,執行 "heroku buildpacks" 命令來把第三方的 build scripts 安裝到目前所在的 git repo。如下圖:


如圖中訊息所顯示的,接下來只需要把應用程式的原始碼推送至 heroku repo,這樣就完成了。下面兩張圖片就是用 TortoiseGit 推送程式碼的過程和結果:



從圖中可以看到,每次 push 至遠端  repo 的時候,就會執行先前安裝的 build scripts 來建置與部署應用程式。

上述操作完成後,用瀏覽器開啟網址 https://ministep.herokuapp.com/api/values,看看能否順利顯示先前在本機上執行時的網頁內容。如下圖:


順利成功!

小結

一行程式碼都沒寫,也沒有修改任何組態檔,也沒有申請和安裝 SSL 伺服器憑證,就可以把一個 ASP.NET Core 應用程式部署到雲端平台,還蠻方便的。當然啦,我是刻意讓應用程式保持簡單,以盡量減少初次部署到 Heroku 平台時因為基礎知識不足而遭遇各種狀況。

先前使用 Docker image 來部署 app 時碰到的狀況,我想多半也是因為我對 ASP.NET Core 2.1、Docker、Heroku 三者都還不夠熟悉,以至於花了好多時間處理茶包。改天有空再研究看看。

技術提供:Blogger.