Understanding Microsoft's "chiseled" Docker containers for .NET applications

Posted: (EET/GMT+2)

 

If you're using Docker with .NET, you may have noticed Microsoft's recent announcement of "chiseled" Docker containers for .NET applications. This appears to be one of the more pragmatic, modern approaches to container images, and worth understanding if you care about startup speed, security, and size of your deployments.

Okay, good. But what does "chiseled" mean? In this context, the term "chiseled" refers to container images that are intentionally minimal. They cut down to exactly the parts your application needs, and nothing more. Just like a sculpture refined with a chisel, these images drop unnecessary layers, tools, runtimes, and metadata that are not required for production. The result: smaller, leaner, faster, more secure containers.

Specifically, chiseled containers aim to:

  • Minimize image size: which reduces network transfer time, storage consumption, and attack surface.
  • Improve security: by removing build tools, package managers, debug info and other components that could be abused in a container environment.
  • Speed up startup and deployment: smaller images extract and unpack faster; less overhead for container orchestration.
  • Encourage best practices: production containers only contain what's strictly necessary, similar to native production servers.

With this knowledge, the next question is: how do you use such a "chiseled" .NET container? With .NET 7+ and the chiseled container support, creating a minimal container for your application becomes quite easy. Here is a minimal example of a Dockerfile:

FROM mcr.microsoft.com/dotnet/chiseled:7.0 AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY . .
RUN dotnet publish -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "MyApp.dll"]

This pattern builds your application in a full SDK image (so you have the compilers, tools, etc.), but produces the final artifact in a minimal, slim "chiseled" image, ensuring your runtime container is clean and compact.

Chiseled containers are especially useful when:

  • Microservices or many small services, where container size and speed matter.
  • Cloud deployments or container orchestration platforms where startup speed, network traffic and storage quotas matter.
  • Security-conscious environments, such as production deployments where you don't want unnecessary tools or metadata in the container.
  • Cost-sensitive deployments: smaller images can reduce bandwidth, storage, and cold-start costs.

Of course, the tradeoff is that debugging and introspection become harder (because many tools are stripped out), so this is most suitable for production builds. For development or diagnostics you may still want a fuller image.

In my opinion, chiseled containers represent a logical evolution for .NET Docker workloads. They are a way to move towards minimalism, improved performance and security, without losing the productivity of .NET. If you run .NET containers in production, these new container images are worth evaluating.

Happy containerizing!