aspnet core publish and environment
因為對於 dotnet 的 publish 以及環境變數的設定,一直都有點混淆,所以這邊就來整理一下。
佈署到哪裡? IIS 還是 Kestrel?
在 ASP.NET Core 中,我們可以使用 Kestrel 作為 Web Server,也可以使用 IIS 作為 Web Server。
而執行 dotnet publish
的時候,其實就是將專案編譯成一個可執行的檔案,並且將相關的資源檔案一起打包成一個資料夾,這個資料夾就是我們要佈署的檔案。
dotnet publish
的時候預設會產出一個web.config
給 IIS 使用,也就是說如果要佈署到 IIS,那麼在 dotnet publish
的時候必須要加上環境變數設定的指令, web.config
才會有環境變數
1 | dotnet publish -c Debug -p:EnvironmentName=Development |
1 |
|
Ref:如何透過 dotnet publish 調整 ASP․NET Core 部署到 IIS 的 Web.config 內容
那麼環境變數需要設置的是那些東西,又影響什麼呢?
環境主要用來配置跟環境相關的一些設定值,例如連線字串、NAS 儲存空間的路徑、LOG 紀錄層級等等。設定好環境變數,在應用程序中就可以使用指定的環境(”myhome”)來載入對應的設定文件(如 appsettings.myhome.json)。而在實際上發佈出去的檔案內,也會包含著各個環境的設定檔案,例如 appsettings.myhome.json、appsettings.company.json、appsettings.home.json 等等。
這些檔案會等到實際上執行的時候,再去讀取對應的設定檔案,並且載入到應用程序中。
環境變數設定檔案並不會以實體的方式合併,而是在執行時,會依照環境變數的設定,去讀取對應的設定檔案,並且載入到應用程序中。
那麼版本又是怎麼影響佈署的呢?
版本可能會有開發版本、正式版本等差異,主要的判斷依據就是以功能來區分,雖然這些區分的方式,可以透過環境變數來做,但是如果是在開發階段,可能會有一些功能是還沒有完成的,但是又想要測試,這時候就可以透過版本來做區分。假設我在 Debug 環境需要紀錄完整的資訊,於是可能透過條件式編譯來額外紀錄一些資訊,但是在 Release 環境下,就不需要紀錄這些資訊,這時候就可以透過版本來做區分。
dotnet publish
的時候會發現我們若指定了版本,那麼編譯出來的 appsettings.json 的內容,就會是合併了版本、預設的 appsettings.json 的內容。
我們可以來測試一下,首先將專案設定擋像下面這樣設定
1 | // appsettings.json |
接著發布之後直接查看 appsettings.json 的內容,可以發現內容是合併了版本、預設的 appsettings.json 的內容。
1 | @rem 將檔案編譯輸出到 myoutput 資料夾 |
可以看到結果是 “my_version”: “debug”
那麼環境變數與版本的優先權是怎麼樣的呢?
實際上 publish 的版本已經被合併到 appsettings.json
了,此時,就只剩下了環境變數的設定
、以及合併完預設、版本的設定
。執行的時候會先去抓appsettings.json
的內容,然後也依據環境變數的設定,到對應的檔案中尋找是不是有對應的設定值,有的話就使用,沒有的話就是使用預設的設定值。
假設目前在伺服器上面的設定檔案如下
1 | // appsettings.json |
此時應用程式若要取得 my_version 的值,則會是 debug
;而若要取得 my_conn 的值,則會是 lab connection string
。
ReCap
- 環境變數設定檔案並不會以實體的方式合併,而是在執行時,會依照環境變數的設定,去讀取對應的設定檔案,並且載入到應用程序中。
- publish 的時候,會將版本合併到 appsettings.json 中。
- 環境變數的設定,會優先於 appsettings.json 的設定。
- dotnet publish -c <版本> -p:EnvironmentName=<環境變數> (此時指定環境變數是為了讓 IIS 使用)
補充
微軟官方提供的教學:ASP.NET Core 的設定,內容非常詳盡,有興趣的可以看看。