Docker & .Net 4.8: An Endless Obstacle Course

The more complex an application becomes, the greater is the benefit of Docker. If everything runs in containers, we can use a tool like docker-compose and start all the parts with one single command. No need to install all the tools, services, and frameworks – just run docker-compose and the magic happens automatically. We can go from nothing to the full running application in a few minutes.

Since I saw the talk “Dev and Test Agility for your Database with Docker” by Julie Lerman at NDC Oslo 2019 I wanted to port her solution for .Net Core to the .Net Full Framework. How hard could it be? As it turns out, it is an awful lot of work and a few weeks ago Microsoft made it even harder.

 

The goal

.Net Full Framework is now a legacy technology. All the development happens in .Net 6+ and for the foreseeable future there is no simple way to move your 4.8 application to .Net 5 / .Net 6. In other words: .Net 4.8 will still be around when everyone wants to work with .Net 6+.

My idea is that we need a bridging technology to make maintaining .Net 4.8 applications as effortless as possible. I imagine a workflow in which we get a running application with these 3 commands:

Docker-compose starts our SQL Server with our database, runs a command line application to update the database structure, then starts our web application and runs all our tests (unit-, integration-, and end to end tests). This setup with 4 containers works for most of our applications:

The 4 containers to manage a web application.

No need to install SQL Server, IIS, or Visual Studio. VS Code or the editor of your choice is all you need. Docker and its multi-stage builds compile the application and enforce the coding guidelines (for example with StyleCop). If the change works, a git commit and a git push triggers the build pipeline on Azure and deploys the application to the test system.

Since everything runs in containers, we could make another change, run docker-compose again and get the same clean starting point to run our tests. No need to clean-up the database or to create an elaborate test-setup.

I cannot imagine an even simpler workflow than those 3 commands to get the whole infrastructure for an application up and running.

 

The obstacles: Windows containers

.Net 4.8 only runs on Windows. Unfortunately, Docker on Windows is not the same as Docker on Linux and Docker on Windows with Windows containers is yet another beast. Things that are well-documented for Linux may work differently on Windows or not at all. It is easy to waste hours on things that need an undocumented twist on Windows. You find some of the annoying differences in these posts:

As you can see, even the most basic parts often need extra care. Sadly, there is more bad news.

 

End of SQL Server on Windows containers

In July 2021 Amit Khandelwal posted a short note about the suspension of the beta program for SQL Server on Windows containers. Not only will there be no production-ready SQL Server for Windows containers, but they are also going to remove the existing images:

[…] Hence with immediate effect, the docker hub repos “microsoft/mssql-server-windows-express” and “microsoft/mssql-server-windows-developer” and the tags within these repos will be deleted and images from these repos will not be available for download going forward. […]

I only want to run SQL Server for testing and development purposes in a Windows container. Therefore, the first part of the announcement is not a big deal. However, if we can no longer download the existing images, we have a big problem.

 

Options

The end of pre-created SQL Server images is yet another major setback. Our options are now as follows:

  1. Create our own SQL Server images. We need to figure out the how and if we are allowed to. And we need to host those images somewhere and restrict access to our developers.
  2. We skip the SQL Server container and install it directly on the developer machine. Instead of Docker giving us a clean database when we run our tests, we need to change our testing strategy and clean-up the database somehow.
  3. We postpone Docker until we use .Net 5+ and then run all on Linux containers (maybe on a Windows host).

Option 1 brings a lot of additional work that someone in the team must do. We want to develop software and not maintain container images. It is doable, but is there any chance that we get the invested time back? I do not think so.

Option 2 only saves us the installation of the .Net SDK and maybe Visual Studio. However, it adds the whole complexity of Docker but next to none of the benefits. Again, doable but not advisable.

Option 3 means no improvement to the current situation for the time being. On the other hand, we do not add any complexity and can focus on the migration to .Net 5 / .Net 6.

For me, the best way forward is to keep the goal in mind but wait with Docker until our applications run on .Net 5 or .Net 6. On that platform we can use Julie’s examples and get it up and running within an hour. Should we run into a problem we can use the first result on Google and fix it without wasting time on the differences between Linux and Windows containers. Option 3 it is.

 

Conclusion

The end of pre-build SQL Server Windows container images is for me the final nail in the coffin for .Net 4.8 and Docker. Yet another setback, yet another extra mile we need to go to get something working that runs out of the box on Linux containers. I have enough. I cut my losses and focus on Linux containers. If you want to work with Docker, I advise you to do the same.

Instead of a blog series on Docker and .Net 4.8 I will write a few posts on development containers for Ruby and Python. That way I can salvage at least a few things I learned over the last two years…

2 thoughts on “Docker & .Net 4.8: An Endless Obstacle Course”

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.