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
- Use multi-stage builds
- Minimize image size
- Use specific image tags
- Implement health checks
- Follow security best practices
Production
- Use orchestration platforms
- Implement monitoring and logging
- Regular security updates
- Backup strategies
- Resource limits and quotas
Performance
- Optimize Dockerfile layers
- Use appropriate base images
- Configure resource limits
- Monitor container performance
- 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