Over the last few years I’ve slowly made the transition from “docker detractor” through “docker accepter” all the way to “docker enthusiast” where I am now. Docker isn’t the only container tool out there, but it’s certainly one of the most popular. It gives a spin on application management and deployment that’s honestly pretty refreshing.
At the same time, I’ve been a windows enthusiast my whole life. I’m not opposed to Ubuntu, RHEL, or OSX, and I’m not a stranger to grep, find, and ls, but I’ll defend the use of Windows Server, “where-object” and “get-childitem” any day.
The Docker experience on windows has evolved a ton in the last few years. If you haven’t downloaded Docker Desktop, I would highly recommend grabbing it and playing around (even just to win a game of “have you tried?” at work).
In this post I’ll walk through some of my surprises (pleasant and unpleasant) with using Docker on windows for the last few years.
Volume Mapping is useful, but little tricky
If you didn’t know docker lets you mount directories from your host OS into your container with the docker run –volume option
This works between windows and linux containers, and windows and windows containers, and can be really useful for running linux utilities to modify files on your windows machine, like using a current version of openssl to update certificates
What’s weird about it?
Anytime you’re moving files between windows and linux, you’re going to encounter some weirdness. Things at the top of the list are
- Files created on your windows machine show up in linux with “-rwxr-xr-x”. This can be a little confusing if you author a bash script on your laptop, then submit the Dockerfile to a build tool like CircleCI, and realize it doesn’t have execute permissions
- Default line endings will drive you crazy
- Support for specify the path on your host is different in Docker and docker-compose
- Docker supports relative pathing, because you can execute “(pwd).path” inside of the string you pass to -v
- Docker-compose supports relative pathing inside of your workspace with the normal “./”
Alpine will make you hate Windows Server Core
Alpine containers are delightfully tiny. Think of them like cheese burger sliders, or mini bagels, or minimuffins (you get the picture). The base alpine container is single digit MB (that’s not an exaggeration). Obviously as you add packages and tools to it, it starts to grow, but that’s a great starting point.
Compare that to Windows Server Core that starts off at just over 5 GB. And that only grows when you start adding packages and tools. By the time we have a working windows container it’s often in the tens of GB.
Partly because of the size windows server core containers take a long time to run some basic operations, like extracting, starting, and stopping. It can be frustrating compared to Alpine that can be completely downloaded and up and going in a matter of seconds.
Windows Server Nano is better
Microsoft Nano server is a smaller version of Windows Server and starts off at just under 400 MB which makes it smaller, but that shrinking comes with some caveats like it only runs .NET core and not full .NET.
That makes the case for Nano Server a little more obscure. If you’re committed to some specific windows features in .NET core that aren’t available in linux, it makes sense. But most of .NET core runs on linux now, so think about migrating to linux.
Microsoft’s Image Tagging and Versioning Confuses Me
While I was writing this post, I tried 3 or 4 different image tags from docker hub before I found the right combination of architecture and OS version that would work on my laptop.
Understanding that error comes down to understanding what docker does at it’s core. It is not a virtualization tool, your containers share your host kernel, so you obviously need to have a kernel that’s compatible with the image you’re trying to run. It can still be frustrating to get the first container running.
I’ve also spent a lot of time trying to find the right image repo on docker hub. Searching some terms that seem logical to me like “windows” or “windows 2019” don’t always return the images you’d expect. I haven’t found a good central listing of “all the windows containers from microsoft”.
Docker Desktop’s Moby Linux VM is smooth
When you run a linux container on windows Docker Desktop is using Microsoft HyperV behind the scenes to create a small VM you can use to run linux containers.
The first time I found that out, it gave me some heart palpitations. “A container inside of a VM running on my windows laptop? The resource drain will be astronomical! The performance will be subterranean! The compatibility will be atrocious!”
But after a few weeks of using it, I calmed down quite a bit. We’ve been running docker in production at work for a close to 2 years, and I have yet to see any compatibility issues pulling and running containers onto my laptop. Most of the development happens on OSX or actual linux machines, but the Moby VM works quite well.
This is going to change with the Windows Subsystem for linux 2, and I think that’s the right move. Microsoft is making Linux tooling and development first class citizens on Windows. But the linux VM running inside of HyperV is stable enough I won’t be an early adopter.
Networking is cool and a little confusing
It’s pretty straightforward to expose a port on the container to your host
And that works really smoothly, especially on Windows containers.
On linux containers the VM running your container is technically behind a HyperV switch, so some docker networking modes like “host” and “bridged” don’t work like you’d expect them to. This is fine if you’re running a single container, but when you want to create a group of containers with docker-compose you have to take it into consideration.
My recommendation is to keep things simple and use docker-compose as it was meant to. That is, let docker-compose manage the DNS and networking behind the scenes, and expose as few ports into your container services as you can.
Editing text files in windows containers is really hard, apparently?
If you’ve spent any time in linux you’re probably competent with at least one command line text editor (nano, vi, etc). But apparently none of those are readily available in most versions of windows containers. Searching the internet for “editing text files in powershell” leads me to a bunch of articles about using “set-content” or using powershell to open notepad.
Those approaches have their uses, but what if I just want to edit a config file in a windows container? Apparently my only option is to write a regex, or map the volume to my host. Weird.