Activity 3: Building and running Windows containers
Contents
- What you’ll need
- Pulling the appropriate base images for the host kernel
- Running the Windows base images
- Building and running a Windows image
What you’ll need
To build and run Windows containers, you’ll need one of the following system configurations:
-
A 64-bit version of Windows 10 Pro/Enterprise/Education (Version 1607 or newer) with Docker Desktop for Windows installed and configured to use Windows containers
-
Windows Server 2016 or newer with Docker Enterprise Edition (EE) for Windows Server installed
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:
-
The first comment line instructs Docker to treat the backtick character as the escape character for the Dockerfile, instead of the default backslash character. This is necessary to ensure that Windows paths with backslashes in them are treated correctly and not misinterpreted as containing unintended escape sequences.
-
The
SHELL
directive specifies the shell that is used to evaluate commands inRUN
directives. A number of base images provided by Microsoft (such as those for .NET Core and the .NET Framework) set PowerShell as the default shell, so this line is necessary if you wish to use the Windows command prompt as the default shell when extending those base images. Explicitly including this directive in your Dockerfiles for Windows container images is a helpful practice because it prevents breakages arising from changes in the shell used by upstream base images.
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.