利用VS code 遠程調試 docker 中的 dotnet 應用


 

 

 

前言

最近.Net 5 正式版發布,我也來蹭一點熱度。

如題所示,我這次要講的是debug docker中的dotnet應用。其實之前我已經寫過類似主題的隨筆,有興趣回顧的朋友可以看看: VS code docker 調試 asp.net core

首先之前的隨筆說得比較片面,由於當時也是剛剛接觸docker和利用vscode寫代碼,並且當時遺留下來的幾個問題也在本文中有了解決辦法。

其次是隨着docker的普及,vscode 原生支持遠程調試。這些特點都降低調試docker中的應用的難度,而且這種技術,不僅僅限於dotnet,是可以覆蓋到nodejs,python等等別的技術棧的。

在這篇隨筆中就不在陳述為什么我們需要調試docker中的應用了,簡單來說,是有這個需要。

 

是怎么實現的

這里貼一張vs code實現遠程調試的原理圖。

可以看出來,完整的代碼,workspace 擴展組件,sdk,都是在遠程的OS的,在我們的場景下,就是docker的容器下。

而我們本地的操作系統下,僅僅需要一些vs code和簡單的組件。

 

 

本地操作系統必要應用/工具

1. VS code, 版本盡量新,我用的是1.51.0版本,vs code從什么版本開始支持remote server確實不知道了。

2. VS code extension :Remote Development. 他是一個pack,會同時安裝上container, WSL, SSH的遠程調試擴展。 是下圖這個樣子的

 

3. Docker for Desktop. 由於下文中會用到本地代碼映射到container,所以需要用到完整的docker,而不僅僅是一個CLI。

4. hmm....應該就這些了,本機甚至不需要安裝dotnet sdk和vscode 的c# 擴展。

5. 由於本地沒有了sdk,我們還需要一份已經創建好的代碼,由於時間的關系,我已經准備好了:

 https://github.com/woailibain/remote-debug-sample

 

Getting Start

構建docker image

1. 到鏈接上checkout代碼,打開vs code,然后打開git目錄下的src。

在vs code上看到的是這個樣子的,里面有一個sln文件,一個csproj。

2. 打開vs code下面的terminal窗口,或者可以打開系統下的CMD/terminal,然后cd到src目錄下。

執行下面的命令

docker-compose build

如果第一次操作這里會需要挺長的時間,是因為要到docker hub上pull sdk image。

等構建成功之后,會出現這種下圖的這種提示

3. 我們使用docker命令再次校驗是否已經生成了我們想要的image

docker images | grep remote-debug-sample

 

 

 

Container 跑起來

1. 使用下面的命令,讓container跑起來。我們可以在terminal/CMD上看到如下圖類似的輸出

docker-compose up

 

 

 

2. 通過瀏覽器打開地址(http://localhost:5155/),就可以看到有一些內容了

 

 

調試

Attach to Container

1. 從vscode的側邊欄點開Remote Explorer

然后這里能看到你的docker中有什么Container。 如果是第一次使用,在Other Containers下,如果已經曾經使用了,就會在Container下

2. 右鍵需要用到的Container,然后點擊attach to container

 

3. 稍等幾秒,就會自動打開一個新的vscode窗口。 (如果你在開始之前並沒有安裝前面提到的Remote Development 擴展組件,則這里需要等待幾分鍾去完成安裝,然后才會打開新的vscode窗口)

等vs code窗口打開后,窗口的右下角會出現Starting Dev Container的提示,我們點擊它,就會出現TermIcal的窗口

 

 

點擊上圖的右下角的提示,就會出現Terminal 窗口,並且在左下角顯示已經鏈接到kiwiho/remote-debug-sample這個container了

 

 

4.點擊vs code旁邊的Explorer,我們就能看到container上的代碼已經能打開了,這里也特殊表明了這個是Container中的文件

 

 

 

 

5. 我們再隨便打開其中一個C# 文件,就會自動安裝C# 調試不要的必要擴展了。其實這里可以通過自定義文件完成擴展的自動安裝,不過這里不展開說.

如果沒有自動安裝,請自行安裝

 

6. 等C#擴展安裝好之后,在debug 的地方,按照平常本地使用vs code的方式,創建一個調試配置文件。

在調試窗內點擊create a launch.json file.

 然后會有彈窗,我們選擇dotnet Core

 

 

 

然后配置文件就生成了,我們主要用里面的.NET Core Attach。 其余不需要的可以自行刪除

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": ".NET Core Launch (web)",
            "type": "coreclr",
            "request": "launch",
            "preLaunchTask": "build",
            "program": "${workspaceFolder}/bin/Debug/net5.0/remote-debug-sample.dll",
            "args": [],
            "cwd": "${workspaceFolder}",
            "stopAtEntry": false,
            "serverReadyAction": {
                "action": "openExternally",
                "pattern": "\\bNow listening on:\\s+(https?://\\S+)"
            },
            "env": {
                "ASPNETCORE_ENVIRONMENT": "Development"
            },
            "sourceFileMap": {
                "/Views": "${workspaceFolder}/Views"
            }
        },
        {
            "name": ".NET Core Attach",
            "type": "coreclr",
            "request": "attach",
            "processId": "${command:pickProcess}"
        }
    ]
}

 

 

 

 

 

 

開始調試

1. 啟動 .NET Core Attach 調試配置。 我們在彈窗下選第一個,這里需要注意,我們要選自己運行的process。如果你用的是dotnet run,那就需要選擇對應的process

 

 

在HomeController的Index方法最后一行打上斷點,打開http://localhost:5155/Home

稍等一會兒,就能看到已經進去斷點了。

我們需要的遠程調試已經實現了

 

熱部署和調試

其實在開發過程中,我們需要的很可能並不僅僅是調試,可能還需要修改代碼。

那如果沒改一次代碼,都必須走完上面的全部步驟,那不是很坑嗎。

所以我們需要引入dotnet watch 命令。

 

重點:但是要使用這種功能,container和代碼必須要同一個台機!  前面的步驟都是能真正的遠程調試,container可以運行在別的機器上。以下步驟必須在同一台機!!!

 

修改docker-compose配置和dockerfile

1. docker-compose.override.yml , 將volumes的代碼注釋去掉。改成下面這樣的

version: '3.4'

services:
  remote-debug-sample:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://0.0.0.0:80\
    ports:
      - "5155:80"
    # enable local OS code watching and hot deployment 
    volumes:
      - ./remote-debug-sample:/src/remote-debug-sample

 

2. 修改Dockerfile.Develop,講最后面的2段代碼注釋和去掉注釋。修改后是這樣的.

在這里需要特別注意2點:

   目前的dotnet sdk image,不能用Debian的,我這里就改成5.0-focal,是使用Ubuntu的

   最后的Entrypoint,必須要加上--no-launch-profile,否則,就會使用代碼中的launchsetting,會導致asp.net不使用80端口

FROM mcr.microsoft.com/dotnet/sdk:5.0-focal
ARG BUILD_CONFIGURATION=Debug
ENV ASPNETCORE_ENVIRONMENT=Development
ENV DOTNET_USE_POLLING_FILE_WATCHER=true
EXPOSE 80

WORKDIR /src
COPY ["remote-debug-sample/remote-debug-sample.csproj", "remote-debug-sample/remote-debug-sample.csproj"]

RUN dotnet restore remote-debug-sample/remote-debug-sample.csproj

# comment below lines to enable the coding watching
# COPY . .
# WORKDIR /src/remote-debug-sample
# RUN dotnet publish --no-restore -c Debug -o /app
# WORKDIR /app
# ENTRYPOINT ["dotnet", "remote-debug-sample.dll"]

# uncomment below lines to enable the coding watching
WORKDIR /src/remote-debug-sample
ENTRYPOINT ["dotnet","watch", "run","--no-launch-profile"]

  

重新構建Image和部署Container

1. 構建Image

docker-compose build

2. 部署Container

docker-compose up

 

配置遠程VS code

1. 仿照上面的步驟,attach to containr, 安裝VS code擴展,配置.net core attach調試文件

2. 啟動調試,打斷點。 這里我們需要選dotnet watch run的那一個

 

 

首先我們進入相同的地址(),可以看到json返回出來的還是hello,world!的字眼。

 

 然后我們在本地代碼修改,加入第11行的代碼。需要注意的是,我們改的是本地文件!! 

 

 

保存文件的改動!然后可以在Terminal下看到Application is shutting down...  File changed, Started等提示,證明代碼已經熱部署了

 

我們再去瀏覽器看看結果,事實證明。 代碼確實成功修改並且熱部署了

 

 停用調試和attach to container

其實有很多情況,我們是不需要調試的,只需要改代碼做驗證,那么就不需要attach to container和調試了。

只需要啟動container,然后在本地修改你想改的代碼,保存就能看到結果了。

 

 

結語

發現這篇文章寫得非常的冗長,當作是新手指南吧。 

因為當初我確實在這方面遇到了一點困難,所以覺得有必要詳細分享。

不像網絡上的都是幾句話,附加到container,然后就調試。

 

還有什么坑我隱藏沒有告訴你

首先我們要知道,調試的必要條件

1. 代碼是用Debug發布的,或者Release發布后,必須包含*.pdb文件

2. 調試,我們需要的是sdk,而不是runtime

鏡像的坑

1. 這次我也是首次調試.net5的代碼,發現sdk:5.0的Image是有問題的,無法正常使用dotnet watch。后來我選擇了用sdk:5.0-focal,就沒問題了

2. 肯定有人好奇我一個這么簡單的項目,為什么要用docker-compose。 其實原因是docker build要使用緩存會相對麻煩。所以我使用docker-compose,加快了每次生成Image的速度

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM