Skip to content

Commit 4bde15c

Browse files
authored
Update image size comparison documentation (#6816)
1 parent caa532b commit 4bde15c

1 file changed

Lines changed: 65 additions & 31 deletions

File tree

Lines changed: 65 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,78 @@
1-
# .NET Container Image Size Report
1+
# .NET image size comparison
22

3-
.NET offers a variety of deployment options for applications, which pair with container images that we offer. It's possible to produce very small container images. This document summarizes the available options to help you make the best choice for your apps and environment.
3+
.NET offers a variety of deployment options for applications which pair well
4+
with the container images that we publish. It's possible to produce very small
5+
container images. This document summarizes the available options to help you
6+
make the best base image choice for your apps and environment.
47

5-
All images were produced from the ["releasesapi" sample](https://github.com/dotnet/dotnet-docker/tree/main/samples/releasesapi) using Ubuntu 22.04 ("jammy") images for amd64.
6-
Alpine images will be similar.
7-
The Baseline image is a standard [framework-dependent](https://learn.microsoft.com/dotnet/core/deploying/#publish-framework-dependent) deployment on the ASP.NET runtime image.
8-
This is the largest image with the most functionality and flexibility.
9-
However, the new [Ubuntu Chiseled](https://github.com/dotnet/dotnet-docker/blob/main/documentation/ubuntu-chiseled.md) .NET base images can provide significantly smaller and more secure deployments for your application as demonstrated below.
8+
The table below shows how base image choice and publish type affects typical
9+
image sizes and for a simple .NET minimal web API. These images were produced
10+
from the ["releasesapi" sample](../samples/releasesapi).
11+
12+
| Base Image | Publish Type | Distroless | Globalization | Compressed Size |
13+
| ------------------------------------------ | ----------------------------- | ---------- | ------------- | --------------: |
14+
| [`aspnet:10.0`] | [Framework-dependent] | ✖️ No | ✅ Yes | 92.48 MB |
15+
| [`aspnet:10.0-noble-chiseled`] | [Framework-dependent] | ✅ Yes | ✖️ No | 52.81 MB |
16+
| [`aspnet:10.0-noble-chiseled-extra`] | [Framework-dependent] | ✅ Yes | ✅ Yes | 67.68 MB |
17+
| [`runtime-deps:10.0`] | [Self-contained] + [Trimming] | ✖️ No | ✖️ No | 61.53 MB |
18+
| [`runtime-deps:10.0`] | [Self-contained] + [Trimming] | ✖️ No | ✅ Yes | 61.63 MB |
19+
| [`runtime-deps:10.0-noble-chiseled`] | [Self-contained] + [Trimming] | ✅ Yes | ✖️ No | 21.86 MB |
20+
| [`runtime-deps:10.0-noble-chiseled-extra`] | [Self-contained] + [Trimming] | ✅ Yes | ✅ Yes | 36.82 MB |
21+
| [`runtime-deps:10.0`] | [Native AOT] | ✖️ No | ✖️ No | 51.27 MB |
22+
| [`runtime-deps:10.0`] | [Native AOT] | ✖️ No | ✅ Yes | 51.36 MB |
23+
| [`runtime-deps:10.0-noble-chiseled`] | [Native AOT] | ✅ Yes | ✖️ No | 11.60 MB |
24+
| [`runtime-deps:10.0-noble-chiseled-extra`] | [Native AOT] | ✅ Yes | ✅ Yes | 26.56 MB |
25+
| [`aspnet:10.0-alpine`] | [Framework-dependent] | ✖️ No | ✖️ No | 51.93 MB |
26+
| [`runtime-deps:10.0-alpine`] | [Self-contained] + [Trimming] | ✖️ No | ✖️ No | 20.95 MB |
27+
| [`runtime-deps:10.0-alpine-extra`] | [Self-contained] + [Trimming] | ✖️ No | ✅ Yes | 35.52 MB |
28+
| [`runtime-deps:10.0-alpine`] | [Native AOT] | ✖️ No | ✖️ No | 10.69 MB |
29+
| [`runtime-deps:10.0-alpine-extra`] | [Native AOT] | ✖️ No | ✅ Yes | 25.25 MB |
1030

1131
> [!NOTE]
12-
> The recorded image sizes are a snapshot of deployment sizes at the time of .NET 8.0 GA.
13-
> Image sizes will fluctuate over time due to base image updates and updated package installations.
14-
> This document will not be updated over time. The key takeaway is the size *difference* between the different models.
32+
> Please note that these image sizes are a snapshot of deployment sizes from
33+
> November 2025. Image sizes will fluctuate over time due to base image and
34+
> package updates.
1535
16-
## Framework-Dependent Deployment
36+
Watch the [announcements page](https://github.com/dotnet/dotnet-docker/discussions/categories/announcements)
37+
for the latest information on new features and changes in .NET container images.
1738

18-
| Image Kind | Base Image | Uncompressed Image Size | Compressed Image Size | % Size Savings Over Baseline[^1] |
19-
| --- | --- |--- | --- | --- |
20-
| Baseline | [`aspnet:8.0-jammy`](https://github.com/dotnet/dotnet-docker/blob/main/src/aspnet/8.0/jammy/amd64/Dockerfile)| 217 MB | 90.9 MB | |
21-
| [Chiseled](https://github.com/dotnet/dotnet-docker/blob/main/documentation/ubuntu-chiseled.md) | [`aspnet:8.0-jammy-chiseled`](https://github.com/dotnet/dotnet-docker/blob/main/src/aspnet/8.0/jammy-chiseled/amd64/Dockerfile)| 111 MB | 49.3 MB | 46% |
22-
| [Chiseled](https://github.com/dotnet/dotnet-docker/blob/main/documentation/ubuntu-chiseled.md) + [ASP.NET Composite Runtime](https://github.com/dotnet/dotnet-docker/blob/main/documentation/image-variants.md#composite-net-80) | [`aspnet:8.0-jammy-chiseled-composite`](https://github.com/dotnet/dotnet-docker/blob/main/src/aspnet/8.0/jammy-chiseled-composite/amd64/Dockerfile)| 103 MB | 40.8 MB | 55% |
39+
## About Publishing Options
2340

24-
## Self-Contained + Trimming Deployment
41+
### .NET Image Variants
2542

26-
[Self-contained](https://learn.microsoft.com/dotnet/core/deploying/#publish-self-contained) deployments bundle the .NET Runtime with your app so that it's able to run without the full .NET Runtime installed.
27-
[IL Trimming](https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-self-contained) for self-contained apps removes unused code from the .NET Runtime and libraries to reduce application size.
28-
And [Native AOT](https://learn.microsoft.com/dotnet/core/deploying/native-aot/) deployment produces an app that is completely compiled to native code at build time for the smallest deployment size that .NET allows for.
43+
- **[Ubuntu Chiseled] images** images are a type of [distroless container image](./distroless.md)
44+
that contain only a minimal set of packages with everything else removed - no
45+
shell, no package manager, and no globalization support by default. This
46+
results in a dramatically smaller deployment size and attack surface.
47+
- **`extra` images** add `icu` and `tzdata` to Alpine and Chiseled/distroless
48+
images for full globalization support in .NET apps.
2949

30-
| Image Kind | Base Image | Uncompressed Image Size | Compressed Image Size | % Size Savings Over Baseline[^1] |
31-
| --- | --- |--- | --- | --- |
32-
| [Self-contained](https://learn.microsoft.com/dotnet/core/deploying/#publish-self-contained) + [Trimming](https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-self-contained) | [`runtime-deps:8.0-jammy`](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/8.0/jammy/amd64/Dockerfile) | 146 MB | 57.9 MB | 36% |
33-
| [Chiseled](https://github.com/dotnet/dotnet-docker/blob/main/documentation/ubuntu-chiseled.md) + [Self-contained](https://learn.microsoft.com/dotnet/core/deploying/#publish-self-contained) + [Trimming](https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-self-contained) | [`runtime-deps:8.0-jammy-chiseled`](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/8.0/jammy-chiseled/amd64/Dockerfile)| 39.3 MB | 16.4 MB | 82% |
34-
| [Native AOT](https://learn.microsoft.com/dotnet/core/deploying/native-aot/) | [`runtime-deps:8.0-jammy-chiseled`](https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/8.0/jammy-chiseled/amd64/Dockerfile)| 27.7 MB | 12.4 MB | 86% |
50+
See [.NET Image Variants](https://github.com/dotnet/dotnet-docker/blob/main/documentation/image-variants.md)
51+
for more details.
3552

36-
For more information on .NET image variants and AOT images, please see the following documentation:
53+
### Publishing Types
3754

38-
- [.NET Image Variants](https://github.com/dotnet/dotnet-docker/blob/main/documentation/image-variants.md)
39-
- [Announcement: .NET 10 AOT container images](https://github.com/dotnet/dotnet-docker/discussions/6312)
40-
- [Announcement: New approach for differentiating .NET 8+ images](https://github.com/dotnet/dotnet-docker/discussions/4821)
55+
- **[Self-contained]** deployments bundle the .NET Runtime with your app so that
56+
it can run without the .NET Runtime installed.
57+
- **[Trimming]** for self-contained apps removes unused code from the .NET
58+
Runtime and libraries to reduce application size.
59+
- **[Native AOT]** deployment produces an app that is compiled ahead-of-time
60+
(AOT) for the smallest deployment size and startup time.
4161

42-
Watch the [announcements page](https://github.com/dotnet/dotnet-docker/discussions/categories/announcements) for the latest information on new features and changes in .NET contanier images.
62+
See [".NET Application Publishing Overview"](https://learn.microsoft.com/dotnet/core/deploying)
63+
for more details on all of the supported options for publishing .NET apps.
4364

44-
[^1]: Percentage of size savings is based on compressed image size.
65+
[Ubuntu Chiseled]: https://github.com/dotnet/dotnet-docker/blob/main/documentation/ubuntu-chiseled.md
66+
[Self-contained]: https://learn.microsoft.com/dotnet/core/deploying/#publish-self-contained
67+
[Trimming]: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-self-contained
68+
[Native AOT]: https://learn.microsoft.com/dotnet/core/deploying/native-aot/
69+
[Framework-dependent]: https://learn.microsoft.com/dotnet/core/deploying/#publish-framework-dependent
70+
[`aspnet:10.0`]: https://github.com/dotnet/dotnet-docker/blob/main/src/aspnet/10.0/noble
71+
[`aspnet:10.0-noble-chiseled`]: https://github.com/dotnet/dotnet-docker/blob/main/src/aspnet/10.0/noble-chiseled
72+
[`aspnet:10.0-noble-chiseled-extra`]: https://github.com/dotnet/dotnet-docker/blob/main/src/aspnet/10.0/noble-chiseled-extra
73+
[`runtime-deps:10.0`]: https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/10.0/noble
74+
[`runtime-deps:10.0-noble-chiseled`]: https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/10.0/noble-chiseled
75+
[`runtime-deps:10.0-noble-chiseled-extra`]: https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/10.0/noble-chiseled-extra
76+
[`aspnet:10.0-alpine`]: https://github.com/dotnet/dotnet-docker/blob/main/src/aspnet/10.0/alpine3.22
77+
[`runtime-deps:10.0-alpine`]: https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/10.0/alpine3.22
78+
[`runtime-deps:10.0-alpine-extra`]: https://github.com/dotnet/dotnet-docker/blob/main/src/runtime-deps/10.0/alpine3.22-extra

0 commit comments

Comments
 (0)