ASP.NET & Docker Experience

Introduction

Docker is system for creating and managing lightweight linux containers, which has become very popular in the enterprise computing business.

ASP .NET is a framework/platform from Microsoft, mainly used in building web applications. At the moment is on version 4.6.1 (stable) and version 5 is waiting around the corner. Version 5 is a completely re-done, its structure and mentality mimics the frameworks like Django, Flask or Express, which are small and provide you with basic functionality for web development. The rest is provided upon request by adding packages.

I have been experimenting with ASP.NET5 & Docker recently and so far I like it, and as expected it’s not a problem free solution. I have been using the following tools & frameworks: yeoman, ASP.NET 5, docker, VS Code and Docker Toolbox (with VirtualBox) on my Mac (most of which were installed through homebrew).

ASP.NET5

In case you haven’t heard yet, .NET embrassed a totally new approach/architecture, the new approach of .NET follows the path of almost everyone else out there making (web) frameworks. The new .NET contains only the core, which is the base for everything. The installation of course is quicker since you don’t download the old humangous framework, basically you download the runtime and then everything else are distributd as nugets. Even if you want to interact with the filesystem you need to download a new nuget, otherwise it does not work.

In general .NET is a very complete framework, you can find almost everything a web developer might need. Though, one of the features that was definitely missing from .NET was the ability to use it cross-platform. That’s not the case any more. You can run it on 3 more operating systems, apart from Windows, those are Linux, OSX and FreeBSD. It is apparent that it took them quite sometime to realize that they need this, but it’s never too late. I am working for a .NET shop (as we call our selves) and some people especially the ones working on the front-end are struggling with Windows including myself. The struggle is mainly Visual Studio’s stubborness to stop consuming all of the memory of a machine. So, a cross-platform .NET will free them (and me) from the crappy resource consuming Windows environment.

So, I decided to experiment with the new .NET, but I don’t want to run it in Windows, it’s obvious that in Windows everything will work normally (or close to normal). I was looking for problems, so I looked on a place where things can get fishy, .NET with Linux & Docker would be one since both environments are very new to .NET. It turned out that I encountered a few problems. Ok, to be fair my problems were not that big, but they can be very time-consuming and frustrating, especially if you are a newbie in Docker.

What Have I Done?

I used yeoman which is a scaffolding tool (someone calls it a wizard in ascii), which provides you with a way to bootstrap and scaffold your code. Basically, through templates it allows you to create files with code, similarly to what snippets do, but for whole files.

As a newbie in ASP.NET5 I took the easy way, thus I used ASP.NET Generator, which creates for you everything you need to start a basic web application with or without Docker. In fact everything is amazingly smooth, apart from 1 minor glitch.

BTW, this is command to create a project:

$ yo aspnet --gulp

Problem #1

Well, the problem lays in the combination of Kestrel, a new web server by Microsoft and Docker. Kestrel interfaces with the user like most servers I know, you just call it from CLI and (by default) it runs on localhost on a default port (in this case 5000) and that’s where the problem lays. In Docker if you run something on localhost, you just lost it, because localhost maps to 127.0.0.1 (yes the loopback address), one of the properies of this loopback address is that it is local to each host. So to fix that you need to modify your project.json file to look like this or you change the ENTRYPOINT in your Dockerfile.

"commands": {
    "web": "Microsoft.AspNet.Server.Kestrel --server.urls http://0.0.0.0:5000"
    },

OR

ENTRYPOINT ["dnx", "-p", "project.json", "Microsoft.AspNet.Server.Kestrel", "--server.urls", "http://0.0.0.0:5000"]

Basically, you need to make kestrel run on 0.0.0.0 otherwise you cannot connect to it.

Problem #2

As I mentioned before I was using my Mac and Docker does not work on the Mac directly, rather you can use Docker Toolbox. You can find the following tools in Docker Toolbox:

With these tools you create a VM that runs docker which in turn will run your applications. The interfacing is almost seamless so you don’t have to connect with the VM, you interface to Docker through your machine.

This comes with (at least) one problem, in my case port forwarding. So, I have created my app, I have fixed the issue with the interface mentioned before, but I could not connect to the app. I connected directly to the VM and I used curl everything worked just fine, I couldn’t understand why that was happening. Then I used nmap to see what ports are open on my host, it turned out that 5000 was not. Then I realized the problem and I solved by adding a rule in VirtualBox, to forward 5000 from my Mac to 5000 towards the VM. And that was it, my application was running like a charm as expected.

Virtual Box Port Forwarding

Conclusion

Clearly, Microsoft has acknowledged that their architecture is not optimal, that’s why they switched to a lightweight version of their huge product. Docker is an amazing tool, but it hinders a few sneaky problems like the ones mentioned. ASP.NET 5 generator is extremely helpful, but not perfect, despite that I suggest everyone to go with it, it helps a ton and speeds up development. BTW, the 1st problem mentioned is fixed by now. There was a PR on github, that fixed it (https://github.com/OmniSharp/generator-aspnet/pull/563).

References

NOTE: originally posted on medium https://medium.com/@ipinak/asp-net-docker-experience-bf92188bb07