For the past couple of years, businesses on the bleeding edge of technology have changed the way they build and deploy applications using Linux-based containers and they’ve used containers to provide an isolated and portable operating environment that works consistently and repeatedly when deployed in development, staging, or in production. And now with the release of Windows Server 2016, we have native support for Windows-based containers and Microsoft shops can now start to enjoy the benefits of containerized applications as well.

We’ll start off with an introduction to container technology and move on to deploying containers on Windows Server, so you’ll learn how to set up a Windows Server 2016 container host running Docker and much more.


Understand Containers



Looking back 15-20 years ago, organizations typically deployed individual physical servers for each application that they needed to support and sometimes they’d install several applications on one machine, but for the sake of stability, it was a pretty common model to have physical servers dedicated to one application. So in that type of a scenario you can imagine that it would take a long time to get new servers installed, when the time came to deploy a new server the IT team would need to procure a new hardware, and that often would take at least a couple of weeks, and then the server would come in, they need to get it racked and cabled up to the network, then an operating system needed to be installed, and you get the idea. The ability for the organization to move quickly was really impacted by this process and don’t forget about unused capacity and a waste of physical resources.


So as technology advanced, virtualization technology like Hyper-V made it really easy to deploy virtual machines, businesses were suddenly able to increase their agility and move a little bit quicker, and oftentimes this also helped with making more efficient use of the hardware available. But there are a few things about running virtual machines that aren’t as efficient as they could be. So for example, every virtual machine has a full copy of an operating system and that means potentially licensing those servers and then we’ve got to do patching and maintenance, and on top of all of that virtual machine disk files are usually pretty large in a Windows world, so they’re hard to move around between environments, they’re slow to boot up, and then of course they need a lot of memory and possibly CPU.


Because of that, many businesses have turned to container technology to bypass those limitations. So you can kind of think about containers as the evolution of virtual machines. The big difference is that containers don’t need a completely dedicated operating system, they actually share the operating system kernel on the host that they’re running on. So this frees up a ton of resources and it also eliminates the need to license and patch multiple operating systems. Another great benefit is that containers boot almost instantly, they’re a lot smaller in size as well, and that makes them a lot more portable. So this portability is one of the biggest reasons that containers have gained so much popularity. Developers can build and test apps locally in containers on their laptop, and then they can easily run those same containers on physical servers, virtual machines, or in the cloud without any kind of modification.


What is DOCKER? 


Docker is open source platform to build, ship and run distributed applications. The container technology is not really new, it’s actually been built into Linux for years, and now Microsoft has introduced native support for containers in Windows Server 2016 and in Windows 10 with the anniversary update and to interface with these containers running on Linux or Windows, we can use software from Docker. Developers and administrators or operations engineers can use the same tools and technologies available from Docker, regardless of whether they’re working with containers on Linux or on Windows Server.

Let’s take a look at image bellow and see the difference between VMs and Containers.  Notice on the diagram on the left we have virtual machines running on top of a hypervisor like Hyper-V. Now on the right, you can see that the difference here is that instead of a hypervisor, we have something called a DOCKER ENGINE. So this Docker engine is what runs on either Linux or Windows, and it’s the software that does all the heavy lifting of creating and running containers. Now looking at these two diagrams there’s a key difference here. You can see that on the right-hand side, the containers don’t have a full copy of an operating system, and again that’s because they share the operating system kernel on the container host and for us as Windows administrators, what that means is when the Docker Engine is running on Windows Server 2016 we can only run containers that share the OS kernel of Windows, so in my case that’s going to be Windows Server 2016 with GUI but you can use Nano or Core server. I will show you how to run this on Nano server as well.


So our next question may be, how can we install docker and run it in Windows?

This could be a little bit confusing when you’re first starting out because you can see a bunch of different options on the Get Docker Menu page on their website. If you browse to and click on Get Docker you will see a lot of options there and you will see For Desktops (Windows) and For servers (Windows Server). Now the difference between these two is that one is for development and one is for production. Docker for Windows, this actually runs on Windows 10, and this is where developers would run containers in the development environment.

I am not going to be dealing with Docker for Windows, running the development version on a Windows 10 machine, we’re going to be focused on Windows Server version of Docker, so that is going to be Docker running on Windows Server 2016, and we’re really looking at this from the perspective of administrators wanting to set up and manage containers on Windows Server for production purposes.



Container Concepts

So to run our containers we need a host machine, and in my case that’s going to be a Windows Server 2016 (GUI) machine, and this can be a physical or a virtual machine and it needs to have the native containers Windows feature installed on the system. But keep in mind that this machine would be referred to as your container host, and on your container host you’ll need to install the Docker Engine. You’ll hear this referred to as the Docker Daemon, but essentially what it means is that you’re running the Docker Engine as a service on this container host, and it’s the component that you’ll interface with to create and launch your containers. Once you have that containers feature and the Docker Engine installed on the container host, then you can start spinning up containers.

In order to manage the containers on the container host we’ll need to use the Docker Client, and this is basically just a command-line tool that we use to issue commands.

Container Image

Another key concept that we’ll be working with a lot is container images, and if you’ve ever created a virtual machine template or a golden image for your servers, this is a similar idea. Containers basically start with a striped down base operating system image.

Container Registry

In terms of transporting these images around, the process is fairly straightforward, so the idea is that you’re going to package up your application into a container image and then you’re going to push that image into something called a Container Registry. Now when it comes to Container Registries you can build your own, or you can use a cloud-based provider, Docker actually has a default registry called the Docker Hub that we’ll work with. But the idea here is that you can create your own images, you can share them with multiple container hosts so those container hosts can run those images to create containers, and inside the Container Registry you’re going to have a repository that’ll store your images. So you can use the Docker Client to push your images, those custom images that you built, up into the repository, and then from another system you can actually use the Docker Client to pull the image down and then you can start a container using that image somewhere else.

When it comes to the terminology here, an important concept to keep in mind is that registries are made up of multiple repositories, these repositories of course are where we store our images.



Now the last thing I want to mention here is that we actually have two separate container types available on the Windows platform. So everything that we’ve talked about so far is the typical model where the container shares the operating system kernel on the container host, but we also have this concept of Hyper-V containers. So in Hyper-V type the container host actually has the Hyper-V role installed, and when we start up these type of containers they’re transparently started inside Hyper-V virtual machines.

I will show you later how to set up container hosts to support Hyper-V containers.



When I show you the steps to deploy Docker on Windows Server 2016 with a desktop, it’ll pretty much be the same exact steps that you’ll run on Windows Server Core, and then there’s a few small things that’ll be a little bit different about Nano Sever, and I’ll show you how to deploy a container host on Nano Server as well.  But from a Windows Server perspective there’s really one main requirement, and that’s the brand new Containers feature, and that provides the native container support within Windows Server 2016.

(Just to point that this feature will be installed automatically when you install docker package so no need to install this in advance).


To install Docker for Windows Server 2016 we don’t actually download anything from the Docker website, the current process for deploying Server 2016 container hosts is to use PowerShell.

This is really just a way for you to use PowerShell to search for packages in software repositories, and then you can also use PowerShell to install packages from those repositories. So in this case we’ll need to install the Docker Microsoft provider from the PowerShell gallery, and then we can install the Docker package, which will include the Docker Engine as well as the Docker Client.

Let’s see how we can install it.

One of the first things that you’re going to want to do is make sure that your system’s completely up to date. When that is done open Powershell as admin and type in

Install-Module -Name DockerMsftProvider -Repository PSGallery -Force

At this point we need to install a NuGet provider so we can install the packages, so I’ll just go ahead and say yes to this, I’ll type in Y and hit Enter and now that that’s installed, we can install the Docker package.


Now we need to run another command to install package.  Now really all this is doing is downloading a zip archive that has the Docker daemon, or the Docker Engine, as well as the Docker Client in it, and what I’m going to do is tack on verbose parameter so we can actually see what this thing is doing along the way.

Install-Package -Name docker -ProviderName DockerMsftProvider -verbose

And then we get a prompt down at the bottom saying that the package source is not marked as trusted, so I’m just going to type in A so we say Yes to All, but if you look at this verbose output here you can see that it’s downloading a JSON document from Microsoft, and that JSON document actually has a link to an archive that contains the Docker Engine and the Docker Client.


You can see one of the first things it’s doing is it’s installing the Containers feature on Windows. So it’s actually calling the Install-WindowsFeature cmdlet to install that prerequisite server feature…

When that is done we need to restart the computer and be sure that docker service is running.

Run Restart-Computer -Force


When reboot is completed, open powershell as admin and type in

Get-Service Docker

(If you notice that service is not running you can start it by running Start-Service docker)


Docker version command is showing us the version for the Docker Client, as well as the Docker Engine or the Server as it’s listed below. So for both the Docker Client and the Docker Engine we’re running version 17.03, and the fact that I’m actually getting this output here means that we’re successfully communicating with the Docker Engine from the Docker Client. So at this point we’ve successfully deployed a container host on Windows Server 2016.




Since the Nano Server has very limited interactive capabilities, we’re going to do most of the work remotely. I will run this on my Nano server (Nano-HV01)

(Be sure that your Nano server is up to date)

So just like we did on Windows Server with a GUI, we’re going to install that Docker Microsoft provider

Install-Module -Name DockerMsftProvider -Repository PSGallery -Force


Next we need to install package

Install-Package -Name docker -ProviderName DockerMsftProvider

Restart the Nano server and check if the service is running.



Configure the startup options for the Docker Engine.

Docker Engine is powered by a process called dockerd (it stands for Docker Deamon) and it is the service that powers out ability to interface with docker using the Docker Client. If you browse to  page you will find a lot of start up options that you can customize when starting the service. You can do this as you run the process manually, or you can set this in a configuration file.



So for example you may want to connect to the Docker Engine remotely, you may want to configure which IP address and which port that engine is going to listen on, so that’s one way where you can go in and customize the settings. This is pretty wide topic so you will need to spend some time testing this.

If you click on the option that says Windows configuration file, on the right-hand side you can set some of these options in a json document.


Json document doesn’t exist by default but you can create it, notice that the default location will go into a program data, so typically that’s going to be %programdata%\docker\config\daemon.json


So you could create this daemon.json file and put whatever items in there that you want to add to customize the behavior of the Docker Engine when it starts up. I have Nano server and this is something you have to do if you have Nano server and to be able to connect to the docker engine remotely from a docker client I will need to configure the docker engine to listen on a certain IP and port number.


So let’s login to Nano server and configure this. First I will open up a hole in the firewall to allow incoming connections on TCP port 2375

netsh advfirewall firewall add rule name=”Docker daemon” dir=in action=allow protocol=TCP localport=2375


Next thing we need to do is to create daemon.json file.

New-Item -ItemType file C:\ProgramData\docker\config\daemon.json


Now with daemon.json file created I need to add that host key into the file, and basically the json is going to look like this.

Add-Content ‘c:\ProgramData\docker\config\daemon.json’ ‘{ “hosts”: [“tcp://”, “npipe://”] }’


Last step is to restart docker service

Restart-Service Docker

At this point we can connect to the Docker Engine from a Docker Client. To avoid very long posts we will continue in the next part.

Thanks for reading!