Maybe I am unfair, but when using Microsoft development tools, it often feels like they only as an afterthought are adapted for professional development. The main acceptance criterion is mainly – does it look cool to the casual observer when we show it at Build?
Azure SDK
When the cloud became cool, Microsoft added a menu option to Visual Studio, so that you could click a button and push a website to Azure. Cool, right? Well – how would you use it in real life? Give developers access to push directly from Visual Studio? Seriously? Also – there is an option to attach a debugger to an azure website. Obviously not a scalable way to develop, but in a crisis it could be a Hail Mary when working with a non-production environment, but if you didn’t cowboy deploy like above, this Hail Mary is not available. Surely, if they had spent five minutes working this out on paper before they built it they could have created much more useful versions of these features
Containerisation
So here is a backgrounder on a major shift in how software is developed and deployed, including the struggle Microsoft have had to stay relevant and it features a couple of major technical achievements marred by minor impracticalities, negating a lot of usefulness.
A few years ago a company called Docker bundled some Linux kernel features and used them to wrap software into little half-isolated worlds that ran on the same machine, shared operating system and could communicate amongst themselves in prescribed ways, but were otherwise isolated. Thinner isolation than full VMs, and horizontally sliced to promote resource sharing and make better use of cloud infrastructure. They called these half isolated worlds containers, and the rest was history. “Works on my machine” At Scale, as some put it. Microsoft were livid. Once again they were left in the cold because no cool kids will use their operating system. After a Herculean effort people bodged together a thing called Docker for Windows based on VirtualBox or Hyper-V, the Bing of hypervisors. Basically you could run Linux docker containers on Windows so now one year’s Build talks were safe, but the efforts to stay relevant continued. They tried to build Windows containers, but a minimum Windows install was several tens of gigabytes, so work began on cutting superfluous cruft from a dedicated container edition of Windows to make it as small as Linux, but Windows containers still didn’t take off.
Microsoft at the same time after many years of developers complaining about the Windows command-line experience decided to bring actual native Bash to Windows by emulating(!) Linux on Windows, reimplementing most of the Linux syscall ABI in a new subsystem called WSL. It could run a lot of Ubuntu which set hearts and minds racing, but didn’t provide a big enough syscall compatibility to be able to run Docker, but still a massive feat of software engineering.
A year later Microsoft ships the second generation of WSL, now no longer a reimplementation but a full-fledged Linux distribution run virtualised with almost completely transparent booting of the VM in the background, full file system integration and beefed up command-line integration. Extremely impressive stuff. At this point, Microsoft had also reached maturity with their rewritten high-performance cross-platform open source web framework ASP.NET Core, and with WSL2 as mentioned they support running multiple Linux distributions as a subsystem in Windows. They are openly courting developers that ship software on Linux and want them to at least write code on Windows, even if they must host it on Linux in production. With WSL2 Microsoft are finally ready – docker running ostensibly natively on Windows.
Container Tools for Visual Studio
With the state of technology being as described above, naturally I want to get in on it. Writing my same old code but running it on cheaper Linux machines? Fantastic.
To do docker containers in .NET Core the Microsoft way, people have been using Docker Desktop which interoperates with Visual Studio through a plug-in called Container Tools which handles the creation, destruction, starting, stopping and debugging of containers.
I see that a preview version of Docker Desktop exists that uses docker installed in WSL2 as a back-end. I downloaded it and tried to install it but as it turns out – it cannot be installed on Windows 10 home edition due to platform incompatibility, making it unavailable to me. I play around with raw docker-compose, foregoing the visual studio plug-in, but resentment and ennui means I just end up doing something else.
Fast forward a few months ad Docker Desktop changed which Win32 APIs they used , replacing some exclusive to Win 10 Pro with more generally available ones, meaning from my perspective they fixed the problem – making Docker Desktop with experimental WSL2 backend available on Windows 10 Home. Hallelujah, praise the Lord, you’d think – the hard stuff is all done now, let’s go!!!
Enter Visual Studio Container Tools, a product that’s – as stated previously – a few years old that wraps the docker-compose, Kubernetes and docker CLIs among others in MSBUILD tasks and a Visual Studio extension.
Unlike with bash scripts or running docker-compose on the command line, where usually – pleasantly – error conditions leave information in context, thus aiding progress, similar docker configuration errors when discovered by Visual Studio tooling are expressed as compiler errors, exceptions thrown in the MSBUILD task itself with either no context, or misleading context. Why would anybody accept living like this? When they could get somewhat googleable error messages and at least a handful of people that have experienced this before if they just used the bare command line on a bare metal Linux machine.
As part of the logs I see that an address is already in use. Wat? Oh yeah, all Dockerfiles generated by the plug-in export ports 80 and 443, so all four websites in the solution try to host on the same ports. The generated docker-compose.yml has no port disambiguation. Surely a scenario with multiple sites wasn’t unexpected? How many ASP.NET Core solutions in real life has less than two websites? Heck, even toy apps should struggle under this limitation.
The point to this is – no engineering efforts are spared to do cool things “look! I’m running Linux natively in Windows” or “Look! This breakpoint is hit in the cloud.” but, in the daily struggle of delivering better code faster, very few of these gimmicks actually work, because of unnecessary simple things that could have been so much easier to fix than the almost literal rocket-science that went into those headline grabbing toy features.