<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/distroless-chiseled-or-alpine-choosing-a-net-base-image-qqzpvdm6s" -->

---
title: Distroless, Chiseled or Alpine: Choosing a .NET Base Image
description: Choosing a .NET container base image should start with libc compatibility, not image size, because Alpine (musl), Ubuntu Chiseled and Azure Linux Distroless...
canonical: https://daily.dev/posts/distroless-chiseled-or-alpine-choosing-a-net-base-image-qqzpvdm6s
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Distroless, Chiseled or Alpine: Choosing a .NET Base Image | daily.dev
og:description: Choosing a .NET container base image should start with libc compatibility, not image size, because Alpine (musl), Ubuntu Chiseled and Azure Linux Distroless...
og:url: https://daily.dev/posts/distroless-chiseled-or-alpine-choosing-a-net-base-image-qqzpvdm6s
og:image: https://api.daily.dev/og/posts/QqZPVDm6s.png
og:image:alt: Distroless, Chiseled or Alpine: Choosing a .NET Base Image
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Distroless, Chiseled or Alpine: Choosing a .NET Base Image

**[Benjamin Abt](https://daily.dev/sources/benjaminabt)** · 12 min read · 15 upvotes · 0 comments

## Summary

Choosing a .NET container base image should start with libc compatibility, not image size, because Alpine (musl), Ubuntu Chiseled and Azure Linux Distroless (both glibc) are not interchangeable. Copying a linux-x64 build into Alpine can produce a DllNotFoundException even when the file matches the CPU architecture. All minimal variants omit ICU and time-zone data, so apps needing culture-aware formatting should use the 'extra' image variants instead. Native AOT still requires a matching musl RID and toolchain for Alpine. For most ASP.NET Core services, Ubuntu Chiseled is recommended as the default, with Azure Linux Distroless or Alpine reserved for specific platform or dependency needs.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://benjamin-abt.com/blog/2026/10/27/distroless-vs-chiseled-vs-alpine-dotnet>

## Questions this post answers

### Why does my .NET app throw DllNotFoundException when I copy a linux-x64 published output into an Alpine container?

Alpine uses musl as its C library while a linux-x64 build targets glibc, so native assets built for glibc can match the CPU architecture but fail to load under Alpine's musl loader. The fix is to publish with the linux-musl-x64 runtime identifier whenever the app or its packages include native assets, rather than reusing a glibc build.

_Developers containerizing .NET apps on Alpine track RID and libc pitfalls like this on daily.dev._

### Should I use Ubuntu Chiseled, Azure Linux Distroless, or Alpine as the base image for a new ASP.NET Core container?

Ubuntu Chiseled is the recommended default for a normal minimal ASP.NET Core service because it keeps broad glibc compatibility while removing the shell and package manager. Azure Linux Distroless fits when the platform is already governed around Azure Linux, and Alpine is appropriate only when every native dependency is deliberately tested against musl.

_Teams deciding between .NET container base images can keep up with guidance like this on daily.dev._

### Do I need the -extra variant of a .NET container image if my app needs culture-specific number formatting or time zones?

Yes, because the smallest Alpine, Chiseled, and Azure Linux Distroless variants all omit ICU and time-zone data by default. Applications needing culture-sensitive formatting, casing, sorting, parsing, or IANA time zone data should use the official 'extra' variant, such as aspnet:11.0-preview-resolute-chiseled-extra, instead of manually installing ICU.

_Developers avoiding globalization bugs in containerized .NET services follow details like this on daily.dev._

## Similar posts on daily.dev

- [Containerizing .NET in 2026 Without a Dockerfile](https://daily.dev/posts/containerizing-net-in-2026-without-a-dockerfile-fkwoukhiu) · Benjamin Abt · 14 upvotes · 0 comments
- [What you need to know about Red Hat's .NET container images](https://daily.dev/posts/what-you-need-to-know-about-red-hat-s-net-container-images-vzcctbo1n) · Red Hat Developer · 0 upvotes · 0 comments

---

Tags: [#docker](https://daily.dev/tags/docker), [#.net](https://daily.dev/tags/.net), [#aspnetcore](https://daily.dev/tags/aspnetcore)

[View this post on daily.dev](https://daily.dev/posts/distroless-chiseled-or-alpine-choosing-a-net-base-image-qqzpvdm6s)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Distroless, Chiseled or Alpine: Choosing a .NET Base Image","url":"https://daily.dev/posts/distroless-chiseled-or-alpine-choosing-a-net-base-image-qqzpvdm6s","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/distroless-chiseled-or-alpine-choosing-a-net-base-image-qqzpvdm6s"},"datePublished":"2026-10-27T00:22:00.578Z","dateModified":"2026-10-27T00:31:42.329Z","description":"Choosing a .NET container base image should start with libc compatibility, not image size, because Alpine (musl), Ubuntu Chiseled and Azure Linux Distroless...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/4daf9ce973b5167bd030f3be97d3fda8?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/4daf9ce973b5167bd030f3be97d3fda8?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Benjamin Abt","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Benjamin Abt","logo":"https://media.daily.dev/image/upload/s--zm3TLFn9--/f_auto,q_auto/v1791119044/logos/benjaminabt?_a=BAMAMicg0","url":"https://daily.dev/sources/benjaminabt"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/distroless-chiseled-or-alpine-choosing-a-net-base-image-qqzpvdm6s","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":15},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"docker,.net,aspnetcore","timeRequired":"PT12M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Benjamin Abt","item":"https://daily.dev/sources/benjaminabt"},{"@type":"ListItem","position":3,"name":"Distroless, Chiseled or Alpine: Choosing a .NET Base Image"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/distroless-chiseled-or-alpine-choosing-a-net-base-image-qqzpvdm6s#faq","mainEntity":[{"@type":"Question","name":"Why does my .NET app throw DllNotFoundException when I copy a linux-x64 published output into an Alpine container?","acceptedAnswer":{"@type":"Answer","text":"Alpine uses musl as its C library while a linux-x64 build targets glibc, so native assets built for glibc can match the CPU architecture but fail to load under Alpine's musl loader. The fix is to publish with the linux-musl-x64 runtime identifier whenever the app or its packages include native assets, rather than reusing a glibc build. Developers containerizing .NET apps on Alpine track RID and libc pitfalls like this on daily.dev."}},{"@type":"Question","name":"Should I use Ubuntu Chiseled, Azure Linux Distroless, or Alpine as the base image for a new ASP.NET Core container?","acceptedAnswer":{"@type":"Answer","text":"Ubuntu Chiseled is the recommended default for a normal minimal ASP.NET Core service because it keeps broad glibc compatibility while removing the shell and package manager. Azure Linux Distroless fits when the platform is already governed around Azure Linux, and Alpine is appropriate only when every native dependency is deliberately tested against musl. Teams deciding between .NET container base images can keep up with guidance like this on daily.dev."}},{"@type":"Question","name":"Do I need the -extra variant of a .NET container image if my app needs culture-specific number formatting or time zones?","acceptedAnswer":{"@type":"Answer","text":"Yes, because the smallest Alpine, Chiseled, and Azure Linux Distroless variants all omit ICU and time-zone data by default. Applications needing culture-sensitive formatting, casing, sorting, parsing, or IANA time zone data should use the official 'extra' variant, such as aspnet:11.0-preview-resolute-chiseled-extra, instead of manually installing ICU. Developers avoiding globalization bugs in containerized .NET services follow details like this on daily.dev."}}]}
```

