How to Set Up Windows Server 2016 Docker

Docker on Windows Server 2016 gives administrators and developers a production-grade container runtime directly on a Windows host without needing a Linux VM intermediary. Windows Server 2016 was the first Windows release to support Docker Engine natively, and Microsoft ships an official DockerMsftProvider PowerShell module that simplifies installation and management. This guide covers a complete Docker setup on Windows Server 2016, including installation, TLS-secured daemon configuration, registry authentication, image management, volume and network configuration, and best practices for production deployments.

Prerequisites

You need a machine running Windows Server 2016 Standard or Datacenter (full GUI or Server Core), at least 4 GB of RAM, 20 GB of free disk space, and outbound internet access on port 443 for pulling images and the installation package. All commands must be run in an elevated PowerShell session. Ensure Windows is fully patched before starting to avoid known Docker compatibility issues with older builds.

Step 1: Install the Containers Feature

The Containers Windows feature is a prerequisite for Docker on Windows Server 2016. Install it and allow the server to restart.

Install-WindowsFeature -Name Containers -Restart

Step 2: Install Docker Engine via PowerShell Gallery

After the restart, install the DockerMsftProvider package provider and then install Docker. Specifying RequiredVersion 17.06 installs the version validated for Windows Server 2016. Newer releases such as 19.03 or later Engine EE builds are also supported but require checking compatibility with your specific build.

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

Restart-Computer -Force

Step 3: Start Docker and Verify Installation

After the second restart, start the Docker service, set it to automatic startup, and verify both the client and daemon are operational.

Start-Service Docker
Set-Service Docker -StartupType Automatic
docker version
docker info

The docker info command provides details about the daemon configuration including storage driver, number of containers, images, and the OS/architecture. Confirm that OSType shows windows and Architecture shows x86_64.

Step 4: Configure the Docker Daemon

The Docker daemon is configured through the daemon.json file located in C:ProgramDataDockerconfig. Create or edit this file to set options such as the data root directory, log driver, and DNS servers.

$daemonConfig = @{
    "data-root" = "D:\DockerData"
    "log-driver" = "json-file"
    "log-opts" = @{ "max-size" = "10m"; "max-file" = "3" }
    "dns" = @("192.168.1.10", "8.8.8.8")
    "storage-opts" = @("size=20G")
} | ConvertTo-Json -Depth 5

$daemonConfig | Set-Content -Path 'C:ProgramDataDockerconfigdaemon.json' -Encoding UTF8
Restart-Service Docker

Step 5: Enable TLS for the Docker Remote API

To securely manage Docker from a remote machine, enable TLS on the Docker daemon. Generate a CA, server certificate, and client certificate using OpenSSL or the certreq tool, then reference them in daemon.json.

$daemonConfig = @{
    "hosts"   = @("tcp://0.0.0.0:2376", "npipe://")
    "tlsverify" = $true
    "tlscacert" = "C:\certs\ca.pem"
    "tlscert"   = "C:\certs\server-cert.pem"
    "tlskey"    = "C:\certs\server-key.pem"
} | ConvertTo-Json

$daemonConfig | Set-Content -Path 'C:ProgramDataDockerconfigdaemon.json' -Encoding UTF8
Restart-Service Docker

Open the Docker TLS port in the Windows Firewall.

New-NetFirewallRule -DisplayName 'Docker TLS' -Direction Inbound `
    -Protocol TCP -LocalPort 2376 -Action Allow

Step 6: Pull and Manage Images

Pull the official Windows Server Core and Nano Server base images from the Microsoft Container Registry. Always match the image version to the host OS build to avoid compatibility errors.

docker pull mcr.microsoft.com/windows/servercore:ltsc2016
docker pull mcr.microsoft.com/windows/nanoserver:sac2016

# List local images
docker images

# Remove an image
docker rmi mcr.microsoft.com/windows/nanoserver:sac2016

# Inspect an image
docker inspect mcr.microsoft.com/windows/servercore:ltsc2016

Step 7: Configure a Private Registry

For production environments use a private container registry such as Azure Container Registry or a self-hosted Docker Registry. Authenticate to your registry and tag images before pushing.

# Log in to a private registry
docker login myregistry.azurecr.io -u myuser -p mypassword

# Tag a local image for the registry
docker tag myiis:latest myregistry.azurecr.io/myiis:v1.0

# Push the image
docker push myregistry.azurecr.io/myiis:v1.0

# Pull from the private registry
docker pull myregistry.azurecr.io/myiis:v1.0

Step 8: Work with Docker Volumes

Docker volumes persist data beyond the container lifecycle. Create a named volume, mount it into a container, and inspect its location on the host.

# Create a named volume
docker volume create mydata

# Run a container with the volume mounted
docker run -d --name myapp -v mydata:C:AppData `
    mcr.microsoft.com/windows/servercore:ltsc2016 ping -t localhost

# Inspect the volume
docker volume inspect mydata

# List all volumes
docker volume ls

Step 9: Configure Docker Networks

Docker on Windows Server 2016 supports multiple network drivers: nat (default), transparent, overlay, and l2bridge. Create a custom NAT network with a specific subnet for better IP address management.

# List existing networks
docker network ls

# Create a custom NAT network
docker network create --driver nat --subnet 172.20.0.0/16 mynatnet

# Run a container on the custom network
docker run -d --name webserver --network mynatnet `
    -p 8080:80 myiis:latest

# Inspect network details
docker network inspect mynatnet

Step 10: Monitor and Troubleshoot Docker

Use the following commands to monitor container resource usage, view logs, and troubleshoot issues with the Docker daemon.

# View container resource statistics
docker stats --no-stream

# View container logs
docker logs myapp

# Follow live container logs
docker logs -f myapp

# View Docker daemon events
docker events --since 1h

# Check Docker daemon status
Get-Service Docker
Get-EventLog -LogName Application -Source docker -Newest 20

Setting up Docker on Windows Server 2016 opens a powerful path to containerized application deployment using familiar Windows tools and technologies. By following this guide you have installed and configured the Docker Engine, secured the daemon with TLS, managed images through a private registry, configured persistent volumes, and created custom networks. In production deployments, automate image builds with CI/CD pipelines, enforce resource limits with –memory and –cpus flags on docker run, and regularly scan images for vulnerabilities using tools like Trivy or the Microsoft Container Scanning service. Keeping Docker and your base images updated is critical for maintaining a secure and stable container environment.