How to Deploy .NET to Docker Without Writing a Dockerfile

M
Miget Team
Writer
January 14, 2026
5 min read

You can containerize any .NET application without writing a Dockerfile using migetpacks. It auto-detects your .NET SDK version from global.json or *.csproj, runs dotnet publish with production optimizations, removes source code from the final image, and outputs a slim ASP.NET runtime image. One command, zero configuration.


Why Is Writing a Dockerfile for .NET So Complicated?

A production-ready .NET Dockerfile requires:

  • Multi-stage builds to separate SDK from runtime
  • Choosing between .NET 6, 7, 8, or 9
  • dotnet restore caching for faster builds
  • dotnet publish -c Release with proper output paths
  • Removing source code after compilation
  • Choosing between aspnet and runtime base images
  • Container-optimized settings (DOTNET_RUNNING_IN_CONTAINER)

Get the publish configuration wrong and you ship source code or debug symbols to production.

How Do I Containerize a .NET App Without a Dockerfile?

Open your terminal, navigate to your .NET project, and run:

cd ~/projects/my-aspnet-api

docker run --rm \
  -v "$PWD":/workspace/source \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e OUTPUT_IMAGE=my-aspnet-api:latest \
  miget/migetpacks:latest

That's it. migetpacks will:

  1. Detect .NET from *.csproj, *.sln, or global.json
  2. Read SDK version from project files
  3. Run dotnet restore with NuGet caching
  4. Run dotnet publish -c Release
  5. Remove all source code (.cs, .csproj, etc.)
  6. Output a slim ASP.NET runtime image

How Does migetpacks Detect My .NET Version?

Version is resolved in this order:

SourceExample
global.json (sdk.version){"sdk": {"version": "8.0.100"}}
*.csproj (TargetFramework)<TargetFramework>net8.0</TargetFramework>
Default8.0

The TargetFramework value has the net prefix stripped (e.g., net8.0 becomes 8.0).

What Does the Generated Dockerfile Look Like?

# Build stage
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS builder
WORKDIR /build

ENV NUGET_XMLDOC_MODE=skip
ENV DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
ENV DOTNET_NOLOGO=1

COPY . .

RUN dotnet restore \
    && dotnet publish --configuration Release --no-restore -p:PublishDir=bin/publish

# Runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY --from=builder --chown=1000:1000 /build /app

You never write or maintain this file - migetpacks handles it automatically.

What Gets Removed After Compilation?

Since .NET is a compiled language, source code is completely removed from the runtime image:

RemovedReason
*.cs, *.fs, *.vbSource files (compiled to DLLs)
*.csproj, *.fsproj, *.vbprojProject files
*.sln, *.slnxSolution files
obj/Intermediate build files
bin/Release/net*/, bin/Debug/Non-publish build output

Only the bin/publish/ directory contents are kept in the final image.

What Runtime Configuration Is Applied?

VariableValue
ASPNETCORE_ENVIRONMENTProduction
DOTNET_RUNNING_IN_CONTAINERtrue
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT1
DOTNET_CLI_TELEMETRY_OPTOUT1
ASPNETCORE_HTTP_PORTS5000

How Do I Build an ASP.NET Core Web API?

ASP.NET Core works out of the box:

cd ~/projects/my-webapi

docker run --rm \
  -v "$PWD":/workspace/source \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e OUTPUT_IMAGE=my-webapi:latest \
  miget/migetpacks:latest

# Run the container
docker run -p 5000:5000 my-webapi:latest

How Do I Build a Monorepo Project?

Use PROJECT_PATH to specify which project to build:

cd ~/projects/my-monorepo

docker run --rm \
  -v "$PWD":/workspace/source \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e OUTPUT_IMAGE=my-api:latest \
  -e PROJECT_PATH=src/MyApi \
  miget/migetpacks:latest

How Do I Build Secure Distroless Images?

Enable Docker Hardened Images for minimal containers:

docker run --rm \
  -v "$PWD":/workspace/source \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e OUTPUT_IMAGE=my-app:latest \
  -e USE_DHI=true \
  miget/migetpacks:latest

DHI uses distroless ASP.NET Core images - no shell, no package manager, minimal attack surface.

Next Steps

Stay UpdatedWith Latest Posts

Subscribe to our newsletter and never miss a new blog post, update, or special offer from the Miget team.