| name | dotnet-docker-deploy |
| description | Configure Docker, Docker Compose, .NET Aspire orchestration, and CI/CD pipelines for .NET 10 applications. Use when user says "dockerize", "add Docker", "docker-compose", "Aspire setup", "deploy", "CI/CD", "GitHub Actions", "production deployment", "containerize", or asks about deployment and orchestration. |
| metadata | {"author":"Claude-DotNet-Ultimate","version":"1.0.0","category":"deployment"} |
Docker & Deployment
Multi-Stage Dockerfile (Chiseled Ubuntu)
FROM mcr.microsoft.com/dotnet/aspnet:10.0-chiseled AS base
WORKDIR /app
EXPOSE 8080
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
COPY ["Directory.Build.props", "."]
COPY ["Directory.Packages.props", "."]
COPY ["src/Core/ClaudeDotNetUltimate.Core.csproj", "Core/"]
COPY ["src/Application/ClaudeDotNetUltimate.Application.csproj", "Application/"]
COPY ["src/Infrastructure/ClaudeDotNetUltimate.Infrastructure.csproj", "Infrastructure/"]
COPY ["src/Api/ClaudeDotNetUltimate.Api.csproj", "Api/"]
RUN dotnet restore "Api/ClaudeDotNetUltimate.Api.csproj"
COPY src/ .
WORKDIR "/src/Api"
RUN dotnet build -c Release -o /app/build
FROM build AS publish
RUN dotnet publish -c Release -o /app/publish /p:UseAppHost=true
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["./ClaudeDotNetUltimate.Api"]
Chiseled image benefits: ~100MB vs ~250MB, no shell, no package manager, reduced CVE exposure.
Docker Compose (Local Development)
services:
api:
build: .
ports:
- "8080:8080"
depends_on:
postgres: { condition: service_healthy }
redis: { condition: service_healthy }
rabbitmq: { condition: service_healthy }
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ConnectionStrings__Default=Host=postgres;Database=claudedb;Username=postgres;Password=postgres
- ConnectionStrings__Redis=redis:6379
- RabbitMQ__Host=rabbitmq
postgres:
image: postgres:17-alpine
environment:
POSTGRES_DB: claudedb
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports: ["5432:5432"]
volumes: [pgdata:/var/lib/postgresql/data]
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
ports: ["6379:6379"]
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
rabbitmq:
image: rabbitmq:3-management-alpine
ports: ["5672:5672", "15672:15672"]
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "check_port_connectivity"]
interval: 10s
volumes:
pgdata:
.NET Aspire Orchestration
AppHost (src/Aspire/AppHost/Program.cs)
var builder = DistributedApplication.CreateBuilder(args);
var postgres = builder.AddPostgres("postgres")
.WithPgAdmin()
.WithDataVolume();
var redis = builder.AddRedis("redis")
.WithRedisCommander();
var rabbitmq = builder.AddRabbitMQ("rabbitmq")
.WithManagementPlugin();
builder.AddProject<Projects.ClaudeDotNetUltimate_Api>("api")
.WithExternalHttpEndpoints()
.WithReference(postgres)
.WithReference(redis)
.WithReference(rabbitmq)
.WaitFor(postgres)
.WaitFor(redis)
.WaitFor(rabbitmq);
builder.Build().Run();
GitHub Actions CI/CD
name: Build and Deploy
on:
push: { branches: [main] }
pull_request: { branches: [main] }
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with: { dotnet-version: '10.0.x' }
- run: dotnet restore --verbosity minimal
- run: dotnet build --no-restore -c Release
- run: dotnet test --no-build -c Release --verbosity normal
- run: dotnet publish -c Release -o ./publish --no-build
- uses: docker/build-push-action@v5
with:
context: .
push: ${{ github.ref == 'refs/heads/main' }}
tags: ${{ vars.REGISTRY }}/api:${{ github.sha }}
Commands
docker build -t claude-dotnet-ultimate:latest .
docker-compose up -d
docker-compose down
docker-compose logs -f api
dotnet run --project src/Aspire/AppHost/ClaudeDotNetUltimate.AppHost.csproj
Health Checks
Already configured at:
/health — Overall health
/health/ready — Readiness (DB + Redis connected)
/health/live — Liveness (app running)
Production Checklist