「Dockerコンテナの中だから、デバッグはログ出力で我慢する」なんて思っていませんか?
前回のDay 38では、.devcontainer/devcontainer.json を使って開発環境のすべてをコード化(IaC)し、Gitでチーム共有する手法を学びました。
しかし、現場のエンジニアから最もよく聞かれる不安がこれです。
「コンテナの中で動いているC#アプリって、本当にVisual Studioのようにブレークポイントで止めて、ステップ実行や変数の中身を見られるの?」
結論から申し上げます。ローカルPC直接実行と1ミリも変わらない快適さで、F5キーを押すだけで完全にデバッグできます!
ホストのVS Codeとコンテナ内のMicrosoft公式デバッガ(vsdbg)が阿吽の呼吸で連携するため、ブレークポイント設定、F10ステップオーバー、F11ステップイン、変数ウォッチ、さらには dotnet watch によるホットリロードまで自由自在です。本講義では、コンテナ内デバッグの裏側の仕組みから、launch.jsonの実践設定、バグ修正Git運用まで徹底解説します!
- 第1章:30年選手の苦笑い:「リモートデバッグの苦行」とポート開放のトラウマ
- 第2章:コンテナ内デバッグの裏側:VS Code Server と vsdbg の美しい連携アーキテクチャ
- 第3章:徹底対比:従来の遠隔デバッグ vs Dev Containers(完全比較表)
- 第4章:現場の2刀流:ホットリロード(dotnet watch)と F5 ステップ実行の使い分け戦略
- 第5章:launch.json と tasks.json の完全解説:自動ビルドからデバッガ起動まで
- 第6章:【実践ハンズオン】ASP.NET Core Web API をコンテナ内でF5デバッグ&変数ウォッチ
- 第7章:コンテナ内統合ターミナルでの dotnet CLI 活用とログ監視テクニック
- 第8章:Git連携:Git blame からバグ特定 ➔ コンテナ内即修正 ➔ テストコミットの黄金ループ
- 第9章:本日の理解度セルフチェック&次回予告
1 30年選手の苦笑い:「リモートデバッグの苦行」とポート開放のトラウマ
長年Windowsやオンプレミスサーバーでシステム開発に携わってきたベテランエンジニアほど、「別のマシンや仮想環境で動くプログラムのデバッグ」と聞いただけで身構えてしまうのではないでしょうか。
かつてのリモートデバッグといえば、以下のような苦難の連続でした:
- リモートサーバー側に「Visual Studio Remote Debugger(msvsmon.exe)」を手動で配置・起動しなければならない
- ファイアウォールで特定ポート(4020〜4026など)を開放する申請を出し、インフラ担当者と調整する
- ネットワーク認証やドメイン参加要件が厳しく、接続しようとしても「アクセスが拒否されました」で半日潰れる
- 対象プロセスのプロセスID(PID)をタスクマネージャーで探し出して手動アタッチした瞬間、サーバー全体が重くなる
- 手元のソースコードとサーバー上のDLLのビルドタイムスタンプが1秒でも異なると「シンボルが一致しません」と警告されてブレークポイントが白抜き無効化される
このようなトラウマから、「コンテナという隔離されたLinux環境の中で動いているC#アプリをデバッグするなんて、どうせ設定がややこしくて実用に耐えないはずだ。大人しく Console.WriteLine や ILogger でログを吐き出して目で追うしかない」と諦めてしまう現場が後を絶ちません。
しかし、その常識は Dev Containers の登場によって完全に過去のものとなりました!
2 コンテナ内デバッグの裏側:VS Code Server と vsdbg の美しい連携アーキテクチャ
なぜ Dev Containers では、手元のVS Codeからキーボードの「F5」を押すだけで、コンテナ内部のC#コードでブレークポイントがピタッと止まり、ステップ実行ができるのでしょうか?
その秘密は、「外からネットワーク越しにリモートデバッグしているのではなく、デバッガ自体がコンテナの中に常駐して同居している」という画期的なアーキテクチャにあります。
この連携は以下の3ステップで寸分の狂いもなく実行されます:
- ① ホスト側:VS Code UI
ホストPC上のVS Codeは、エディタの画面描画、キー入力、ブレークポイントの赤丸表示、変数監視ウィンドウの描画など「UIフロントエンド」のみを担当します。 - ② 境界通信:VS Code Server
コンテナ内部にはヘッドレスな「VS Code Server」が稼働しており、ホストのVS Codeと内部IPCパイプ(Docker exec / ソケット通信)で超高速に対話します。外部ポートを開放する必要は一切ありません。 - ③ コンテナ内:.NETデバッガ(vsdbg)
Microsoftが提供するLinux用.NETデバッガエンジン「vsdbg」がコンテナ内部で直接起動します。vsdbgは同じコンテナ内で稼働するASP.NET Coreのプロセスを直接制御し、スレッドの停止・再開、メモリ上の変数読み取りを超高速に行います。
つまり、ホストのVS Codeから見れば「あたかもローカルで動いているプロセス」であり、コンテナ内のデバッガから見れば「同じローカルLinux内で動くプロセス」なのです。ネットワークの遅延やファイアウォール設定の苦しみは、構造上100%存在しません。
3 徹底対比:従来の遠隔デバッグ vs Dev Containers(完全比較表)
旧来のVM・リモートデバッグ運用と、現代のDev Containersによるデバッグ体験の違いを一覧表で整理してみましょう。
4 現場の2刀流:ホットリロード(dotnet watch)と F5 ステップ実行の使い分け戦略
コンテナ内でC#開発を行う際、現場のハイパフォーマーが実践しているのが「ホットリロード」と「F5デバッグ」の賢い使い分け(2刀流)です。
常にF5デバッグで動かしていると、わずかなコード修正でもビルドとプロセスの再起動が走り、数秒〜数十秒の待ち時間が発生します。開発のフェーズに合わせて最適なモードを選択しましょう。
【利用シーン】
UIの見た目微調整、APIレスポンスの文言修正、バリデーションロジックの追加など、素早い試行錯誤を行いたい時。
【特徴】
コードを保存(Ctrl+S)した瞬間に、プロセスを再起動することなく実行中アセンブリに差分パッチが適用されます。ブラウザやSwaggerのリフレッシュだけで即座に結果を確認できます。
【利用シーン】
複雑な条件分岐の判定ミス、例外(Exception)の発生原因特定、データベースから取得した複雑なオブジェクト構造の精査など。
【特徴】
狙ったコード行で処理を確実に一時停止。ローカル変数、呼び出し履歴(コールスタック)、イミディエイトウィンドウによる式評価で、バグの根本原因をミリ単位で暴き出します。
5 launch.json と tasks.json の完全解説:自動ビルドからデバッガ起動まで
VS Codeで「F5」を押したときに、自動で最新コードを dotnet build し、生成されたDLLにデバッガをアタッチする設定は、.vscode/launch.json と .vscode/tasks.json のペアによって実現されます。
Dev Containers環境では、コンテナ内の絶対パス(例: /workspace/...)を意識する必要がありますが、${workspaceFolder} マクロを使えばOS差異を意識することなく完全ポータブルに定義できます。
① .vscode/tasks.json(事前ビルドタスクの定義)
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/MyWebApi.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
② .vscode/launch.json(F5起動・デバッガ連携の定義)
{
"version": "0.2.0",
"configurations": [
{
"name": "C#: Launch .NET Web API (Container)",
"type": "dotnet",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/bin/Debug/net8.0/MyWebApi.dll",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"serverReadyAction": {
"action": "openExternally",
"pattern": "\bNow listening on:\s+(https?://\S+)",
"uriFormat": "%s/swagger"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_URLS": "http://+:5000"
}
}
]
}
preLaunchTask: "build" を指定することで、F5キーを押した瞬間に tasks.json の build タスクが先行して走り、最新コードがコンパイルされます。コンパイルエラーがあればデバッグ起動が自動で中断されるため、「古いアセンブリのままデバッグして混乱する」事故を100%防止できます。
6 【実践ハンズオン】ASP.NET Core Web API をコンテナ内でF5デバッグ&変数ウォッチ
それでは、実際にコンテナ内でASP.NET Core Web APIを起動し、ブレークポイントで止めて変数を検査するハンズオンを実施してみましょう!
ステップ1:検証用Minimal APIコード(Program.cs)
計算処理とオブジェクト生成を含むシンプルなエンドポイントを用意します。
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/api/order/calculate", (int quantity, decimal unitPrice) =>
{
// ★ ここにブレークポイント(F9)を設定!
var subtotal = quantity * unitPrice;
var taxRate = 0.10m;
var taxAmount = Math.Round(subtotal * taxRate, 2);
var grandTotal = subtotal + taxAmount;
var response = new
{
Quantity = quantity,
UnitPrice = unitPrice,
Subtotal = subtotal,
TaxAmount = taxAmount,
GrandTotal = grandTotal,
ServerTime = DateTime.UtcNow
};
return Results.Ok(response);
});
app.Run();
ステップ2:ブレークポイント設定とF5実行
var subtotal = quantity * unitPrice;の行の左端(行番号の左隣)をクリックして赤丸を点灯させます(または該当行でF9キーを押下)。- キーボードの
F5を押下します。自動的にビルドが走り、コンテナ内でAPIが起動します。 - ホストPCのブラウザまたはターミナルから以下のURLをリクエストします:
curl "http://localhost:5000/api/order/calculate?quantity=5&unitPrice=1200" - リクエストを送った瞬間、VS Codeのエディタが黄色くハイライトされ、該当行で処理がピタッと一時停止します!
ステップ3:変数ウォッチとステップ実行の操作方法
| ショートカットキー | 機能名 | コンテナ内での動作 |
|---|---|---|
| F10 | ステップ オーバー | 関数を丸ごと実行し、次の行へ進む |
| F11 | ステップ イン | 呼び出しているメソッドの内部へ潜り込んでデバッグする |
| Shift + F11 | ステップ アウト | 現在のメソッドを脱出して呼び出し元に戻る |
| F5 | 続行(Continue) | 次のブレークポイントまで一気に処理を進める |
左サイドバーの「変数(Variables)」パネルには、コンテナ内で動くC#の quantity (5) や unitPrice (1200) の値がリアルタイム表示されます。さらに変数の上にマウスカーソルをホバーするだけで値がポップアップします!
7 コンテナ内統合ターミナルでの dotnet CLI 活用とログ監視テクニック
VS CodeでDev Containersを開いているとき、Ctrl + ` で開く「統合ターミナル」は、ホストのPowerShellではなく「コンテナ内部のLinux bash/sh」に直接接続されています。
そのため、ホストPCに.NET SDKが一切インストールされていなくても、コンテナ内ターミナルで以下の強力なコマンド群が何でも実行できます:
# 1. コンテナ内でホットリロード開発を開始
dotnet watch run --urls "http://+:5000"
# 2. 単体テストを実行して合否判定
dotnet test --logger "console;verbosity=detailed"
# 3. NuGetパッケージの追加(コンテナ内で解決)
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
# 4. EF Coreマイグレーションの実行
dotnet ef database update
8 Git連携:Git blame からバグ特定 ➔ コンテナ内即修正 ➔ テストコミットの黄金ループ
Dev Containersの真価は、Gitと完璧に連動したトラブルシューティング運用にあります。
本番やステージングで不具合が報告された際、チーム開発では以下の3ステップでバグを撲滅します:
- ① Git履歴・blameで変更履歴を特定
VS CodeのGitLensやgit blameを活用し、どのコミット・どのPRで入ったコードが怪しいかを特定。ブランチを切り替えて問題のコードをチェックアウトします。 - ② コンテナ内でF5検証・再現・即修正
環境の差異がゼロのコンテナ環境だからこそ、本番と同じ挙動がローカルで忠実に再現します。F5デバッグでブレークポイントを張り、変数の中身を確認しながらコードを安全に修正します。 - ③ コンテナ内で全テスト実行・即コミット&PR
コンテナ内ターミナルでdotnet testを流し、既存テストがすべてグリーン(合格)であることを検証。自信を持って修正コミットをプッシュし、Pull Requestを作成します。
🤖 AIエージェントへの指示プロンプト例(Antigravity / Claude Code / Copilot)
VS Codeの launch.json や tasks.json の記述に迷ったときは、AIエージェントに以下のように指示することで、最適な設定を即座に生成させることができます。
【指示プロンプト例】
VS CodeのDev Containers環境で稼働している.NET 8 Web APIプロジェクトに対して、
F5キーを押した際に自動ビルドを行い、コンテナ内のvsdbgでデバッグ起動するための
.vscode/launch.json と .vscode/tasks.json を生成してください。
ポートは5000番をリッスンし、Swagger UIへ自動連携する設定を含めてください。
9 本日の理解度セルフチェック&次回予告
🎯 本日の最重要セルフチェック
- コンテナ内デバッグにおいて、ホストVS Codeとデバッガ(vsdbg)はどのようなアーキテクチャで通信していますか?
(回答目安:コンテナ内に常駐するVS Code ServerとホストUIが内部パイプラインで連携し、デバッガvsdbg自体がコンテナ内部で直接プロセスを制御しているため、外部ポート開放不要で遅延なくローカル同等に動作する点) - 「dotnet watch」と「F5ブレークポイント実行」はどのように使い分けるのが最も効率的ですか?
(回答目安:画面確認や軽微なコード修正はホットリロードで即時反映させ、複雑なロジック不具合や例外解析の際はF5で1行ずつ停止・変数精査を行う点) - tasks.json の preLaunchTask を指定する最大のメリットは何ですか?
(回答目安:F5押下時に事前ビルドを強制実行し、コンパイルエラーを検知して古いアセンブリでの誤デバッグを未然に防止できる点)
Dev Containerの中で開発が快適にできるようになったら、次に直面するのが「コンテナの中からGitHubへの git push や git commit 署名をどう安全に行うか?」という認証の壁です。
コンテナの中にSSH秘密鍵を直接コピーするのは重大なセキュリティリスク!
次回は、ホストPCのSSH AgentやGit設定をセキュアにコンテナ内へ共有する「SSH Agent Forwarding & 署名フォワーディング術」を徹底解説します!お楽しみに!
コメント
コメントを投稿