點選上方藍字關註“汪宇傑部落格”
最近我遭遇了一個奇怪的問題。使用Azure DevOps配置CI/CD管線,自動部署到Azure App Service以後,.NET Core的網站竟然會啟動失敗。我們來看看如何解決這個問題。
查詢問題
首先,幸好,這是個staging環境。爆了以後,我發現網站竟然沒有log,連log的目錄都找不到,這非常奇怪。於是我決定在Azure啟用開發樣式,讓網站輸出詳細錯誤資訊。熟悉經典ASP.NET的同學可能知道,只要在web.config裡設定個customError就行了。但是.NET Core沒有這個東西,怎麼辦呢?我教大家一個猥瑣小技巧:
.NET Core的設定,是優先用環境變數改寫的。所以我們可以利用這點,在Azure App Service的設定裡加這麼一個環境變數:
ASPNETCORE_ENVIRONMENT:Development
更改設定的地方在Application settings頁面
朋友們可能會問:我怎麼知道這個值的?其實這個設定來源於Visual Studio
開啟開發樣式以後,輸出了宇宙大爆炸的詳細資訊:
發現執行的程式碼路徑竟然不是在App Service應有的網站根目錄!於是我的程式碼找不到依賴項,就爆了。
怎麼回事
我嘗試了手動從VS部署,也是爆的。在Azure DevOps重新部署,也是爆的。甚至停用CD管線,用kudu直接build git的程式碼,也是爆的!我陷入了迴圈懵逼:
最終我刪除並重建了一個新的App Service實體,用VS釋出,居然就好了。但是我再次用CI/CD管線部署以後,又產生了大爆炸。細心的我,保留了網站執行正常時候的配置資訊,與爆炸以後的配置對比發現,是多了這麼一個設定:
這是個啥玩意兒
我追溯到一個微軟Azure的announcement:https://github.com/Azure/app-service-announcements/issues/84
發現它是針對Azure Function設計的,這是App Service進一步包裝以後的服務。與傳統部署的差別就是,傳統部署會把新檔案改寫到wwwroot目錄,也就是我們的網站根目錄,而用了RUN_FROM_PACKAGE的話,網站執行的時候會指向一個zip檔案,壓縮包的內容會對映到wwwroot目錄,但會變成只讀。
使用這個功能有一些好處,比如可預測、更快速的部署、更快速的啟動性等等,具體大家可以去看微軟公告的介紹。
恢復網站執行
想要臨時恢復網站執行,非常簡單,只要將WEBSITE_RUN_FROM_PACKAGE這個設定整個刪除,重啟網站,就可以恢復到部署前的良好版本。但是Azure DevOps將來的部署,將不會起作用。因為真實的wwwroot目錄不會被更新了。
恢復至CD部署前版本:6980
那如何自動部署呢
我們需要修改Azure DevOps部署任務的預設值
編輯你的Release定義,在Tasks下找到Deploy Azure App Service子任務。
展開Additional Deployment Options,勾選 Select deployment method,然後手工選擇為 Web Deploy,儲存設定。
然後重新提交一個Release,等待成功部署。完成之後就可以看到正確的新版本被部署在wwwroot物理路徑下了,網站也能正常啟動: