My Docker for Windows Experience

docker-for-windows

Or “How I spent last weekend.”

Docker! More specifically, testing out the .NET Framework 4.7 image using Docker for Windows.

So first I had to enable Hyper-V. No problem, methinks. Riiight. After rebooting the computer, my multimonitor setup is totally trashed, thrashes, fubar’ed. As are my Fences icons. And there’s these extra monitors suddenly showing up. WTF?

Get that finally squared away, download the image (the instructions on the github repo are fubar’d) and launch VS2017.

Where is it? I get the VS2017 splash screen, then nothing. Elephant me, it looks like VS2017 & VS2015 are blown away. Uninstall both, reinstall both.

Same problem. Elephant.

Just by chance, I hit Alt-Tab and I see Visual Studio is one of the running applications. Where the Elephant is it??? So I think, maybe it’s on one of those weird extra monitors I saw. So I poke around, and there’s this “disconnect monitor” option in the display settings. So I try that for one of the “ghost” monitors. OMFG. Suddenly VS appears.

Next, I discover the BS that is Microsoft’s attempt at bringing .NET onto Docker. So there’s this image. OK. Docker tells me it’s downloading some 10 GIGA (yes, that’s GIGA) bytes of data for the image. OMG OMG OMG When all is said and done, my poor little 256GB SSD only has 1.4GB free (it was pretty stuffed already) but it turns out the whole Docker/Windows/.NET thing sucks up 17GB of disk space uncompressed. Well, at least the goofy demo Microsoft gives you compiled.

Oh, but I forgot to tell you, you need to switch to “Windows containers” in the Docker applet. Oh, and what I really forgot to tell you was the three install attempts for Docker for Windows because I had a previous “Docker Toolbox” installation (which I did uninstall before doing anything!!!) but that left various breadcrumbs – PATH entries (I had added those as they are necessary to work with the Docker VM), and a “.docker” folder in the Users\Marc folder. All of which caused Docker For Windows to be “No Docker For You”. Two separate SO posts resolved those issues.

So, we finally get to compiling. Fine. Then we get to running.

And We wait (at this point, it’s the royal WE)

And We Wait

await Marc;

And We Wait

And OMG it ran! There’s the output of the silly “bot” in the console window.

It takes something like 15-30 seconds on my 8 core 16GB fast machine to spin up the container, undoubtedly because I’m running a near full instance of Windows. I decide to try a few other things, all of which work, and finally landing on “let’s write a simple HttpListener” as a container. Great, 20 lines of code later and I have something that works in Windows. Let’s see if it works in the container.

Nope. Sesame Street time: One of these things (or most of these things) doesn’t belong: http://localhost, http://127.0.0.1, http://0.0.0.0, http://*

The last one, http://*:5001/ is what works. I go to my browser, to “localhost:5001” and…

nothing.

Hours later, I discover some interesting things. By now, after fussing with Dockerfile EXPORT and that http://*:5001, I discover that entering the container’s local IP into my browser works. But that’s container’s local IP, which changes every time the container is fired up, for each container that is fired up, all hail Mary to the container that never rules anything.

Various posts say you can’t access a container from the host. Some posts say you’re not using a container correctly if you’re doing this, you should use a VM instead (and indeed, I had a VM of this working with Python.) Some say other BS, but at the end of the day, they’re all saying BS, but I still can’t figure out the problem.

I make a post on the Docker forum. I refuse to give up. The oxygen tank is redlining, but I refuse to give up. And then I find it.

 Kymeric/DockerProxy: Proxy localhost for Docker Windows Containers

Indeed you can’t access the container through the host’s localhost unless you proxy localhost:port to [containerIP:port], and that’s what that little gem above does.

Sweet. Everest has been vanquished. No Elephants where harmed in this post.

At the end of the day though, Docker for Windows is an enormous footprint on your drive and painfully, actually unusable given how slow it is to fire up a container.  With round trip testing / debugging / code fixes, it’s not a viable solution, particularly when you’re figuring out the nuances of how to communicate bidirectionally and the code has to be tested in the container.

HOPE for the Web

hope-1

The above diagram is a high level view of what I’ve implemented with .NET Core 2.0 and Docker.  The idea is to take the work I’ve done with semantic types and allow users to create public or private repos of semantic types and microservices that operate on those types whenever they are “published” in the user’s environment.

With .NET Core 2.0, all the core pieces that I need (reflection, NewtonsoftJson, HttpListener, to name a few) are all fully usable with C# 7.  And while I’ll eventually return to supporting Python, it is a pleasure work with this concept in a strongly-typed language, as that’s a really key component to semantic processing (yes, of course it can be done in a dynamically-typed language with Python as well, as I’ve demonstrated in previous posts and an article.)

And the beauty of doing this with .NET Core is that it can run in a Linux container, which is so much faster than using Docker for Windows!

I’ll be posting more about the implementation details and writing some articles on Code Project on the subject.