隨著 Windows 10 與 Windows Server 2016 推出的 IIS 10.0 最新版本,僅帶來一些功能改進,大部分功能都相容於 IIS 7 與 IIS 8 ,但有個鮮為人知的自訂環境變數功能,我覺得值得寫篇文章分享給大家知道。
有時候我們需要對網站進行「多環境部署」,像是將網站部署到測試環境與正式環境就有很多參數要調整,例如資料庫連接字串、寫入 Log 的路徑、發信主機 IP 地址、安全性設定、…可能都不一樣,這些依據環境而不同的參數設定如果掌握在「開發人員」身上,或是將這些設定都放入「版本控制系統」中,都不是很好的解法,畢竟這些資訊屬於 維運端 (Operators) 的重要資訊,理應跟 開發端 (Developers) 切割乾淨,這樣才能在 DevOps 協作的過程中釐清責任、彼此分工。
像我們就經常將網站部署到 Azure Web App 雲端平台,由於這是個 PaaS (Platform-as-a-Service) 平台,因此內建了許多優異的設定功能,讓我們很容易就可以做到多環境部署,如下圖示:
不過如果你要將網站部署到 地端 (on-premises) 的話,使用 Windows Server 2016 的 IIS 10.0 或許是個不錯的選擇。
由於 IIS 的「網站」( Sites ) 都必須執行在特定一個「應用程式集區」( Application Pool ),而每個應用程式集區就會啟動一個以上的「工作者處理序」( Worker Process ),啟用工作者處理序則是 W3SVC 服務在做的事。
只要設定應用程式集區可以執行兩個以上的工作者處理序就稱為 Web Garden 架構。
從 IIS 10.0 開始,可以讓你設定「應用程式集區」,讓 W3SVC 服務在準備啟動「工作者處理序」( Worker Process ) 時,自動賦予額外的「環境變數」。如此一來,你就可以修改你的網站應用程式,將「環境」相關的變數從 Web.config 全部改從 環境變數 取得資訊,日後在部署網站時,就不用特別針對環境修改程式或設定,你可以將同一份原始碼編譯後自動部署到不同環境下執行,我們在實作 CI (持續整合) / CD (持續部署) 也會更加容易。
目前自訂應用程式集區的環境變數並沒有任何 GUI 介面可以操作,因此你必須手動調整 applicationHost.config 設定檔才能完成設定,常見的路徑如下:
- C:\Windows\System32\inetsrv\config\applicationHost.config
請注意:此檔案位於系統資料夾下,必須以系統管理員身分開啟文字編輯器才能修改此檔案。
如果開啟此檔案,你可以直接跳轉到大約 145 行左右,在 <system.applicationHost> 區段下有個 <applicationPools> 區段,這裡定義著本機 IIS 所有的應用程式集區設定,如下圖示:
設定完成後如下示意圖:
在存檔之後,你 ASP.NET 應用程式就可以透過類似 Environment.GetEnvironmentVariable("foo") 這樣的程式碼取得環境變數!
關於 IIS Express 10.0 的注意事項
你如果透過 Visual Studio 2015/2017 啟動內建的 IIS Express 10.0 會發現它並不支援這個設定,那是因為 IIS Express 不像 IIS 有工作者處理序的程序管理員,IIS Express 其實是由 Visual Studio 啟動的,而 Visual Studio 又是由「你」所啟動的。所以基本上 IIS Express 在執行時會用到與 Visual Studio 完全相同的環境變數,而 Visual Studio 的環境變數預設都會從「使用者環境變數」複製過來。由此可知,環境變數是會繼承的,最上層是系統環境變數,然後是使用者環境變數,然後個應用程序如果啟動一個子程序時,也可以賦予額外的環境變數。
所以,如果你希望 IIS Express 被 Visual Studio 啟動時也要包含某些自訂的環境變數,也可以參考以下設定技巧:
- 修改 Visual Studio 啟動捷徑
- 修改捷徑的目標,改透過 cmd.exe 來啟動 devenv.exe 開發工具,並在前面加上 set foo=bar 自訂環境變數設定,兩個指令之間可以透過 && 合併再一起即可,你當然也可以設定多組環境變數參數。如果有很多環境變數要設定,建議可以自行撰寫一個批次檔 ( *.bat ) 會比較好維護設定。
相關連結
- The Official Microsoft IIS Site
- 取得目前運行的 IIS 版本可以執行以下程式碼
- Request.ServerVariables["SERVER_SOFTWARE"]