Windows

Deploy and manage Docker containers on Windows Server 2025 VPS

You have a Windows Server 2025 VPS with 8 GB of RAM and a full Administrator account. You need to run containerized workloads, but Docker Desktop is out of the question on a headless server. The answer is Docker Engine, installed natively on Windows Server 2025, running Windows containers alongside your IIS or .NET applications. This guide walks you through the installation, the first container, and the day-to-day management commands you will actually use.

  • Docker Engine runs natively on Windows Server 2025 as a Windows service.
  • Windows containers share the kernel with the host, so the container OS version must match the host build.
  • Docker Compose v2 works on Windows Server and uses the docker compose syntax, not docker-compose.
  • You manage everything through PowerShell, the docker CLI, and optionally a remote Docker context.

Prerequisites

  • A Windows Server 2025 VPS with at least 4 GB of RAM (8 GB recommended for real workloads).
  • Full Administrator access via RDP or PowerShell Remoting.
  • The Containers Windows feature enabled. The Hyper-V feature is optional and only needed for Hyper-V isolation.
  • Familiarity with the docker CLI on Linux. The commands are identical, the host OS is what differs.

If you are deciding between operating systems for this kind of workload, a Linux VPS is usually the simpler path for Docker. But when your stack is .NET Framework, PowerShell modules, or legacy Windows services, running containers on Windows Server keeps everything consistent with your existing infrastructure.

Why run Docker on Windows Server instead of a Linux VPS

Docker on Windows Server does not run Linux containers side by side with Windows ones. The engine runs Windows containers natively, and Linux containers require a Linux virtual machine underneath, which defeats the purpose of a lightweight container runtime. So when do you pick Windows containers over a Windows VPS with traditional services?

The case is usually a .NET Framework application that cannot move to .NET Core, or a service that depends on Windows APIs and registry keys. Containerizing it gives you the same packaging and lifecycle benefits Linux users take for granted: immutable images, easy rollbacks, and isolated deployment units. You keep the Windows kernel, you just stop managing applications as if they were pets.

Windows Server 2025 is the current Long-Term Servicing Channel release, with mainstream support through 2029 and extended support through 2034. Starting a container platform on it is a long-term decision, not a stopgap.

Step 1 - Install the Containers feature and Docker Engine

Open an elevated PowerShell session and enable the Containers feature first. This prepares the OS to run Windows containers, installing the required kernel components.

Install-WindowsFeature -Name Containers
Restart-Computer -Force

The restart is mandatory. The Containers feature adds a Windows feature payload that only activates on reboot. Skipping it leads to confusing errors later, like the docker service starting but containers failing to initialize.

After the server comes back, install Docker Engine using the official provider. The DockerMsftProvider module is the supported path for Windows Server.

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

This installs Docker Engine 20.10.x or the current stable build available in the provider, registers it as a Windows service, and starts it. To make it start automatically on boot, set the service startup type:

Set-Service -Name docker -StartupType Automatic

Verify the install:

docker version

You should see the client and server versions listed. The "Server" section appearing means the engine is running. If only the client shows up, the service failed to start, check the next section's troubleshooting steps.

Step 2 - Pull and run your first Windows container

Windows containers are based on Windows base images, not Alpine or Debian. The two you will use most are mcr.microsoft.com/windows/servercore and mcr.microsoft.com/windows/nanoserver. ServerCore is a full Server installation without the GUI, around 4 GB. Nano Server is a minimal footprint, around 200 MB, but it has limitations on what you can install inside.

Pull the Nano Server image and test it:

docker pull mcr.microsoft.com/windows/nanoserver:ltsc2025
docker run --rm mcr.microsoft.com/windows/nanoserver:ltsc2025 cmd /c "echo Hello from a Windows container"

The version tag matters. Windows containers must match the host OS build. Windows Server 2025 uses the ltsc2025 tag. Pulling an ltsc2022 image onto a 2025 host fails at runtime because the container expects a different kernel version. This is the single most common mistake people make when starting with Windows containers.

Verify the container ran:

docker ps -a

You should see the exited container in the list, or nothing if --rm cleaned it up. If the command output "Hello from a Windows container", the engine works.

Step 3 - Deploy a multi-container app with Docker Compose v2

Docker Compose is bundled with Docker Engine on Windows Server, so you do not install it separately. Check the version with docker compose version. The v2 syntax uses a space, not a hyphen.

Create a project directory and a docker-compose.yml file. Here is a realistic example running an IIS site and a Redis cache, two workloads that make sense on Windows infrastructure:

mkdir C:\containers\webapp
cd C:\containers\webapp
notepad docker-compose.yml
services:
  web:
    image: mcr.microsoft.com/windows/servercore:ltsc2025
    ports:
      - "80:80"
    command: powershell -Command Add-WindowsFeature Web-Server; Start-Sleep -Seconds 86400
  cache:
    image: mcr.microsoft.com/windows/nanoserver:ltsc2025
    command: cmd /c ping -t 127.0.0.1

This example keeps things simple: the web service exposes port 80 and installs IIS on start, the cache service stays alive with a ping loop. In production you would build a proper image with a Dockerfile that installs IIS at build time, not at container start.

Deploy it:

docker compose up -d
docker compose ps

Verify the stack:

curl.exe http://localhost

You should get the IIS welcome page. If the container started but the page does not load, the IIS installation inside the container may still be running, give it a minute and retry.

Step 4 - Manage Docker containers day to day

The docker CLI on Windows Server behaves exactly like on Linux, but with a few Windows-specific notes. Use these commands daily:

docker ps                     # list running containers
docker ps -a                   # list all containers, including stopped
docker logs <container-id>     # view stdout logs of a container
docker inspect <container-id>  # detailed config and state in JSON
docker stop <container-id>     # gracefully stop a container
docker rm <container-id>       # remove a stopped container
docker image prune -a          # remove unused images
docker system df               # show disk usage by images, containers, volumes

One important difference: PowerShell aliases docker in some configurations. If you run docker ps and get a list of processes instead of containers, you have the alias conflict. Fix it by running docker.exe ps or by removing the alias in your profile. This trips up Windows admins more than any other docker command issue.

For logs, docker logs works for containers that write to stdout. Windows services inside containers often write to the Windows event log instead, so you may need docker exec <container-id> powershell Get-EventLog -LogName Application to see what is failing. Build this into your debugging workflow early.

Step 5 - Set up the Docker daemon to listen remotely

Managing containers through RDP is fine for a single server, but when you have several Windows hosts, point your local docker CLI at them over the network. This requires configuring the Docker daemon to listen on a TCP port with TLS, never on a naked port.

Edit the daemon configuration at C:\ProgramData\docker\config\daemon.json:

{
  "hosts": ["npipe://", "tcp://0.0.0.0:2376"],
  "tlsverify": true,
  "tlscacert": "C:\\ProgramData\\docker\\certs\\ca.pem",
  "tlscert": "C:\\ProgramData\\docker\\certs\\server-cert.pem",
  "tlskey": "C:\\ProgramData\\docker\\certs\\server-key.pem"
}

Generate the certificates using a trusted CA or your own internal CA, copy the client certificates to your workstation, and restart the service:

Restart-Service docker

On your local machine, connect using the context syntax:

docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H tcp://192.0.2.10:2376 ps

Set that up as a Docker context so you do not type the flags every time:

docker context create windows-prod --docker "host=tcp://192.0.2.10:2376,ca=ca.pem,cert=cert.pem,key=key.pem"
docker context use windows-prod

This gives you the same workflow as managing a remote Linux Docker host, right from a workstation on your desk. It is the setup I recommend for any Windows Server container fleet beyond a single test box.

Step 6 - Automate container startup and monitoring

Containers do not restart automatically unless you tell them to. You have two options: the --restart policy on individual containers, or a scheduled task that checks and starts the stack.

For a single container, set the restart policy at creation time:

docker run -d --restart unless-stopped -p 80:80 your-image

For Compose stacks, add restart: unless-stopped under each service in the compose file. This is the simplest production safeguard, it survives both container crashes and host reboots.

Monitoring on Windows Server means watching docker events and the service state. Use PowerShell to capture events:

docker events --filter "event=die" --filter "event=restart"

This prints a stream of container stop and restart events. Run it in a scheduled task that writes to a log file, and you have a lightweight audit trail without adding a monitoring stack.

For deeper metrics on a VPS monitoring setup, export container stats to a file at intervals, or install one of the container-aware monitoring agents. On a single VPS, docker stats run on demand is usually enough.

Troubleshooting common Windows container failures

Windows containers fail in predictable ways. Here are the three failures you will hit first, and the diagnostics that find them.

The container exits immediately after starting

This is usually a version mismatch between the container image and the host build. Run:

docker inspect <container-id> | Select-String -Pattern "image"
Get-ComputerInfo | Select-Object WindowsProductName, WindowsVersion

If the image tag targets an older Windows release, pull the matching ltsc2025 tag and rebuild.

The docker service fails to start

The Containers feature is missing, or the service account lost permissions. Check the Windows event log:

Get-EventLog -LogName Application -Source docker -Newest 20

The fix is almost always re-running Install-WindowsFeature -Name Containers and rebooting, then starting the service again.

Ports are not reachable from outside

Windows Firewall blocks container ports by default. The docker engine creates a firewall rule for mapped ports, but explicit rules sometimes override it. Check and add a rule:

New-NetFirewallRule -DisplayName "Docker 80" -Direction Inbound -LocalPort 80 -Protocol TCP -Action Allow

The container may be running fine and the host firewalling is the only thing standing between you and the app.

FAQ

Can Docker on Windows Server run Linux containers?

Not natively. The Windows Docker Engine runs Windows containers that share the Windows kernel. Running Linux containers requires a Linux VM or a Linux-based Docker host, which is what a Linux VPS gives you. On Windows Server, you cannot mix both container types in a single engine instance.

How much RAM does a Windows Server 2025 VPS need for Docker?

The base OS plus Docker Engine needs around 2 GB. Each Windows container adds memory based on its workload, a Nano Server container with a small process uses 200-300 MB, ServerCore with IIS uses 1-1.5 GB. Plan for 4 GB minimum, 8 GB if you are running multiple services. Windows Server generally needs more RAM than an equivalent Linux host for the same workload.

What is the difference between ltsc2022 and ltsc2025 container images?

The tag indicates the Windows Server release the image is built for. Containers share the host kernel, so an ltsc2022 image running on a Windows Server 2025 host causes a version mismatch error on start. Always pull the tag that matches your host OS, which is ltsc2025 for Windows Server 2025.

Do I need Docker Desktop on Windows Server?

No. Docker Desktop is for Windows 10 and 11 workstations and requires a license for commercial use. Windows Server uses Docker Engine, installed via the DockerMsftProvider module, which is free and designed for server workloads. The command set is the same, the installation path is different.

Is Docker Compose v2 available on Windows Server 2025?

Yes. Docker Engine on Windows Server ships with Docker Compose v2 built in. You use the docker compose syntax with a space, not the legacy docker-compose command, and the compose file format is identical to Linux.

Related articles

Windows Server 2025 部署 Docker 要点

Windows Server 2025 上安装 Docker Engine 需要使用 PowerShell 启用容器功能并重启,然后通过 DockerMsftProvider 安装引擎。Windows 容器与宿主机共享内核,镜像标签必须匹配 ltsc2025,否则容器启动会失败。Docker Compose v2 已内置,使用 docker compose 语法管理多容器应用。生产环境建议设置容器重启策略,并通过 TLS 远程管理 Docker 守护进程。与 Linux 容器不同,Windows 容器只能运行 Windows 镜像。

Note: This guide is for general reference. Every system and infrastructure has its own specifics, so test each step in a safe environment and consult a qualified engineer before applying it in production.