Container Support Guide for Windows Server 2019

Tyler Maginnis | January 15, 2024

Windows Server 2019DockerContainersMicroservicesKubernetes

Need Professional Windows Server 2019?

Get expert assistance with your windows server 2019 implementation and management. Tyler on Tech Louisville provides priority support for Louisville businesses.

Same-day service available for Louisville area

Container Support Guide for Windows Server 2019

Overview

Windows Server 2019 provides native support for Windows containers and Docker, enabling lightweight application deployment and microservices architecture. This guide covers container installation, configuration, and management.

Container Types

Windows Server Containers

  • Process and user-mode isolation
  • Shared kernel with container host
  • Lightweight and fast startup
  • Suitable for trusted applications

Hyper-V Containers

  • Hardware-assisted isolation
  • Each container runs in its own VM
  • Enhanced security for untrusted workloads
  • Slightly higher resource overhead

Prerequisites

System Requirements

  • Windows Server 2019 (version 1809 or later)
  • 64-bit processor with virtualization support
  • 4 GB RAM minimum (8 GB recommended)
  • 20 GB available disk space
  • Internet connectivity for image downloads

Required Features

# Enable Hyper-V (for Hyper-V containers)
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All

# Enable Containers feature
Enable-WindowsOptionalFeature -Online -FeatureName Containers -All

Docker Installation

Install Docker Engine

Method 1: Using PowerShell

# Install Docker provider
Install-Module -Name DockerMsftProvider -Repository PSGallery -Force

# Install Docker package
Install-Package -Name docker -ProviderName DockerMsftProvider -Force

# Start Docker service
Start-Service Docker

# Configure Docker to start automatically
Set-Service -Name Docker -StartupType Automatic

Method 2: Manual Installation

# Download Docker binaries
$url = "https://download.docker.com/win/static/stable/x86_64/docker-20.10.7.zip"
Invoke-WebRequest -Uri $url -OutFile "C:\Docker.zip"

# Extract and install
Expand-Archive -Path "C:\Docker.zip" -DestinationPath "C:\Program Files"
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\Program Files\Docker", "Machine")

# Register Docker service
dockerd --register-service

# Start Docker service
Start-Service Docker

Configure Docker

Basic Configuration

# Create Docker daemon configuration
$config = @{
    "hosts" = @("tcp://0.0.0.0:2376", "npipe://");
    "tlsverify" = $true;
    "tlscert" = "C:\Docker\server-cert.pem";
    "tlskey" = "C:\Docker\server-key.pem";
    "tlscacert" = "C:\Docker\ca.pem"
}

# Save configuration
$config | ConvertTo-Json | Out-File -FilePath "C:\ProgramData\Docker\config\daemon.json" -Encoding UTF8

# Restart Docker service
Restart-Service Docker

Container Images

Base Images

Windows Server Core

# Pull Windows Server Core image
docker pull mcr.microsoft.com/windows/servercore:ltsc2019

# Verify image
docker images

Nano Server

# Pull Nano Server image
docker pull mcr.microsoft.com/windows/nanoserver:1809

# Check image size
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"

Create Custom Images

Dockerfile Example

# Use Windows Server Core as base
FROM mcr.microsoft.com/windows/servercore:ltsc2019

# Set working directory
WORKDIR /app

# Copy application files
COPY . .

# Install IIS
RUN dism /online /enable-feature /all /featurename:IIS-WebServerRole /NoRestart

# Expose port 80
EXPOSE 80

# Set entry point
ENTRYPOINT ["powershell", "-Command", "Start-Service W3SVC; while ($true) { Start-Sleep -Seconds 3600 }"]

Build Custom Image

# Build image from Dockerfile
docker build -t my-iis-app:latest .

# Tag image
docker tag my-iis-app:latest company/my-iis-app:v1.0

# Push to registry
docker push company/my-iis-app:v1.0

Container Management

Running Containers

Basic Container Operations

# Run container
docker run -d --name web-server -p 80:80 mcr.microsoft.com/windows/servercore/iis:latest

# List running containers
docker ps

# List all containers
docker ps -a

# Stop container
docker stop web-server

# Remove container
docker rm web-server

Container with Volume Mounting

# Run container with volume
docker run -d --name sql-server -p 1433:1433 -v C:\SQLData:C:\Data mcr.microsoft.com/mssql/server:2019-latest

# Mount read-only volume
docker run -d --name app -v C:\AppData:C:\Data:ro my-app:latest

Container Networking

Default Networks

# List networks
docker network ls

# Inspect network
docker network inspect bridge

Custom Networks

# Create custom network
docker network create --driver nat my-network

# Run container on custom network
docker run -d --name web --network my-network microsoft/iis:latest

# Connect container to network
docker network connect my-network existing-container

Storage Management

Container Storage

Volumes

# Create volume
docker volume create my-volume

# Use volume in container
docker run -d --name app -v my-volume:C:\Data my-app:latest

# List volumes
docker volume ls

# Inspect volume
docker volume inspect my-volume

Bind Mounts

# Bind mount host directory
docker run -d --name app -v C:\HostData:C:\ContainerData my-app:latest

# Read-only bind mount
docker run -d --name app -v C:\HostData:C:\ContainerData:ro my-app:latest

Storage Drivers

Configure Storage Driver

# Check current storage driver
docker info | Select-String "Storage Driver"

# Configure storage driver in daemon.json
$config = @{
    "storage-driver" = "windowsfilter";
    "storage-opts" = @(
        "size=120G"
    )
}

Security

Container Security

Security Best Practices

# Run container with limited privileges
docker run -d --name secure-app --security-opt no-new-privileges my-app:latest

# Use specific user
docker run -d --name app --user ContainerUser my-app:latest

Image Security

# Scan image for vulnerabilities
docker scan my-app:latest

# Sign images
docker trust sign my-app:latest

Hyper-V Isolation

Run Hyper-V Container

# Run with Hyper-V isolation
docker run -d --name secure-app --isolation=hyperv microsoft/nanoserver:latest

# Check isolation type
docker inspect secure-app | Select-String "IsolationTechnology"

Orchestration

Docker Compose

Install Docker Compose

# Download Docker Compose
$url = "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Windows-x86_64.exe"
Invoke-WebRequest -Uri $url -OutFile "C:\Program Files\Docker\docker-compose.exe"

# Add to PATH
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\Program Files\Docker", "Machine")

Docker Compose File

version: '3.8'

services:
  web:
    image: microsoft/iis:latest
    ports:
      - "80:80"
    networks:
      - app-network
    volumes:
      - web-data:/inetpub/wwwroot

  database:
    image: mcr.microsoft.com/mssql/server:2019-latest
    environment:
      - ACCEPT_EULA=Y
      - SA_PASSWORD=YourStrong!Passw0rd
    ports:
      - "1433:1433"
    networks:
      - app-network
    volumes:
      - db-data:/var/opt/mssql

networks:
  app-network:
    driver: nat

volumes:
  web-data:
  db-data:

Deploy with Compose

# Deploy application
docker-compose up -d

# Scale services
docker-compose scale web=3

# Stop application
docker-compose down

Kubernetes Support

Install Kubernetes

# Enable Kubernetes in Docker Desktop
# Or install kubectl
curl -LO "https://dl.k8s.io/release/v1.22.0/bin/windows/amd64/kubectl.exe"

# Create deployment
kubectl create deployment web-app --image=my-app:latest

# Expose service
kubectl expose deployment web-app --port=80 --type=LoadBalancer

Monitoring and Logging

Container Monitoring

Resource Usage

# Monitor container resources
docker stats

# Get container processes
docker top container-name

# Container logs
docker logs container-name

# Follow logs
docker logs -f container-name

Performance Monitoring

# Get container metrics
docker exec container-name powershell "Get-Process | Sort-Object CPU -Descending | Select-Object -First 10"

# Monitor system resources
Get-Counter "\Process(*)\% Processor Time" | Where-Object {$_.InstanceName -like "*docker*"}

Centralized Logging

Log Configuration

# Configure log driver
docker run -d --name app --log-driver json-file --log-opt max-size=10m --log-opt max-file=3 my-app:latest

# Send logs to event log
docker run -d --name app --log-driver etwlogs my-app:latest

Backup and Recovery

Container Backup

Create Container Image from Running Container

# Commit container to image
docker commit container-name backup-image:latest

# Export image
docker save -o backup-image.tar backup-image:latest

# Import image
docker load -i backup-image.tar

Volume Backup

# Backup volume
docker run --rm -v my-volume:/data -v C:\Backup:/backup alpine tar czf /backup/backup.tar.gz /data

# Restore volume
docker run --rm -v my-volume:/data -v C:\Backup:/backup alpine tar xzf /backup/backup.tar.gz -C /

Troubleshooting

Common Issues

Container Won't Start

# Check container logs
docker logs container-name

# Inspect container
docker inspect container-name

# Check system events
docker system events

Network Issues

# Test network connectivity
docker exec container-name ping google.com

# Check network configuration
docker network inspect bridge

# Restart Docker service
Restart-Service Docker

Performance Issues

# Check resource usage
docker stats --no-stream

# Monitor system resources
Get-Counter "\Process(dockerd)\% Processor Time"
Get-Counter "\Process(dockerd)\Working Set"

Diagnostic Tools

Docker Diagnostics

# System information
docker system info

# Check disk usage
docker system df

# Clean up unused resources
docker system prune -f

# Check Docker daemon logs
Get-EventLog -LogName Application -Source Docker

Best Practices

Development

  1. Use multi-stage builds
  2. Minimize image size
  3. Use specific image tags
  4. Implement health checks
  5. Follow security best practices

Production

  1. Use orchestration platforms
  2. Implement monitoring and logging
  3. Regular security updates
  4. Backup strategies
  5. Resource limits and quotas

Performance

  1. Optimize Dockerfile layers
  2. Use appropriate base images
  3. Configure resource limits
  4. Monitor container performance
  5. Regular maintenance

Advanced Topics

Windows Container Networking

Advanced Network Configuration

# Create overlay network
docker network create --driver overlay --subnet=192.168.1.0/24 my-overlay

# Configure NAT
docker network create --driver nat --subnet=172.16.0.0/16 my-nat-network

Container Registry

Set Up Private Registry

# Run registry container
docker run -d -p 5000:5000 --name registry registry:2

# Push to private registry
docker tag my-app:latest localhost:5000/my-app:latest
docker push localhost:5000/my-app:latest

CI/CD Integration

Jenkins Pipeline

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                bat 'docker build -t my-app:latest .'
            }
        }
        stage('Test') {
            steps {
                bat 'docker run --rm my-app:latest powershell -Command "Invoke-Pester"'
            }
        }
        stage('Deploy') {
            steps {
                bat 'docker run -d --name prod-app my-app:latest'
            }
        }
    }
}

Conclusion

Windows Server 2019 provides comprehensive container support, enabling modern application deployment and microservices architecture. Proper configuration and management ensure optimal performance and security for containerized workloads.

Next Steps

  • Implement container orchestration
  • Set up monitoring and alerting
  • Configure CI/CD pipelines
  • Explore advanced networking options