mcpField
D
docker

docker

github.com/codewithmukeshクラウド・DevOps7913.0k 回インストール12 週間前に更新
リポジトリ

docker について

コンテナのビルド、実行環境、ヘルスモニタリングを扱う、.NET 開発者向けの Docker 実践ガイドです。マルチステージビルド、非 root 実行、オーケストレーター側のプローブを重視します。

主な機能

  1. 01マルチステージイメージビルド
  2. 02非 root 実行
  3. 03NuGet レイヤーキャッシュ
  4. 04オーケストレーターのヘルスプローブ
  5. 05Docker Compose によるローカル開発
  6. 06イメージとシークレットの扱い

活用シーン

  1. 01ASP.NET Web API コンテナの構築
  2. 02ローカルサービス依存関係の設定
  3. 03コンテナのヘルスモニタリング設定
  4. 04CI ビルドとイメージサイズの最適化

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/codewithmukesh/dotnet-claude-kit --skill docker

インストール後、Claude Code で/dockerを入力して読み込まれたか確認します。

詳細

Docker

基本原則

  1. 常にマルチステージビルドを使用する — ビルドステージとランタイムステージを分離します。SDK イメージでビルドし、ASP.NET ランタイムイメージで実行します。
  2. デフォルトで非 root ユーザーを使用する — .NET コンテナーイメージでは、.NET 8 以降、デフォルトで USER app がサポートされています。本番環境では root として実行しないでください。
  3. レイヤーキャッシュは重要です — ソースコードをコピーする前に .csproj ファイルをコピーして復元します。これにより、ビルド間で NuGet の依存関係がキャッシュされます。
  4. ヘルスプローブはオーケストレーター側で実行する — /health/live エンドポイントを公開し、Kubernetes/Compose からプローブします。Chiseled イメージとデフォルトの aspnet イメージにはシェルも curl もないため、イメージ内で実行する HEALTHCHECK コマンドには実行手段がありません。

パターン

Web API 用のマルチステージ Dockerfile
# Stage 1: Build
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src

# Copy project files and restore (cached layer)
COPY ["src/MyApp.Api/MyApp.Api.csproj", "src/MyApp.Api/"]
COPY ["src/MyApp.Domain/MyApp.Domain.csproj", "src/MyApp.Domain/"]
COPY ["Directory.Build.props", "."]
COPY ["Directory.Packages.props", "."]
RUN dotnet restore "src/MyApp.Api/MyApp.Api.csproj"

# Copy everything and build
COPY . .
RUN dotnet publish "src/MyApp.Api/MyApp.Api.csproj" \
    -c Release \
    -o /app/publish \
    --no-restore

# Stage 2: Runtime
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime
WORKDIR /app

# Non-root user (default in .NET 8+ images)
USER app

COPY --from=build /app/publish .

EXPOSE 8080

ENTRYPOINT ["dotnet", "MyApp.Api.dll"]
コンテナーのヘルスプローブ

Dockerfile の HEALTHCHECK よりも、オーケストレーター側のプローブ(Kubernetes の livenessProbe、Compose の healthcheck)を優先してください。標準の aspnet イメージと Chiseled イメージにはシェルも curl も wget も含まれていないため、コンテナー内でプローブを実行する手段がありません。オーケストレーターの接続先を /health/live に設定してください。

# docker-compose — probe from outside the app process
services:
  api:
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:8080/health/live || exit 1"]
      interval: 30s
      timeout: 3s
      retries: 3
# Note: CMD-SHELL requires a shell + wget in the image. Use a non-chiseled
# variant for this, or better: let Kubernetes httpGet probes do it —
# they run from the kubelet, needing nothing inside the image.

イメージ内で HEALTHCHECK を実行する必要がある場合は、wget を含む Chiseled ではないイメージをランタイムステージのベースにしてください。プローブコマンドでアプリのバイナリを再実行してはいけません。最初のインスタンスを確認する代わりに、2 つ目のインスタンスを起動してしまいます。

.dockerignore
**/.git
**/.vs
**/bin
**/obj
**/node_modules
**/Dockerfile*
**/docker-compose*
**/tests
ローカル開発用の Docker Compose

.NET 固有の重要な注意点として、接続文字列は環境変数で渡し、ヘルスチェック付きの depends_on を使用します。

services:
  api:
    build:
      context: .
      dockerfile: src/MyApp.Api/Dockerfile
    ports:
      - "5000:8080"
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ConnectionStrings__Default=Host=postgres;Database=myapp;Username=postgres;Password=postgres
      - ConnectionStrings__Redis=redis:6379
    depends_on:
      postgres:
        condition: service_healthy
  # Add postgres/redis services with healthcheck — standard boilerplate
.slnx を使用した最適化ビルド

複数のプロジェクトがあるソリューションでは、必要なプロジェクトのみを復元します。

FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src

# Copy solution and all project files
COPY *.slnx .
COPY Directory.Build.props .
COPY Directory.Packages.props .
COPY src/**/*.csproj ./src/

# Restore project structure
RUN for file in src/**/*.csproj; do \
    mkdir -p $(dirname $file) && mv $file $(dirname $file)/; \
    done
RUN dotnet restore

COPY . .
RUN dotnet publish src/MyApp.Api -c Release -o /app/publish --no-restore
ヘルスチェックエンドポイント
// In Program.cs — lightweight health endpoint for Docker
app.MapGet("/health/live", () => Results.Ok("healthy"))
    .ExcludeFromDescription();

アンチパターン

ランタイムに SDK イメージを使用しない
# BAD — SDK image is 900MB+, includes compilers
FROM mcr.microsoft.com/dotnet/sdk:10.0
COPY . .
RUN dotnet run

# GOOD — separate build and runtime, runtime image is ~200MB
FROM mcr.microsoft.com/dotnet/aspnet:10.0
復元前にすべてをコピーしない
# BAD — any source change invalidates the NuGet cache
COPY . .
RUN dotnet restore

# GOOD — copy only project files first, then restore
COPY ["src/MyApp.Api/MyApp.Api.csproj", "src/MyApp.Api/"]
RUN dotnet restore "src/MyApp.Api/MyApp.Api.csproj"
COPY . .
root として実行しない
# BAD — running as root (security risk)
FROM mcr.microsoft.com/dotnet/aspnet:10.0
COPY --from=build /app .
ENTRYPOINT ["dotnet", "MyApp.Api.dll"]

# GOOD — use the built-in non-root user
FROM mcr.microsoft.com/dotnet/aspnet:10.0
USER app
COPY --from=build /app .
ENTRYPOINT ["dotnet", "MyApp.Api.dll"]

選択ガイド

シナリオ推奨事項
Web API コンテナーaspnet ランタイムイメージを使用したマルチステージビルド
Worker サービスdotnet/runtime イメージを使用したマルチステージビルド
ローカル開発サービスの依存関係を設定した Docker Compose
CI ビルドマルチステージビルド(自己完結型)
イメージサイズの最適化小さいイメージには Alpine バリアントとトリミングを使用
ヘルスモニタリング/health エンドポイントとオーケストレータープローブ(K8s httpGet/Compose healthcheck)
シークレット環境変数またはマウントされたシークレットを使用し、イメージには含めない

コメント