TensorWorks Training Logo

CN001 - Containers and container orchestration

Activity 3: Building and running Windows containers


What you’ll need

To build and run Windows containers, you’ll need one of the following system configurations:

Pulling the appropriate base images for the host kernel

Unlike Linux container images, Windows container images must match the kernel version of the host system in order to function correctly. First, determine which version of Windows you are running:

docker info | findstr /C:"Operating System"

You should see a version string such as Windows 10 Pro Version 2009. The last component of the string (in this case, 2009) is the version number needed in order to determine the appropriate container images to pull. The table below lists the image tags for the different versions of each Windows base image (note that all tags are prefixed with mcr.microsoft.com/, but this prefix is omitted below for brevity):

Host OS Version Nano Server Tag Server Core Tag Full Windows Tag
1607 windows/nanoserver:sac2016 windows/servercore:ltsc2016 N/A
1709 windows/nanoserver:1709 windows/servercore:1709 N/A
1803 windows/nanoserver:1803 windows/servercore:1803 N/A
1809 windows/nanoserver:1809 windows/servercore:ltsc2019 windows:1809
1903 windows/nanoserver:1903 windows/servercore:1903 windows:1903
1909 windows/nanoserver:1909 windows/servercore:1909 windows:1909
2004 windows/nanoserver:2004 windows/servercore:2004 windows:2004
2009 windows/nanoserver:20H2 windows/servercore:20H2 windows:20H2

Pull the three base image variants for your host OS version. For example, under Windows 10 version 20H2 or Windows Server 20H2 you would run the following docker pull commands:

# Pull the base images for Windows version 2009 (also known as 20H2)
docker pull "mcr.microsoft.com/windows/nanoserver:20H2"
docker pull "mcr.microsoft.com/windows/servercore:20H2"
docker pull "mcr.microsoft.com/windows:20H2"

If you run the docker images command and take note of the sizes of each image then you will see that the Nano Server image is by far the smallest, the Server Core image is somewhat larger, and the full Windows image is extremely large.

Running the Windows base images

Start three different containers, each in a separate command prompt, using the appropriate image versions for your host OS. For example, under Windows 10 version 20H2 or Windows Server 20H2 you would run the following commands:

# Start containers using the base images for Windows version 2009 (also known as 20H2)
docker run --rm -ti --isolation=process "mcr.microsoft.com/windows/nanoserver:20H2" cmd
docker run --rm -ti --isolation=process "mcr.microsoft.com/windows/servercore:20H2" cmd
docker run --rm -ti --isolation=process "mcr.microsoft.com/windows:20H2" cmd

In the Nano Server container, you will need to use the Service Control tool to list the running services, since PowerShell is not included in recent versions of the Nano Server base image:

sc query

In the Server Core and full Windows containers, use PowerShell to list the running processes:

powershell Get-Service

You will see that the Server Core container includes more running system services than the Nano Server container, and the full Windows container includes even more running system services than the Server Core container. Combined with the number of bundled system DLL files, these varying sets of system services demonstrate how the three Windows base image variants each provide a different tradeoff between image size and legacy application compatibility.

Building and running a Windows image

Windows container images are written and built in much the same manner as Linux container images. Create a file called Dockerfile with the following contents (replace the base image tag in the FROM directive with the appropriate Server Core image tag for your host OS version):

# escape=`
FROM mcr.microsoft.com/windows/servercore:20H2

# This is not strictly necessary in this case, but harms nothing and helps avoid nasty surprises
SHELL ["cmd", "/S", "/C"]

# Create a new filesystem layer with an empty directory
RUN md C:\mydir

There are two things worth noting in this example Dockerfile:

Run the docker build command to build a container image from the Dockerfile:

# Build an image using the Dockerfile in the current directory and tag it as "windows-test:latest"
docker build --isolation=process -t "windows-test" .

Once the image has been built, use it to start a container:

# Start a container with an interactive command prompt
docker run --rm -ti --isolation=process "windows-test" cmd

If you run the dir command then you will see the list of directories under the root of the container’s filesystem, including the mydir directory that was created in the Dockerfile’s RUN directive.