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. 01构建 ASP.NET Web API 容器
  2. 02配置本地服务依赖
  3. 03设置容器健康监测
  4. 04优化 CI 构建和镜像体积

安装

复制下面的命令,在终端中运行。

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

安装后在 Claude Code 中输入/docker确认已加载。

详细介绍

Docker

核心原则

  1. 始终使用多阶段构建 — 分离构建阶段和运行时阶段。在 SDK 镜像中构建,在 ASP.NET 运行时镜像中运行。
  2. 默认以非 root 用户运行 — 自 .NET 8 起,.NET 容器镜像默认支持 USER app。生产环境中绝不要以 root 用户运行。
  3. 分层缓存很重要 — 先复制 .csproj 文件并还原依赖项,再复制源代码。这样可以在不同构建之间缓存 NuGet 依赖项。
  4. 在编排器层级配置健康探测 — 暴露 /health/live 端点,并让 Kubernetes/Compose 对其进行探测。Chiseled 镜像和默认的 aspnet 镜像没有 shell 或 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"]
容器健康探测

优先使用编排器层级的探测(Kubernetes 的 livenessProbe、Compose 的 healthcheck),而不是 Dockerfile HEALTHCHECK — 标准的 aspnet 和 Chiseled 镜像不包含 shell、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 镜像构建运行时阶段 — 绝不要在探测命令中重新运行应用二进制文件;这会启动第二个实例,而不是检查第一个实例。

.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)
密钥使用环境变量或挂载的密钥,绝不要放入镜像中

评论

支持 Markdown