How to Configure Windows Server 2019 Windows Containers

Windows Containers are a lightweight virtualization technology in Windows Server 2019 that package applications and their dependencies into isolated units. Unlike Hyper-V containers, Windows containers share the host OS kernel, making them faster to start and more resource-efficient. They are fully compatible with Docker tooling and can run Windows Server Core or Nano Server base images. This guide covers the complete configuration of Windows containers on Windows Server 2019, from installation through management and networking.

Installing the Containers Feature

The first step is enabling the Windows Containers feature on the host. This installs the container runtime and the Host Networking Service:

Install-WindowsFeature -Name Containers -IncludeManagementTools -Restart

After the server restarts, install Docker Engine:

Install-Module -Name DockerMsftProvider -Repository PSGallery -Force
Install-Package -Name docker -ProviderName DockerMsftProvider -Force
Restart-Computer -Force

Verify Docker is running after the restart:

Get-Service docker
docker version
docker info

Pulling Windows Container Base Images

Windows Server 2019 containers require base images from the Microsoft Container Registry. The available base images range from full Windows Server Core to minimal Nano Server:

docker pull mcr.microsoft.com/windows/servercore:ltsc2019
docker pull mcr.microsoft.com/windows/nanoserver:1809
docker pull mcr.microsoft.com/windows/server:ltsc2019

Verify the pulled images:

docker images

Running Your First Windows Container

Run an interactive Windows Server Core container to test the environment:

docker run -it --rm mcr.microsoft.com/windows/servercore:ltsc2019 cmd

Inside the container, verify isolation and check the system:

hostname
systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
ipconfig
whoami

Run a container in detached mode with port mapping:

docker run -d -p 8080:80 --name webtest mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019

Creating a Dockerfile for a Windows Container

Build custom Windows container images using a Dockerfile. Create a Dockerfile for an ASP.NET application running on Windows Server Core with IIS:

FROM mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019

LABEL maintainer="[email protected]"

# Enable ASP.NET 4.8
RUN powershell -NoProfile -Command 
    Add-WindowsFeature Web-Asp-Net45; 
    Remove-Item -Recurse C:inetpubwwwroot*

# Copy application files
COPY ./app/ C:/inetpub/wwwroot/

# Set app pool to run as NetworkService
RUN powershell -NoProfile -Command 
    Set-WebConfigurationProperty -filter '/system.applicationHost/applicationPools/add[@name="DefaultAppPool"]' 
    -name processModel.userName -value "NetworkService"

EXPOSE 80
CMD ["ping", "-t", "localhost"]

Build the image from the Dockerfile:

docker build -t contoso/webapp:v1 -f Dockerfile .

Configuring Container Resource Limits

Windows containers support CPU and memory limits to prevent resource starvation. Set resource limits when running a container:

docker run -d `
    --name constrained_app `
    --cpus 2 `
    --memory 2g `
    --memory-swap 4g `
    --restart unless-stopped `
    contoso/webapp:v1

Update resource limits on a running container:

docker update --cpus 4 --memory 4g constrained_app

Persistent Storage for Windows Containers

Mount host directories or named volumes for persistent data. Create and use a named volume:

docker volume create AppData

docker run -d `
    --name appserver `
    -v AppData:C:/AppData `
    -v C:Logs:C:ContainerLogs `
    contoso/webapp:v1

Inspect the volume:

docker volume inspect AppData

Managing Windows Containers with Docker Compose

Install Docker Compose on Windows Server 2019:

Invoke-WebRequest -UseBasicParsing -Uri "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-windows-x86_64.exe" -OutFile "C:Program Filesdockerdocker-compose.exe"

Create a docker-compose.yml for a multi-container application:

version: '3.8'
services:
  web:
    image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019
    ports:
      - "80:80"
    networks:
      - appnet
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 2G
  sql:
    image: mcr.microsoft.com/mssql/server:2019-latest
    environment:
      - ACCEPT_EULA=Y
      - SA_PASSWORD=Str0ng!Pass
    volumes:
      - sqldata:C:/var/opt/mssql
    networks:
      - appnet
networks:
  appnet:
    driver: nat
volumes:
  sqldata:

Deploy the stack:

docker-compose -f docker-compose.yml up -d

Monitoring and Troubleshooting Containers

View running containers and their resource usage:

docker ps -a --format "table {{.ID}}t{{.Names}}t{{.Status}}t{{.Ports}}"
docker stats --no-stream

Access container logs:

docker logs --tail 100 --timestamps appserver

Execute commands inside a running container for debugging:

docker exec -it appserver powershell
docker exec appserver cmd /c "netstat -ano | findstr LISTENING"

Review Docker and container events for errors:

docker events --filter type=container --since 2h

Windows containers on Windows Server 2019 provide a powerful, production-ready containerization platform for Windows applications. By using appropriate base images (preferring Nano Server for smaller attack surface and faster pulls), applying resource limits, and using volumes for persistent data, you can deploy and manage containerized Windows applications reliably and efficiently.