The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
Inspect the host buildGet-ComputerInfo -Property WindowsProductName, ` WindowsVersion, OsBuildNumber, OsArchitectureView examples
Check the Containers featureGet-WindowsFeature -Name Containers, Hyper-VView examples
Inspect Docker endpointsdocker versionView examples
Inspect runtime configurationdocker infoView examples
Pull a serviced base imagedocker pull ` mcr.microsoft.com/windows/servercore:ltsc2025View examples
List local imagesdocker image ls --digests --filter ` reference='mcr.microsoft.com/windows/servercore:*'View examples
Inspect image OS metadatadocker image inspect ` mcr.microsoft.com/windows/servercore:ltsc2025 --format ` '{{.Os}} {{.OsVersion}} {{.Architecture}}'View examples
Build from refreshed layersdocker build --pull --tag contoso/webapp:2026.08 .View examples
Capture a repository digestdocker image inspect contoso/webapp:2026.08 --format ` '{{json .RepoDigests}}'View examples
Run a disposable version checkdocker run --rm --isolation=hyperv ` mcr.microsoft.com/windows/servercore:ltsc2025 cmd.exe ` /S /C verView examples
Start a bounded test servicedocker run --detach --name webapp-test ` --isolation=hyperv --memory 1g --publish ` 127.0.0.1:8080:8080 contoso/webapp:2026.08View examples
List all containersdocker container ls --all --no-truncView examples
Inspect container configurationdocker container inspect webapp-testView examples
List managed volumesdocker volume lsView examples
Inspect the NAT networkdocker network inspect natView examples
Read recent application logsdocker logs --timestamps --tail 100 webapp-testView examples
Sample resource usagedocker stats --no-stream webapp-testView examples
Stop with a grace perioddocker stop --time 30 webapp-testView examples
Remove a stopped containerdocker container rm webapp-testView examples

Windows containers package an application's user-mode dependencies while relying on either the host kernel or a Hyper-V-isolated utility VM. Reliability starts with a supported host, runtime, base-image family, build, and isolation combination. Treat tags as mutable inputs, rebuild from serviced images instead of patching running containers, minimize host integration, and preserve application state outside each container's writable layer.

Step by step

Detailed examples

01

Confirm host, edition, features, runtime, and administrative scope

Windows Server 2016 through Windows Server 2025 can host Windows Server containers when paired with a supported runtime such as Moby, Mirantis Container Runtime, or containerd. Windows 10 and Windows 11 development hosts require Professional or Enterprise edition and Hyper-V; Microsoft recommends Windows Server for production. On Windows Server, install the Containers feature and a supported runtime; Hyper-V isolation additionally needs Hyper-V and hardware virtualization, including nested virtualization when the host is itself a VM. Feature or runtime setup changes the machine, requires elevation, and can require a reboot, so inspect first and follow the current vendor installation procedure. No PowerShell module or Active Directory domain is inherently required to operate Docker containers, though the application, registry, orchestration platform, or gMSA design can add domain prerequisites. Docker commands target the daemon selected by the current context or endpoint; secure remote daemons with authenticated TLS or an approved management plane because control of the daemon is effectively host-administrative access.

Inventory a prepared Windows Server container host
Get-ComputerInfo -Property WindowsProductName, WindowsVersion, OsBuildNumber, OsArchitecture
Get-WindowsFeature -Name Containers, Hyper-V
Get-Service -Name docker, containerd -ErrorAction SilentlyContinue | Select-Object Name, Status, StartType
docker version
docker info

Note: These checks do not install or restart anything. Docker CLI is an external executable, not a PowerShell module, and its commands do not implement PowerShell WhatIf. Verify the active Docker context or endpoint before any mutation.

Back to quick reference ↑
02

Match base-image family and build to the host

Choose Nano Server for modern applications that fit its small API surface, Server Core for broader Win32 and full .NET Framework compatibility, and the larger Windows or Windows Server images only when their APIs are required. Process isolation shares the host kernel and normally requires compatible host and image builds; Hyper-V isolation provides its own kernel and broader version compatibility, but the current Microsoft compatibility matrix remains authoritative. Tags such as ltsc2025 move as Microsoft publishes serviced images, while a digest identifies exact registry content. Pulling consumes network bandwidth and disk and can replace the local tag pointer; Docker has no WhatIf preview, so approve registry, tag, expected size, and maintenance impact first.

Pull and inspect a Windows Server Core image
$image = 'mcr.microsoft.com/windows/servercore:ltsc2025'
docker pull $image
docker image ls --digests --filter reference='mcr.microsoft.com/windows/servercore:*'
docker image inspect $image --format '{{.Os}} {{.OsVersion}} {{.Architecture}}'
docker image inspect $image --format '{{json .RepoDigests}}'

Note: Pull only after matching the selected image release and isolation mode to the host compatibility table. A local image ID is host-local; preserve a registry digest or signed supply-chain attestation for deployment identity.

Back to quick reference ↑
03

Build minimal images from reviewable inputs

Use a Dockerfile in version control, copy only published application artifacts, run the workload as ContainerUser when it does not require administrator rights, and exclude secrets and build output with .dockerignore. The build context is sent to the daemon and can disclose any included files, including to a remote endpoint. --pull refreshes a mutable base tag but does not guarantee reproducibility; pin a reviewed digest where policy requires an immutable input, rebuild regularly from Microsoft's serviced base images, scan the result, and promote its registry digest rather than rebuilding independently in each environment.

Build a non-administrator Server Core application image
@'
# escape=`
FROM mcr.microsoft.com/windows/servercore:ltsc2025
WORKDIR C:\app
COPY publish\ .\
USER ContainerUser
ENTRYPOINT ["C:\\app\\Contoso.Web.exe"]
'@ | Set-Content -LiteralPath '.\Dockerfile' -Encoding ascii

docker build --pull --tag contoso/webapp:2026.08 .
docker image inspect contoso/webapp:2026.08 --format '{{json .RepoDigests}}'

Note: The file-writing step is intentionally scoped to a project Dockerfile placeholder. Set-Content overwrites an existing file and Docker build has no WhatIf; review the repository diff, context exclusions, base digest, and executable path before use. RepoDigests is empty until content is associated with a registry repository.

Back to quick reference ↑
04

Choose isolation and runtime limits explicitly

Process-isolated containers share the host kernel and are not a robust security boundary for hostile multitenancy. Hyper-V isolation runs each container with a utility VM and is Microsoft's stronger boundary, at additional startup and resource cost. Use an explicit image, name, isolation mode, memory limit, and narrowly bound port; 127.0.0.1 publication keeps this example local but does not replace application authentication or firewall policy. ContainerUser reduces in-container privilege, but mounting host resources, named pipes, devices, or the daemon socket can pierce isolation. docker run immediately creates and may start state, and neither Docker nor the invoked process honors PowerShell WhatIf.

Inspect first, then run constrained test containers
docker container ls --all --no-trunc
docker run --rm --isolation=hyperv mcr.microsoft.com/windows/servercore:ltsc2025 cmd.exe /S /C ver
docker run --detach --name webapp-test --isolation=hyperv --memory 1g --publish 127.0.0.1:8080:8080 contoso/webapp:2026.08
docker container inspect webapp-test

Note: Run commands are change examples, not previews. Confirm that webapp-test is unused, port 8080 is available, the image digest is approved, virtualization is present, and the workload has no unexternalized state before execution.

Back to quick reference ↑
05

Treat mounts, networks, and published ports as trust boundaries

A container writable layer disappears when the container is removed, so durable application data belongs in a named volume, an approved bind mount, or an external service with its own backup and consistency design. Listing volumes is read-only, but a volume name alone does not reveal ownership or backup readiness. The Windows nat network provides connectivity, while published ports expose services on host addresses; bind to the smallest required interface and enforce host and upstream firewall policy. Bind mounts, named pipes, devices, and shared network namespaces deliberately increase host coupling and can weaken isolation. A domain is unnecessary for basic NAT networking, but domain identity such as gMSA requires a separately supported host, domain, credential-spec, and orchestrator design.

Inventory storage and network attachments
docker volume ls
docker network ls
docker network inspect nat
docker container inspect webapp-test --format '{{json .Mounts}}'
docker container inspect webapp-test --format '{{json .NetworkSettings.Ports}}'

Note: Do not delete an apparently unused volume until ownership, retention, backup, and restore have been verified. Docker volume prune and network prune have no WhatIf and are intentionally omitted.

Back to quick reference ↑
06

Observe, rebuild, replace, and clean up deliberately

Use application logs, health status, runtime events, and one-shot resource metrics together; logs can contain secrets and docker stats is not an application availability test. Windows Server containers do not have a servicing stack like the host, so monthly security maintenance means pulling serviced base content, rebuilding and scanning the application image, then replacing containers under an availability plan. docker stop sends the configured stop signal and forces termination after its timeout; docker container rm deletes the stopped container and writable layer. Neither command supports WhatIf. Confirm externalized state and named-volume ownership, retain rollback image digests, validate the replacement from the client path, and only then remove the old instance.

Collect evidence and show a controlled retirement sequence
$name = 'webapp-test'
docker logs --timestamps --tail 100 $name
docker stats --no-stream $name
docker container inspect $name --format '{{json .State}}'
# After replacement approval and external state verification:
docker stop --time 30 $name
docker container rm $name

Note: The final two commands mutate state and cannot be previewed. Removing a container permanently discards its writable layer; named volumes remain, but anonymous-volume and bind-mount handling must be verified separately.

Back to quick reference ↑

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. MicrosoftPrepare Windows operating system containerslearn.microsoft.com
  2. MicrosoftOverview of Windows Container Base Imageslearn.microsoft.com
  3. MicrosoftWindows container version compatibilitylearn.microsoft.com
  4. MicrosoftIsolation Modeslearn.microsoft.com
  5. MicrosoftUpdate Windows Server containerslearn.microsoft.com

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback