How do I move my organization to Linux?

Brian Richardson
4 min readMay 6, 2021

I’m living the dream. My company is running Windows servers and our latest direction is that we want to replace our .NET applications on Windows server with .NET Core applications in Linux containers. This is well-known to be a solid platform for many reasons:

  1. Linux. Say what you will about Linux on the desktop, but Linux on the server is cheaper both in terms of licensing and in terms of core count.
  2. .NET Core. Again, say what you will about Microsoft, but .NET Core is a solid effort. The unified .NET 5 and successors are going to last a very long time, and multi-platform support is a fundamental part of .NET Core.
  3. Better Architecture. Identifying components for scaling and reuse is often poorly done. Designing for scale and isolation reduces coupling between components and allows for horizontal scaling of individual components.
  4. Serverless. Both AWS and Azure provide the ability to run a container instance directly, as well as Kubernetes services for orchestration. Moving from VMs to PaaS services such as these eliminate costly VMs and save maintenance effort.

OK, great. So what am I complaining about? Well, it’s just not that easy. First: this is not a crusade. It’s the bottom line that matters, and Linux will save money. I’ve merely passed the first hurdle in that management now sees things this way. But that doesn’t mean that Windows is verboten. If you want to shorten your lifespan considerably, install Linux desktops for the business users.

Realistically, you won’t install Linux desktops for anyone. Having worked a bit with both Linux and Windows development machines, Linux is still fraught with too many annoyances to get a good, productive development experience. As an aside, I’m partial to using WSL on Windows for development. So, be happy that the Windows servers are going away and concentrate on the benefits above.

So, here’s problem 1: your production and development environments have converged. The solution to this is, of course, Docker, but Docker is really an application for running Linux-based containers on Linux (Docker for Windows Windows-based containers notwithstanding). Docker for Windows solves this by using Hyper-V to install a Linux VM instance for executing Linux containers. This requires the installation of WSL 2.

Here’s problem 2: WSL 2 doesn’t run on all Azure VM families. For example, I have an NV-series development machine on Azure, and it doesn’t support WSL 2 because the required hardware virtualization features are not exposed in Azure for this VM family. Only Dv3 and Ev3 families support nested virtualization. This isn’t as bad as it seems. After all, Windows merely installs a lightweight Linux VM for use with Docker. So, we can simply build our own Docker VM on a Dv3. Setting DOCKER_HOST and DOCKER_TLS_VERIFY environment variables allow us to use Docker from the Windows command line seamlessly.

Problem 3 is the one we really want to avoid. Developers are perhaps some of the most particular people in the world, and big changes are often a source of friction. This is a big change. If not done correctly, too many people will have to learn Linux, and you will have to look for a new job. This is the maximum I’d want to have to teach developers:

  • How to build, deploy and debug Docker images
  • Some basic Linux commands

Most IDEs take care of the first part. Mostly. Dockerfiles and docker-compose are still concepts that need to be learned over a period of time. But getting people into the habit of pulling up their Linux terminal instead of the Windows one may take some effort. This is, with apologies, a “paradigm shift”. While developers still run on Windows, the application now targets Linux. We should start getting into the habit of using the Linux terminal and how to do things in Linux.

This new direction is something I’d been thinking about for a while. I’d put it on the back-burner as not convincing enough, but some recent case studies of larger deployments moving to .NET Core (the Microsoft move of the OAuth gateway to .NET Core showed a 50% reduction in compute costs!) finally moved the bottom line far enough that management got on board. So, now the plan looks something like this:

  1. Decompose the monolith. This is a subject of many articles and books. I won’t go into any detail on this.
  2. Migrate to .NET Core. Again, there’s plenty of documentation on how to do this. This is where you will discover all of your Windows-only dependencies and replace them with Linux-based equivalents.
  3. Build your Docker images according to the design developed in 1)
  4. Deploy applications to containers instead of VMs
  5. Delete VMs

So, we move to Linux by deleting Windows VMs! You won’t be installing any Linux application server VMs, so all you’re going to see is a reduction in server count. And all your PaaS services run on Linux. You’re saving money, improving your application, and supporting Open Source Software. Look at you go!

--

--