前言
.net core的誕生就是為了解決跨平台的事情的,所以.net core app運行在linux、macOS、docker上也不是什么新鮮事了。
相信已經有不少.net core的項目已經部署在docker或者linux的環境下。但是一般的開發人員的開發環境不會是Ubuntu、redhat什么的,既然開發環境和部署環境的區別比較大,我們總希望在開發調試的時候,能更加貼近實際的部署環境。所以今天這篇文章說一下如何調試部署在docker的asp.net core app。
如果大家有安裝VS2017,這個其實是最好的,調試和部署都是點選幾個按鈕,然后就可以愉快地調試了。
但總有一些情況下無法安裝VS2017的,所以下文講的是利用VS code調試。
開發機器必要的環境:
1. .net core 1.1
2. vs code (盡量最新版)
3. docker 17.06.0'
項目結構
我們使用dotnet cli先把項目建起來,進入到要用的目錄,跑下面幾個命令,
dotnet new mvc -n web
dotnet new sln mytest
dotnet sln mytest.sln add web/web.csproj
好了,項目建好之后,我們用vs打開,等待一下,vscode就會自動幫我們建立一個.vscode的文件夾,里面會有一些調試配置文件,如下圖:
打開program.cs文件,修改一下Main方法的代碼,主要是要修改的是端口,為了避免跟別的端口沖突
public static void Main(string[] args) { var host = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseUrls("http://*:6106") .UseIISIntegration() .UseStartup<Startup>() .Build(); host.Run(); }
項目基本是完整的,但是還要配Dockerfile,主要是推到docker的配置文件
我們在web目錄下新建一個Dockerfile,內容如下: (注意:這個文件是沒有后綴的)
1 FROM microsoft/dotnet:latest 2 3 RUN apt-get update 4 5 RUN apt-get install curl unzip -y 6 7 RUN curl -sSL https://aka.ms/getvsdbgsh | bash /dev/stdin -v latest -l ~/vsdbg 8 9 RUN chmod 777 /root/vsdbg 10 11 COPY ./publish /app 12 13 WORKDIR /app 14 15 ENTRYPOINT ["dotnet", "web.dll"]
簡單解釋一下上面的配置,
第1行的意思是基於microsoft/dotnet的最新版本鏡像。
第3、5行是更新apt-get和安裝curl,unzip這2個工具(其中最后一個 -y 是必須的,否則docker會在那里等待命令輸入,最終會導致調試失敗)
第7、9行就是curl安裝 vsdebuger了,並且把這個安裝目錄調了權限
11行是把開發環境下的publish目錄下的內容復制到docker鏡像中的/app目錄下
13行是指定docker工作目錄是/app
15行是運行的入口,翻譯過來的就是 dotnet web.dll (有點像本地部署后的運行)
部署到docker
我們首先要把.net core app發布一下,注意一定要選定Debug模式,后面指定的發布路徑也要指定,否則dockerfile的第11行就要修改了
dotnet publish -c Debug -o ./publish
跑完之后web目錄下就會多了publish目錄,下面有很多dotnet的發布文件(今天先不講最小量發布,東西多了點也沒有關系)
從docker下載鏡像microsoft/dotnet:lastest , 並且制作自己的鏡像myimage1
docker pull microsoft/dotnet
docker image tag microsoft/dotnet:latest myimage1:latest
之后我們就要把.net core 的東西發布到docker了 。 最后的一個點"."是必須的!!!
docker build -t myimage1 --rm .
部署的過程取決於你的網絡,因為要裝好幾個東西,其中vsdebuger是相當慢的,不過也是可以解決的,我們在文章結束后再討論解決辦法
當docker build完成之后,我們就讓app在容器中跑起來
docker run -t -p 6106:6106 --name mytestcontainer myimage1
其中-p 6106:6106指的是把本機的6106端口指向容器中6106端口,其實這里是可以不一一對應的。
--name mytestcontainer 是指把這個myimage1鏡像,用mytestcontainer這個名稱來運行容器。好處是之后我們隊容器的操作只要記住這個名稱就可以了,不用記着docker自動給我們生成的id。
好這樣.net core app就在容器中跑起來了,我們打開localhost:6106,其實就能看到效果啦
vs code 調試配置
打開.vscode/launch.json文件。點擊右下角的Add configuration我們去添加一個調試配置。
之后vscode會自動提示要選哪一些調試配置,我們直接選 .Net: Attach to remote .NET Core Console App(也就是第二個。。。),如圖
點擊之后,就會生成下面的配置,里面有很多東西都要改的。里面也有一些提示,比如debuggerPath就是輸入debugger在目標電腦的位置這些
最終我們要把configuration節點下的內容改成下面這樣
1 { 2 "name": ".NET Core Attach", 3 "type": "coreclr", 4 "request": "attach", 5 "processId": "${command:pickRemoteProcess}", 6 "pipeTransport": { 7 "pipeCwd": "${workspaceRoot}", 8 "pipeProgram": "bash", 9 "pipeArgs": [ 10 "-c", 11 "docker exec -i mytestcontainer ${debuggerCommand}" 12 ], 13 "debuggerPath": "/root/vsdbg/vsdbg" 14 }, 15 "sourceFileMap": { 16 "/Users/admin/my/github/test_debug_docker": "${workspaceRoot}" 17 } 18 }
其中第11行中的 -i mytestcontainer是我們前面指定的容器的名稱,這里也可以用id代替
13行中的debuggerPath就是剛才curl下載安裝的vsdbg,這里要留意docker build的時候vsdbg安裝的目錄在哪里
16行的sourceFileMap是指這整個項目在你開發環境的位置,簡單點來說就是vscode你打開的是那個目錄(這個其實意義比較深,這里不展開討論)
好,一切准備就緒了,調試起來吧!!
調試效果
按F5,然后會讓你選擇哪一個進程進行調試,當然選擇dotnet web.dll這個
等一些時間,然后就可以了,然后我們在homecontroller.cs這個文件的About方法設一個斷點
然后打開這個鏈接:http://localhost:6106/Home/About,就可以看到下圖的端點已經進去了。
然后在左邊的變量中就能看到他的值了,跟左邊跑的是一樣的
我們也可以在debug console中修改他的值,比如輸入成ViewData["Message"] = "test test";可以看到左邊的變量已經變了
頁面的內容也變成test test了
總結
以往我們在vs中調試mvc頁面,我們改了cshtml的內容,保存后刷新頁面,就能夠立即看到變化效果,但是在vs code卻不能。估計是因為docker的原因,之后應該是可以解決的。
另外的一個缺點是,附加到進程始終是有缺點的,他無法同時附加多個進程,如果要多個系統間調試,只能同時啟動多個vs code,這個對比vs的調試來說差別太大了。因為系統既然想部署在docker,估計都是模塊化甚至是微服務單元,這樣一個比較完整的系統,肯定設計多個子模塊間的調試。雖然每個模塊可能不是同一個人做,開發環境下能連着調試不是更加好嗎。
解決vsdebugger下載超級慢的辦法
其實vsdebugger的安裝,只是把文件下載下來,然后放在指定的目錄。
所以解決辦法就是把這個vsdebugger下載下來,然后解壓,放到開發環境下的web目錄下,最后用Dockerfile配置,把vsdbg拷貝過去容器,下面是修改后的Dockerfile
FROM microsoft/dotnet:latest RUN apt-get update RUN apt-get install curl unzip -y # RUN curl -sSL https://aka.ms/getvsdbgsh | bash /dev/stdin -v latest -l ~/vsdbg COPY ./vsdbg /root/vsdbg RUN chmod 777 /root/vsdbg COPY ./publish /app WORKDIR /app ENTRYPOINT ["dotnet", "web.dll"]
這樣就不用等待curl安裝vsdebugger了。
vsdebugger 的下載鏈接:
https://vsdebugger.azureedge.net/vsdbg-15-1-10630-1/vsdbg-linux-x64.zip