How to Run Docker Containers on Windows Server

Running Docker containers on Windows Server is a little like teaching a reliable office building to behave like a food truck: suddenly your applications can move faster, start cleaner, and serve customers without dragging an entire operating system behind them. For teams that depend on .NET Framework apps, IIS workloads, Windows services, legacy enterprise software, or internal tools built around Microsoft infrastructure, Windows Server containers can be a practical bridge between “classic server deployment” and modern container operations.

The good news is that Docker containers on Windows Server are no longer exotic. Windows Server 2019, Windows Server 2022, and Windows Server 2025 all support Windows containers, and administrators can use familiar Docker commands such as docker run, docker ps, docker logs, and docker build. The less glamorous news is that Windows containers have rules. Image versions matter. Isolation mode matters. Networking behaves differently from Linux. And yes, the occasional container error message may look like it was written by a committee of robots after a long lunch.

This guide explains how to run Docker containers on Windows Server from planning to first launch, including installation, container runtime setup, image selection, networking, storage, security, troubleshooting, and practical field experience. The goal is not just to make a container run once. The goal is to make it run predictably, securely, and without turning your server into a mystery box with blinking lights.

What Are Windows Server Containers?

A Windows Server container packages an application with its dependencies and runs it in an isolated environment on a Windows Server host. Unlike a traditional virtual machine, a container does not need to boot a full guest operating system for every app instance. That makes containers faster to start, easier to recreate, and often more efficient for hosting multiple application workloads on the same infrastructure.

Windows containers are especially useful when you need to modernize applications that still rely on Windows APIs, IIS, PowerShell, .NET Framework, Windows services, or enterprise authentication patterns. Instead of manually configuring every server like a snowflake with a strong personality, you can define the environment in a Dockerfile and run it consistently across hosts.

Windows Containers vs. Linux Containers on Windows Server

Before installing anything, understand the difference between Windows containers and Linux containers. Windows Server is designed to run Windows containers directly. Linux containers normally require a Linux environment, such as a Linux virtual machine. Docker Desktop on a developer workstation can switch between Linux and Windows container modes, but production Windows Server hosts are usually prepared specifically for Windows containers.

This distinction matters because a Linux image such as nginx:latest will not run as a native Windows container. Likewise, a Windows image such as mcr.microsoft.com/windows/servercore:ltsc2022 requires a compatible Windows container host. If you try to mix platforms casually, Docker will not politely laugh; it will simply fail.

System Requirements for Docker on Windows Server

To run Docker containers on Windows Server, start with a supported Windows Server version. Modern deployments typically use Windows Server 2019, Windows Server 2022, or Windows Server 2025. The server should be fully patched, have administrator access, and have enough CPU, memory, and disk capacity for the host operating system, container images, logs, and application data.

You also need the Windows Containers feature enabled. If you plan to use Hyper-V isolation, the server must support virtualization, and the Hyper-V role may be required depending on the scenario. For production environments, use a supported container runtime. Microsoft’s support policy for many on-premises Windows Server container scenarios points administrators toward supported runtime configurations rather than casual, unsupported experiments.

Step 1: Prepare Windows Server for Containers

Begin by updating Windows Server. Containers depend heavily on kernel and operating system compatibility, so patching is not optional housekeeping. It is more like putting fuel in the car before complaining that the engine is quiet.

Open PowerShell as Administrator and enable the Containers feature:

If you need Hyper-V isolation, also enable Hyper-V:

After the restart, confirm that the feature is installed:

For virtualized Windows Server hosts, nested virtualization may be necessary if you plan to use Hyper-V isolation inside a VM. This is common in lab environments, private clouds, and test infrastructure. In production, check your hypervisor and licensing policies before building the whole house on nested assumptions.

Step 2: Install a Container Runtime

Docker is the tool most administrators recognize, but the important piece on Windows Server is the container runtime that allows Windows containers to start and run properly. Depending on your environment and support requirements, you may install a supported Docker-compatible runtime for Windows Server containers.

Microsoft’s Windows container documentation includes setup guidance for preparing the host and installing a runtime. Docker’s documentation also explains how Docker Engine works and how the Docker CLI interacts with the daemon. On Windows Server, administrators should avoid assuming that Docker Desktop is the right production answer. Docker Desktop is excellent for many developer workstations, but Windows Server production deployments require a server-appropriate setup.

Once Docker or a compatible runtime is installed, verify the installation:

The output should show client and server information. If the Docker client responds but the server section fails, the Docker service may not be running, the daemon configuration may be incorrect, or the host may not be prepared for containers.

Step 3: Choose the Right Windows Container Base Image

Windows container images are usually built from Microsoft Container Registry base images. The two most common choices are Windows Server Core and Nano Server.

Windows Server Core

Windows Server Core is larger but more compatible. It is a common choice for traditional .NET Framework applications, IIS workloads, and applications that require more Windows components. If your app says, “I need half the operating system and possibly a fax machine,” Server Core is usually the safer starting point.

Nano Server

Nano Server is much smaller and designed for modern workloads such as .NET applications that do not need the broader Windows Server Core component set. It starts faster, consumes less space, and is cleaner for cloud-native patterns. However, it will not support every legacy dependency.

Example images include:

The tag matters. Windows containers are sensitive to host and image version compatibility. If your host is Windows Server 2022, use images intended for LTSC 2022 unless you have a specific reason to do otherwise. When versions do not align, Hyper-V isolation may help in some cases, but choosing the correct base image from the beginning is cleaner.

Step 4: Run Your First Windows Container

Now for the fun part: making something run. Start with a simple container using a Windows Server Core image:

The --rm flag removes the container after it exits. The image is pulled if it is not already available locally. The command runs inside the container and prints a message. It is not glamorous, but neither was the first light bulb. Progress often begins with a tiny glow.

To run an interactive PowerShell session inside a container, use:

Inside the container, you can run commands such as:

To list running containers:

To list all containers, including stopped ones:

Step 5: Understand Process Isolation and Hyper-V Isolation

Windows containers support two main isolation modes: process isolation and Hyper-V isolation.

Process Isolation

Process isolation is lightweight. Containers share the host kernel while maintaining separate views of processes, file systems, registry, networking, and other resources. This is efficient and commonly used when the container image version matches the host operating system version.

Hyper-V Isolation

Hyper-V isolation runs the container inside a highly optimized utility virtual machine. The container still behaves like a container from the Docker user’s perspective, but it has a stronger isolation boundary. Hyper-V isolation can also help with some version compatibility scenarios.

You can request Hyper-V isolation with:

For many single-tenant internal workloads, process isolation may be sufficient. For stronger boundaries or multi-tenant scenarios, Hyper-V isolation deserves serious consideration. Do not choose isolation mode by vibes alone; choose it based on compatibility, security, performance, and support requirements.

Step 6: Run IIS in a Windows Container

A classic Windows Server container demo is IIS. Run the Microsoft IIS image and publish port 80:

Then open a browser and visit:

If you are connecting from another machine, use the server’s IP address or DNS name and confirm that Windows Firewall allows inbound traffic on the published port. The -p 8080:80 mapping sends host port 8080 to container port 80.

Useful commands include:

This is the foundation for containerized IIS apps. In real projects, you would usually build a custom image that copies your application files into the image and configures IIS during the build.

Step 7: Create a Dockerfile for a Windows App

A Dockerfile defines how your image is built. Here is a simple example for an IIS-based site:

Build the image:

Run it:

Use versioned tags such as 1.0, 2026.05.03, or a build number instead of relying blindly on latest. The latest tag is convenient in demos and suspiciously mischievous in production.

Step 8: Configure Networking for Windows Containers

Windows container networking uses virtual network adapters and virtual switches. Docker can create and manage networks, including common modes such as NAT, transparent, overlay, l2bridge, and l2tunnel. The default NAT network is often enough for a single host where containers expose services through published ports.

View networks:

Inspect a network:

Create a custom NAT network:

Run a container on that network:

For multi-host scenarios, overlay networks and orchestrators may be required. For containers that need to appear directly on the physical network, transparent networking may be useful, but it also requires more careful planning around IP addressing, routing, firewall rules, and your organization’s network policies.

Step 9: Add Persistent Storage

Containers are designed to be disposable, but data usually is not. If your application writes uploads, logs, databases, or configuration files, plan storage before production day arrives wearing tap shoes.

Windows containers can use bind mounts and named volumes. A bind mount maps a host directory into the container:

A named volume is managed by Docker:

Use persistent storage only for data that should outlive the container. Do not use a running container as your backup strategy. That is not a backup strategy; that is a cliff with a calendar invite.

Step 10: Use Restart Policies

For long-running services, configure restart policies so containers can come back after a failure or daemon restart.

Common restart policies include no, on-failure, always, and unless-stopped. For simple server workloads, unless-stopped is often practical because Docker restarts the container unless an administrator intentionally stopped it.

You can update an existing container’s restart policy:

Step 11: Manage Logs and Troubleshooting

When a container misbehaves, start with the basics:

If the container exits immediately, check the command or entry point. Many containers stop because the main process exits successfully. That is not failure; that is Docker doing exactly what it was told, which is sometimes more annoying than a real error.

For Windows-specific problems, check host event logs, Docker service logs, Host Compute Service behavior, networking configuration, firewall rules, and version compatibility. If an image fails with an operating system mismatch, rebuild it with the correct base image tag or test Hyper-V isolation if supported.

Step 12: Apply Security Best Practices

Security for Docker containers on Windows Server begins with the host. Keep Windows Server patched, restrict administrator access, control who can use the Docker daemon, scan images, and pull images only from trusted registries. Treat container images as deployable software artifacts, not random ZIP files from the internet wearing a Docker logo.

Use least privilege inside containers whenever possible. Windows containers can run as ContainerUser or ContainerAdministrator, and applications should not run with elevated rights unless they truly require them. Avoid storing secrets directly in images. Use secret management systems, environment-specific configuration, or orchestrator-provided secret features when available.

Also consider isolation requirements. For multi-tenant workloads or stronger security boundaries, Hyper-V isolation may be more appropriate than process isolation. Containers improve packaging and deployment, but they do not magically erase security responsibilities.

Step 13: Use Docker Compose Carefully on Windows Server

Docker Compose is useful for defining multi-container applications in a YAML file. It can start, stop, rebuild, and manage related services together. On Windows Server, Compose availability depends on how Docker or the runtime was installed. Docker Desktop includes Compose for developer machines, while server environments may require a plugin or standalone installation depending on the supported runtime path.

A simple Compose file for an IIS container might look like this:

Run it with:

If your environment uses the older standalone tool, the command may be:

For production, test Compose behavior on the same Windows Server version and runtime configuration you plan to use. Small differences between workstation Docker and server Docker can become big differences when the deployment window is already open and everyone is pretending not to panic.

Common Problems When Running Docker Containers on Windows Server

Problem: The Image Does Not Match the Host

Windows container image version compatibility is one of the most common issues. Use base image tags that match your host’s Windows Server release, such as LTSC 2022 images on Windows Server 2022. If necessary, test Hyper-V isolation.

Problem: The Container Starts and Immediately Stops

A container runs as long as its main process runs. If the command finishes, the container exits. Use docker logs and docker inspect to see what happened.

Problem: The Website Does Not Load

Check port publishing, Windows Firewall, application binding, and whether the service inside the container is listening on the expected port. Also confirm that you are connecting to the host port, not the container’s internal port.

Problem: File Mounts Behave Strangely

Use Windows paths carefully. Confirm that the host directory exists and that the container has permission to access it. Avoid mixing Linux path assumptions with Windows containers.

Problem: DNS or Network Connectivity Fails

Inspect the Docker network, verify DNS settings, and check whether corporate firewalls, proxies, or endpoint security tools are interfering. Container networking on Windows is powerful, but it rewards administrators who read the map before driving into the lake.

Practical Example: Containerizing a Simple IIS Website

Suppose you have a static internal website in C:\Projects\CompanyPortal\site. Create this Dockerfile in C:\Projects\CompanyPortal:

Build and run it:

Test locally:

Update the site by changing files, rebuilding the image with a new tag, stopping the old container, and launching the new version. In more advanced environments, you would push the image to a registry and deploy it through a controlled release process.

Performance Tips for Windows Server Containers

Use the smallest base image that supports your app. Nano Server is lean, but Server Core is more compatible. Do not install unnecessary tools inside production images. Keep Dockerfile layers clean, remove temporary files during the build, and avoid turning the image into a digital attic full of forgotten installers.

Monitor CPU, memory, disk I/O, and network usage. Containers make deployment easier, but they still consume real resources. Set limits where appropriate, especially on shared hosts. Keep logs under control because runaway logs can fill disks faster than a group chat fills with “quick questions.”

Experience-Based Advice for Running Docker Containers on Windows Server

After working with Windows Server containers, one lesson becomes obvious: success depends less on memorizing Docker commands and more on respecting the Windows container ecosystem. Linux container habits do not always translate perfectly. On Linux, many teams casually pull an image, mount a path, expose a port, and move on. On Windows Server, you need to think about host build, base image tag, isolation mode, networking driver, and the application’s dependency history.

The first practical experience is to standardize your host versions. If one server runs Windows Server 2019 and another runs Windows Server 2022, your image strategy becomes more complicated. A container image that behaves perfectly on one host may fail on another because of version compatibility. Keeping container hosts aligned reduces surprises and makes troubleshooting much faster. In production, consistency is not boring. Consistency is what lets you sleep.

The second experience is to build images deliberately. Avoid opening a running container, installing things manually, and then hoping to remember what you did. That approach recreates the old “works on my machine” problem, except now the machine has layers. Put configuration steps in a Dockerfile. Use clear image tags. Store Dockerfiles in version control. Document why each dependency exists. Future you will be grateful, and future you is notoriously hard to impress.

The third experience is to test networking early. Many Windows container issues that look like application bugs are actually port, firewall, DNS, or network driver problems. Before blaming the application, confirm that the container is listening, the host port is published, the firewall permits traffic, and the client is reaching the correct address. Use docker inspect, docker logs, Test-NetConnection, and simple HTTP checks. Start with one container on the default NAT network before introducing custom networks or multi-host designs.

The fourth experience is to treat persistent storage with caution. Containers should be replaceable. If the only copy of important data lives inside a writable container layer, you are one removal command away from a very educational afternoon. Use named volumes or bind mounts for persistent data, and back them up through normal enterprise backup processes. For databases, consider whether a container is truly the right home, especially on Windows Server, where operational expectations may differ from Linux-based container platforms.

The fifth experience is to avoid over-containerizing. Not every Windows application becomes better just because it is inside a container. Apps with heavy GUI dependencies, deep hardware integration, unusual drivers, complex domain assumptions, or fragile installation routines may be poor candidates. Good candidates are services that can run unattended, expose network endpoints, use clear configuration, and tolerate being rebuilt and redeployed. Containerization should simplify operations, not create a tiny museum of legacy problems.

The sixth experience is to plan security before production. Lock down who can access Docker commands. A user who can control the Docker daemon may effectively gain powerful control over the host. Use trusted images, scan images, patch base images, and rebuild regularly. Do not bake passwords, certificates, API keys, or connection strings into the image. Secrets inside images have a way of becoming permanent archaeological artifacts.

The seventh experience is to create a repeatable troubleshooting checklist. When a container fails, check the same items in the same order: host version, image tag, isolation mode, container logs, exit code, event logs, port mapping, firewall, DNS, storage mounts, and resource limits. This prevents random guessing, which is emotionally satisfying for about eight seconds and technically useful almost never.

The final experience is to start small. Run a basic Windows Server Core container. Then run IIS. Then build one custom image. Then add storage. Then add restart policies. Then test deployment from a registry. Each step teaches you how Windows Server containers behave. By the time you containerize a real application, Docker will feel less like a black box and more like a very strict but useful coworker.

Conclusion

Learning how to run Docker containers on Windows Server gives administrators and developers a practical way to modernize Windows workloads without rewriting everything overnight. With the right host preparation, compatible base images, thoughtful isolation choices, clear networking, persistent storage planning, and disciplined security practices, Windows containers can make application deployment faster, cleaner, and more repeatable.

The key is to respect the platform. Windows Server containers are powerful, but they are not Linux containers wearing a different hat. Version compatibility, isolation mode, and Windows-specific networking deserve careful attention. Start with simple commands, build clean Dockerfiles, use reliable image tags, and test every production assumption before users are depending on it.

Done well, Docker on Windows Server can reduce deployment drama, improve consistency, and help teams move from manual server configuration to repeatable infrastructure. And honestly, any technology that helps retire the phrase “just RDP into the server and fix it” deserves a warm round of applause.