ASP.NET Core Blazor + Docker環境をVSCodeでデバッグする方法

Dockerを利用したASP.NET Core BlazorアプリケーションをVisual Studio Code（以下「VSCode」と表記）でデバッグを行う際に設定した内容をまとめます．

尚，Visual Studio 2022でデバッグを行う方法については，以下のMicrosoftのドキュメントに記載があります．

https://learn.microsoft.com/ja-jp/visualstudio/debugger/attach-to-process-running-in-docker-container?view=vs-2022

## 1. 環境
- MacBook Air M2 (macOS Sequoia)
- .NET 8
- ASP.NET Core Blazor

## 2. ディレクトリ構成(デバッグ設定前)
当記事では以下の構成に基づく設定手順をご紹介します．
```
Dockerfile
docker-compose.yml
BlazorProject
├ nginx
| └ default.conf
├ ...
├ appsettings.json
└ BlazorProject.csproj
BlazorProject.sln
```
- `BlazorProject`はASP.NET Core Blazorで利用するファイルを格納するディレクトリです．
- `nginx/default.conf`はASP.NET CoreのリバースプロキシをNginxで構成するためのファイルです．
`docker-compose.yml`にて`/etc/nginx/conf.d/default.conf`として配置することで機能させます．

### 2.1. 各ファイルの内容
```Dockerfile:Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS base

WORKDIR /app/src
COPY ./BlazorProject ./

RUN dotnet restore

ENTRYPOINT [ "dotnet", "watch", "run", "--no-restore" ]
```

```docker-compose.yml
services:
    # ASP.NET Coreが動作するコンテナ
    app:
        build:
            context: .
            dockerfile: Dockerfile
        expose:
            - 5000:5000
        networks:
            - project-network
        volumes:
            - ./BlazorProject:/app/src

    # appコンテナのリバースプロキシ
    web:
        image: nginx:alpine
        ports:
            - 8080:80
        networks:
            - project-network
        volumes:
            - ./BlazorProject/nginx/default.conf:/etc/nginx/conf.d/default.conf

networks:
    project-network:
        driver: bridge
```

```conf:BlazorProject/nginx/default.conf
map $http_connection $connection_upgrade {
    "~*Upgrade" $http_connection;
    default keep-alive;
}

server {
    listen      80;
    server_name blazor-project.dev;
    location / {
        proxy_pass         http://app:5000/;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection $connection_upgrade;
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_redirect     off;
    }
}
```

```json:BlazorProject/appsettings.json
{
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft.AspNetCore": "Warning"
        }
    },
    "Kestrel": {
        "Endpoints": {
            "Http": {
                "Url": "http://*:5000" // リバースプロキシに5000番ポートを公開するための設定
            }
        }
    },
    "AllowedHosts": "*"
}
```

## 3. デバッグ設定手順
1. 拡張機能「Docker」がインストールされていない場合はインストールします．
    ![Screenshot 2025-02-01 at 21.55.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483756/44a7888e-adf1-a44f-91ea-3b38d47b12aa.png)

2. Workspaceの一番上のディレクトリに`.vscode`ディレクトリを追加します．さらにその中に`launch.json`ファイルを追加します．
追加後のディレクトリ構成は以下の通りです．
    ```
    .vscode
    └ launch.json　# 追加
    Dockerfile
    docker-compose.yml
    BlazorProject
    ├ nginx
    | └ default.conf
    ├ ...
    ├ appsettings.json
    └ BlazorProject.csproj
    BlazorProject.sln
    ```

3. `launch.json`に以下を記載します．
    ```launch.json
    {
        "version": "0.2.0",
        "configurations": [
            {
                "name": "Attach Blazor Project", // 任意の名前を指定可能
                "type": "docker",
                "request": "attach",
                "platform": "netCore",
                "processId": "${command:pickRemoteProcess}",
                "sourceFileMap": {
                    "/app/src": "${workspaceFolder}/BlazorProject" // "<コンテナ側のパス>": "<ホスト側のパス>"
                }
            }
        ]
    }
    ```
    このうち`sourceFileMap`にはホスト側とコンテナ側のASP.NET Coreのファイルを格納するパスを記載します．
    ここでは`docker-compose.yml`に以下の記載をしていますので，
    ```docker-compose.yml
    app:
        volumes:
            - ./BlazorProject:/app/src
    ```
    `sourceFileMap`は以下の記載となります．
    ```launch.json
    "sourceFileMap": {
        "/app/src": "${workspaceFolder}/BlazorProject"
    }
    ```

4. `docker compose up -d`等でコンテナを起動します．

5. メニューバーのView -> Runから「Run and Debug」コンソールを開きます．
そして`launch.json`の`name`に記載の名称が選択された状態で，`Start Debugging`ボタンをクリックします．
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483756/347468fc-4c04-e136-bccd-64cb68ee5488.png" width="60% />

6. コンテナグループを選択します．
    ![Screenshot 2025-02-02 at 1.30.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483756/00f00754-99cb-a297-a679-10faf8317f78.png)

7. ASP.NET Coreのプロジェクトが動いているコンテナ（ここでは`blazorproject-app`）を選択します．
    ![Screenshot 2025-02-02 at 1.31.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483756/c711c5db-8c8b-e4e9-68d3-dbe45f4146c1.png)

8. `.NET Debugger`をコンテナ内にコピーするかどうかを尋ねられます．ここで`No`を選択するとデバッグできないので`Yes`を選択します．
    ![Screenshot 2025-02-02 at 1.34.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483756/cabf5870-cdf8-e4f9-5058-00a6c168d101.png)

9. アタッチするプロセスとして，`.csproj`ファイルと同名のプロセス（ここでは`BlazorProject`）を選択します．
    ![Screenshot 2025-02-02 at 1.35.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483756/3cf43b8e-3718-babd-d67f-542dcc4a99d1.png)

10. 以上で設定完了です！問題なく動作していればブレークポイントを置いたり変数のウォッチが可能です．