Skip to content

Pack ImageBuilder as dotnet tool#2007

Open
lbussell wants to merge 4 commits intodotnet:mainfrom
lbussell:pack-as-tool
Open

Pack ImageBuilder as dotnet tool#2007
lbussell wants to merge 4 commits intodotnet:mainfrom
lbussell:pack-as-tool

Conversation

@lbussell
Copy link
Member

@lbussell lbussell commented Mar 6, 2026

This is related to #2006. Since ImageBuilder is only used natively on Windows (and not ran from inside a container image), I would like to explore distributing ImageBuilder as a tool instead of a container image for that platform. The central hypothesis here is that we could potentially remove the Windows build leg of ImageBuilder entirely, speeding up build and iteration time.

This PR only adds a new acquisition channel for ImageBuilder. It does not remove Windows container images or anything like that.

@lbussell lbussell requested a review from a team as a code owner March 6, 2026 19:14
@mthalman
Copy link
Member

mthalman commented Mar 6, 2026

The central hypothesis here is that we could potentially remove the Windows build leg of ImageBuilder entirely, drastically speeding up build and iteration time.

In January of 2027, Windows Server 2016 will be EOL. Dropping support for that would allow us to run ImageBuilder in a container just like we do for Linux because 2016 is the version that doesn't allow us to run nested containers. So that's only 9 months away. I'd rather keep the status quo until that point and then move forward with running ImageBuilder in a container in Windows. That will allow us to finally have a common pattern across both platforms.

@lbussell
Copy link
Member Author

lbussell commented Mar 6, 2026

In January of 2027, Windows Server 2016 will be EOL. Dropping support for that would allow us to run ImageBuilder in a container just like we do for Linux because 2016 is the version that doesn't allow us to run nested containers. So that's only 9 months away. I'd rather keep the status quo until that point and then move forward with running ImageBuilder in a container in Windows. That will allow us to finally have a common pattern across both platforms.

Trust me, I too am counting the days until Server 2016 EOL.

However, the latest ImageBuilder build took 1 hour and 27 minutes. Whereas it takes literally 40 seconds to do a fully clean restore + build + test + pack of this repo on my laptop. It is not an exaggeration to say that we could ship changes 10x or even 20x faster by ditching Docker-in-Docker.

@mthalman
Copy link
Member

mthalman commented Mar 9, 2026

However, the latest ImageBuilder build took 1 hour and 27 minutes. Whereas it takes literally 40 seconds to do a fully clean restore + build + test + pack of this repo on my laptop. It is not an exaggeration to say that we could ship changes 10x or even 20x faster by ditching Docker-in-Docker.

First, I'm not understanding the comparison of a local build to the full pipeline run. There's all kinds of overhead associated with that even when taking containers out of the equation. This proposal is to replace Windows images with the dotnet tool so the pipeline duration will still effectively exist as a result of still building Linux images. And when we update ImageBuilder, we need to build both Windows and Linux. So what are we really gaining from this?

@lbussell
Copy link
Member Author

lbussell commented Mar 9, 2026

First, I'm not understanding the comparison of a local build to the full pipeline run. There's all kinds of overhead associated with that even when taking containers out of the equation. This proposal is to replace Windows images with the dotnet tool so the pipeline duration will still effectively exist as a result of still building Linux images. And when we update ImageBuilder, we need to build both Windows and Linux. So what are we really gaining from this?

Okay, sure, the build time comparison is a little unfair. Take my example build time as a lower bound. My point was that we are way too far away from the lower bound. I'd be happy with something like 10 minutes. Not 80-90 minutes.

I calculated some numbers based on the pipeline mentioned in #2006. Assuming that build agent wait times stay the same, not running Windows builds in this pipeline would have saved 12m 47s of wall clock time and 42m 48s of machine time.

And when we update ImageBuilder, we need to build both Windows and Linux.

Not really, one build+pack of a dotnet tool will work for all platforms - unless I am misunderstanding your point here?

Either way, this PR does nothing but add another distribution mechanism for ImageBuilder, which allows us to experiment further with this idea.

@mthalman
Copy link
Member

Not really, one build+pack of a dotnet tool will work for all platforms - unless I am misunderstanding your point here?

I'm talking about the pipeline. Are you suggesting that we migrate to the tool for both Linux and Windows? Because your PR description seemed to be focused on Windows. And my point that making Windows build faster still leaves you with the overhead of building Linux images.

@lbussell
Copy link
Member Author

lbussell commented Mar 10, 2026

Are you suggesting that we migrate to the tool for both Linux and Windows?

No.

And my point that making Windows build faster still leaves you with the overhead of building Linux images.

Correct. The Windows Server 2016/2019 is the long pole in the ImageBuilder build pipeline because it downloads the 5+ gigabyte Windows Server 2016 base image for no good reason. Using the dotnet tool instead of a container image on Windows means we would no longer have to build any Windows ImageBuilder images, making the ImageBuilder pipeline ~10% faster.

I would also like to explore using the ImageBuilder tool for local development in the dotnet-docker repo instead of using docker, since it will be much faster to start up for things like Dockerfile template generation.

As a reminder this PR will publish the tool in the arcade publishing pipeline along with the ImageBuilder.Models package, so we essentially get the tool publishing for free.


<PropertyGroup>
<OutputType>Exe</OutputType>
<AssemblyName>imagebuilder</AssemblyName>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will impact other things:

$imageBuilderCmd = [System.IO.Path]::Combine($imageBuilderFolder, "Microsoft.DotNet.ImageBuilder.exe")

$runImageBuilderCmd = "$(Build.BinariesDirectory)\.Microsoft.DotNet.ImageBuilder\Microsoft.DotNet.ImageBuilder.exe"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a separate branch with those changes here: lbussell@ab7ec6e

These changes would break this PR since it is not using the updated version of ImageBuilder yet.

I think that we could also use <ToolCommandName/> here instead though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants