Blog Post

Containers
3 MIN READ

Making Windows Server Core Containers 40% Smaller

markosmezgebu's avatar
markosmezgebu
Icon for Microsoft rankMicrosoft
Dec 10, 2019

February 2022 update - to understand how the work blogged in this article from 2019 carries forward to the Windows container base images that ship in Windows Server 2022, please go to the official Windows container docs.

 

Windows Server Insider Preview builds have brought an exciting change to the Windows Server Core Container base image that we’d like to share with you. The Server Core Insider container base image download size is over 40% smaller than the 1903 base image, and container startup into Windows PowerShell is 30% faster!

 

This should be a big win for scaling applications in production, CI/CD, and any other workflow that benefits from faster startup or pulls uncached images.

 

The new images are currently available on the windows/servercore/insider repo on Docker Hub, and will land on the windows/servercore repo with our 20H1 release.

 

What changed?

For performance benefits, Server Core containers have always included a set of .NET pre-compiled native images generated by the Native Image Generator tool (Ngen.exe) to improve startup performance. Starting with our Insider images, the Server Core base image will include a much smaller set of NGEN images.

A larger set is included in .NET Framework runtime images (which are based on Windows Server Core), however, the .NET Framework runtime images are also much smaller because we can now ensure that there is only one copy of each NGEN image. Additionally, The NGEN images in the .NET Framework runtime image are now more intentionally selected to target ASP.NET and PowerShell performance. Tests have shown that container startup into Windows PowerShell has improved by 45% when using the Insider-based .NET Framework runtime image compared to the 1903 .NET Framework image.

How exactly have the sizes changed over time? Depends on what you measure sizes. Using the .NET team's method for retrieving Docker Image Sizes, here is how the latest Insider image compares to the first generally available* 1903 image, released in May 2019:

 

*[May, 22, 2020 Update]: Note that the 1903 image at time of general availability, includes an RTM ("Release to Manufacturing") layer, as well as a second layer containing a collection of monthly updates that accumulate over time.

 

  1903 GA 20H1
Download Size (GB) 1.92 1.13 -41%
Size on Disk (GB) 4.63 2.63 -43%

 

Note that running docker pull on the latest Insider image at the time of writing (Insider Build 19023) will display a download size of 1.22. This is because Docker's method for calculating differs slightly from the method linked above.

 

Image sizes fluctuate month-to-month as they receive monthly servicing updates. The results of the metrics referenced in this and other related blogs will fluctuate accordingly. Note that the size of 1903 used as a benchmark in the related blogs below are based on a a more recent version of 1903, one that has been serviced with several monthly patches that each cause size increases.

Check out the .NET Blog for a deeper dive into these changes, and the PowerShell Blog for PowerShell-centric guidance.

 

What does this mean?

Two things to keep in mind:

  • These changes will remain available for preview to registered Insiders on all current and upcoming builds featured on the windows/servercore/insider repo, and are expected to be Generally Available in the 20H1 windows/servercore release in 2020
  • Going forward, container images that make significant use of .NET Framework or Windows PowerShell should be built on top of the dotnet/framework/runtime container images, which will include additional .NET pre-compiled native images to maintain performance for those scenarios.

Note that while tests show that container startup into Windows PowerShell is 30% faster when using the Insider Server Core image when compared to 1903, Windows PowerShell startup within a running container is 100ms (15%) slower for the Insider image and 20ms (15%) slower on the Insider-based .NET Framework runtime image, when compared to their respective 1903 equivalents.

We’d love for you to test out the smaller Server Core image today on windows/servercore/insider and give us your feedback! Also, remember to check out the .NET blog and look out for corresponding .NET Framework images when 20H1 Windows Server Core containers are Generally Available.

 

Updated Feb 11, 2022
Version 21.0
  • mortenb123's avatar
    mortenb123
    Copper Contributor

    servercore:1903 is 5.05GB on disk:

    docker images | findstr.exe 1903
    REPOSITORY                             TAG                 IMAGE ID            CREATED             SIZE
    mcr.microsoft.com/windows/servercore   1903                1ef8f4bec5fd        6 weeks ago         5.05GB
    mcr.microsoft.com/windows              1903                bcfed1398664        6 weeks ago         13.1GB
    mcr.microsoft.com/windows/nanoserver   1903                ea84758f7458        6 weeks ago         256MB

    It is a lot of bits to move around.

     

  • NabilS2's avatar
    NabilS2
    Copper Contributor

    Hello Awesome Windows Server Team, markosmezgebu, @taylorb_msft

    we are in the process of re-platforming an enterprise application to the Windows Containers.

    our application is running with .Net Framework and can run on a Virtual Machine with
    Windows Server Core 2019 + "app compat Feat on demand"

    When we try to do the same install with the containers, the installer for the "App Compat FoD" Fails inside the container build.
    So we can't seem to be able to find a good way to add the missing libraries inside a Windows Core 2019 Container,
    and we are only left with the choice of using the "full windows image" container.

    What is the easiest way to add the libraries from the "App Compat FoD" into the Win Server Core Container 2019 ?
    Would Microsoft consider building a "Windows Core 2019 Container ++ ? " which would include the App Compate FoD ?


    I would bet that there are many companies trying to move ".Net Framework" applications to Containers,
    without/before re-writing them in ".Net Core". so you would really be helping all of us out there if you can show a way to handle this.