Built-in container support for the .NET SDK
devblogs.microsoft.com
devblogs.microsoft.com
Broadly we just want to lower barriers to containerization for all .NET developers. Jib/Ko/etc are proven patterns in this field, and we saw an opportunity to use the existing infrastructure of MSBuild to reduce the amount of concepts our users would need to know in order to be successful in their journey to the cloud. On top of that, having the feature in SDK provides some opportunities to help users adhere to conventions around container labeling (or customize container metadata entirely!) so we can make .NET containers good citizens in the container ecosystem overall.
Hah, I don't know - my experiences with Jib have only ever been negative. Having something like a Dockerfile that lets you customize everything that goes into the container and only having to worry about your app as a .jar file seemed like a better option to me, rather than having some plugin that integrates with your build tooling and feels infinitely more opaque all of the sudden: https://cloud.google.com/java/getting-started/jib
Essentially if you'd need a bunch of custom packages, e.g. some non-open-source fonts so your PDF export in your Java app would work correctly, you'd still probably need a custom base image, thus slightly negating the benefits of this apparent simplification: https://cloud.google.com/java/getting-started/jib#base-image
In addition, the images that were generated (last I tried) didn't have proper timestamps and thus showed up in Docker as created decades ago, which might be good from a reproducible build perspective (same code --> same image), but still felt unintuitive when you actually looked at the images.
But hey, maybe I'm just used to Dockerfiles and not needing a different plugin for each separate technology stack - looking at any application as just a Dockerfile (or a similar equivalent) regardless of whether it runs Java, Ruby, .NET, Python, Node or something else under the hood has always seemed like a good idea.
I'm glad that people who like alternative approaches have those options!
Personally (bit of a tangent here), I also found things like dealing with memory limits in JVM (e.g. the container needs a bit of free memory not to OOM, so JVM needs to leave a bit free, but Xmx is not the actual limit and will still be exceeded, alas there is no actual JVM_MAX_MEMORY_LIMIT_MB parameter so it's a bit of a pain if you want stable containers that don't crash). to be problematic, so it's nice that various different technologies are getting attention, be it Jib, .NET or something else!
.NET just generally seems like a pretty sane and performant option (primarily for web development, but for other use cases as well), especially with how it feels like most of what you need comes out of the box vs the more fragmented nature of other stacks (e.g. Spring and its plugins like Hibernate/myBatis/jOOQ in Java land).
In summary: I still believe that this (much like the other tools in the space) will be good for people who don't want to learn all of the concepts of what Docker/Buildah/... provide you with and will make building containers for your particular stack more easy. Though this will come at the expense of having multiple separate tools for different tech stacks, which may or may not erase some of the benefits, depending on how polyglotic your stack is.
* eventually providing an 'eject' mechanism to create the matching Dockerfile for a given project. this serves as a basis for any customization you might need, as well as a base language that many existing tools can understand.
* making it easy to include arbitrary image layers by reference in your container through a syntax like `<ContainerLayer Include="<layer SHA ref>" />`. This makes it easy to grab already-built components and inject them into your build.
I entirely agree with your summary. More choices, but all built on the same standard foundation :)
Now for the problem:
I still don't understand why other people compile dotnet projects in containers. Today, we have a many containers built on a monolith, and it looks like if I make containers via `-p:PublishProfile=DefaultContainer`--for example, 20 containers--then that CI build is going to compile our codebase 20 separate times. With `-p:PublishProfile=DefaultContainer`, the long build is mostly duplicated in each container. Right?
So I have one major problem preventing me from adopting this: it's compiling in the container, which balloons our build time.
It's entirely possible I'm missing something obvious or misinterpreting the situation, and if so, please let me know. I'm mostly immune to feeling shame and appreciate feedback.
Having said that, because the .Net toolchain is capable of cross-targeting this feature should enable broad swaths of users to not need to build inside a container to get a container created. So I completely agree with your puzzlement here and would hope that this feature leads to a reduction in that particular pattern.
I have never had .NET build issues due to environment inconsistencies across team members. I think NuGet is pretty good at making the dependencies consistent. No need for containers.
Here's the problem Microsoft should be solving instead: Once a docker image is built, how can my customer (not me) deploy it to Azure using their Azure account? I would like to provide a "Deploy to Azure" button similar to Heroku's "Deploy to Heroku". My customer should be able to deploy a web application using my docker image with a single click, using their Azure subscription. Heroku even provisions a Postgres database in the process. And it was all free until a couple of days ago.
Not at the moment, from the article:
"We have focused on the Linux-x64 image deployment scenario for this initial release. Windows images and other architectures are key scenarios we plan to support for the full release, so watch out for new developments there."
So, ignoring that, this seems like a first cut.
The rational for this seems to be streamlining docker builds when working with dotnet:
"This Dockerfile works very well, but there are a few caveats to it that aren’t immediately apparent, which arise from the concept of a Docker build context. The build context is a the set of files that are accessible inside of a Dockerfile, and is often (though not always) the same directory as the Dockerfile. If you have a Dockerfile located beside your project file, but your project file is underneath a solution root, it’s very easy for your Docker build context to not include configuration files like Directory.Packages.props or NuGet.config that would be included in a regular dotnet build. You would have this same situation with any hierarchical configuration model, like EditorConfig or repository-local git configurations.
This mismatch between the explicitly-defined Docker build context and the .NET build process was one of the driving motivators for this feature. All of the information required to build an image is present in a standard dotnet build, we just needed to figure out the right way to represent that data in a way that container runtimes like Docker could use."
Why is this a problem in your opinion? I'm not trying to catch you out, but as someone who's not using docker for .net builds/deployments I'm trying to understand why you're dismissing this feature.
COPY bin/Release/net5.0/publish .
It works fine. WTF are they talking about a mismatch between explicit definition and the .NET build process?A modern variation of “embrace, extend, extinguish”. I doubt MS has the power or desire to extinguish containers, but getting a foot in to the deployments space would be a win for them “use dotnet because it deploys better than other solutions”.
IMO for a significant part of the user base there's no reason to have to manage that at all - .NET is capable of cross-targeting enough to not need to perform the build inside of a container. That keeps the user in the 'build context' that they are used to, and we can use all of that context to still end up at the ideal result - a correct container, with all of their app dependencies.
I personally don't -- I publish on the host build agent and just Dockerize the publish directory
Full disclosure: Engineer at Microsoft (and previously Docker) not at all involved in .NET. I work on moby (aka docker project) and internal builds of docker and CNCF related projects.
dotnet publish -c Release
Then in Dockerfile add this: COPY bin/Release/net5.0/publish .
Is that hard?