Skip to content

Instantly share code, notes, and snippets.

@YoraiLevi
Created August 5, 2026 10:21
Show Gist options
  • Select an option

  • Save YoraiLevi/04c1a97f368fb4f6630f9f741c6ac8e1 to your computer and use it in GitHub Desktop.

Select an option

Save YoraiLevi/04c1a97f368fb4f6630f9f741c6ac8e1 to your computer and use it in GitHub Desktop.
Install Docker Desktop for Windows containers — prerequisites, WinGet override, PowerShell script, and smoke test

Install Docker Desktop for Windows containers

Install Docker Desktop machine-wide on Windows 11 Pro/Enterprise, enable the required Windows features, select the Windows container engine, and run a Nano Server smoke test.

This setup requires Administrator access and a restart. Windows containers are not available from Docker Desktop's per-user installation mode.

Sources:

TL;DR

Download install-windows-docker.ps1 from this gist, inspect it, and run it from PowerShell as Administrator:

$url  = 'https://gist.githubusercontent.com/YoraiLevi/04c1a97f368fb4f6630f9f741c6ac8e1/raw/install-windows-docker.ps1'
$dest = "$env:TEMP\install-windows-docker.ps1"

Invoke-WebRequest -UseBasicParsing $url -OutFile $dest
Unblock-File $dest
Get-Content $dest
& $dest

If the script enables Hyper-V or Containers, it stops and asks you to restart. After restarting, run the script again. The second run installs Docker Desktop, starts its Windows engine, and performs this smoke test:

docker run --rm --isolation=hyperv `
  mcr.microsoft.com/windows/nanoserver:ltsc2022 `
  cmd.exe /S /C "echo Hello from a Windows container & ver"

Use -SkipSmokeTest if you do not want to download the Nano Server image:

& $dest -SkipSmokeTest

Prerequisites

Requirement Why
Windows 11 Pro or Enterprise Docker Desktop Windows-container support
Hardware virtualization enabled Required by Hyper-V isolation
Administrator access Required for Windows features and machine-wide installation
At least 8 GB RAM Docker Desktop's documented minimum
WinGet Used to download and track Docker Desktop

Check virtualization in Task Manager → Performance → CPU. It should say Virtualization: Enabled.

Why plain WinGet is not enough

As checked on 2026-08-05, the public Docker.DockerDesktop WinGet manifest adds these installer arguments:

--backend=wsl-2 --no-windows-containers

That produces a Linux-only Docker Desktop installation. The Windows engine is absent and this command fails with engine is disabled:

docker desktop engine use windows

The script uses WinGet's --override option to replace the manifest arguments:

winget install --exact --id Docker.DockerDesktop --source winget `
  --override "install --quiet --accept-license --backend=windows --always-run-service"

The important points are:

  • --backend=windows selects the Windows engine initially.
  • Omitting --no-windows-containers keeps Windows integration available.
  • --always-run-service keeps Docker's privileged Windows service available.
  • The default installation is machine-wide, which Windows containers require.

The manifest may change later. Inspect the current version in the WinGet community repository.

Manual installation

Open PowerShell as Administrator.

Enable Hyper-V and Containers:

Enable-WindowsOptionalFeature -Online `
  -FeatureName Microsoft-Hyper-V-All -All -NoRestart

Enable-WindowsOptionalFeature -Online `
  -FeatureName Containers -All -NoRestart

Set-Service LanmanServer -StartupType Automatic
Start-Service LanmanServer
Restart-Computer

After restarting, install Docker Desktop with corrected arguments:

winget install --exact --id Docker.DockerDesktop --source winget `
  --accept-source-agreements --accept-package-agreements `
  --override "install --quiet --accept-license --backend=windows --always-run-service"

Start Docker and verify the engine:

docker desktop start
docker desktop engine ls
docker desktop engine use windows
docker info --format 'Docker server OS: {{.OSType}}'

Expected result:

Docker server OS: windows

Run a disposable Windows container:

docker run --rm --isolation=hyperv `
  mcr.microsoft.com/windows/nanoserver:ltsc2022 `
  cmd.exe /S /C "echo Hello from a Windows container & ver"

Existing Linux-only Docker Desktop installation

Check the installation policy:

Get-Content C:\ProgramData\DockerDesktop\install-settings.json
docker desktop engine ls

If it contains "noWindowsContainers": true, Docker was installed with an installation-time security restriction. Do not work around it by manually editing the JSON file.

Back up important Docker images and volumes before uninstalling. Uninstalling Docker Desktop removes its local Docker data.

winget uninstall --exact --id Docker.DockerDesktop

winget install --exact --id Docker.DockerDesktop --source winget `
  --accept-source-agreements --accept-package-agreements `
  --override "install --quiet --accept-license --backend=windows --always-run-service"

Restart Windows and verify again.

Upgrading later

An ordinary WinGet upgrade can reapply the manifest's Linux-only arguments. Until the manifest changes, upgrade with the same override:

winget upgrade --exact --id Docker.DockerDesktop --source winget `
  --override "install --quiet --accept-license --backend=windows --always-run-service"

After upgrading, confirm that both engines remain registered:

docker desktop engine ls

Common issues

Symptom Explanation or fix
The requested operation requires elevation Run PowerShell as Administrator
engine is disabled Docker was installed with --no-windows-containers; reinstall as described above
Only linux appears in docker desktop engine ls Windows integration was disabled during installation
no matching manifest for linux/amd64 Docker is still using the Linux engine; run docker desktop engine use windows
Container/image version error Use --isolation=hyperv, or choose an image compatible with the host kernel
docker-users access error Add only trusted users to the local docker-users group, then sign out and back in
Docker and Podman both installed Use docker for Docker and podman for Podman; do not redirect DOCKER_HOST unless intentional

Uninstall

Warning: this removes Docker Desktop's local containers, images, and volumes.

winget uninstall --exact --id Docker.DockerDesktop

The Windows Containers and Hyper-V features are not disabled automatically. Other applications may depend on Hyper-V, so do not disable it casually.

#Requires -Version 5.1
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Enable Windows container prerequisites, install Docker Desktop with Windows
container integration, select the Windows engine, and optionally smoke-test it.
.DESCRIPTION
The public WinGet Docker Desktop manifest currently supplies
--no-windows-containers. This script replaces the manifest's arguments with an
explicit machine-wide Windows-container configuration.
The script deliberately refuses to replace an existing Docker Desktop install
whose installation policy disables Windows containers. Uninstalling Docker can
destroy local images, containers, and volumes, so that decision remains manual.
.PARAMETER SkipSmokeTest
Do not pull and run the Nano Server hello-world test image.
.EXAMPLE
.\install-windows-docker.ps1
.EXAMPLE
.\install-windows-docker.ps1 -SkipSmokeTest
#>
[CmdletBinding()]
param(
[switch]$SkipSmokeTest
)
$ErrorActionPreference = 'Stop'
function Write-Step([string]$Message) {
Write-Host "==> $Message" -ForegroundColor Cyan
}
function Write-Ok([string]$Message) {
Write-Host "[OK] $Message" -ForegroundColor Green
}
function Write-Warn2([string]$Message) {
Write-Host "[!] $Message" -ForegroundColor Yellow
}
function Wait-DockerServer {
param(
[ValidateSet('linux', 'windows')]
[string]$ExpectedOS,
[int]$TimeoutSeconds = 180
)
$deadline = (Get-Date).AddSeconds($TimeoutSeconds)
do {
$serverOS = (& docker info --format '{{.OSType}}' 2>$null | Out-String).Trim()
if ($LASTEXITCODE -eq 0 -and $serverOS -eq $ExpectedOS) {
return
}
Start-Sleep -Seconds 2
} while ((Get-Date) -lt $deadline)
throw "Docker did not become ready with the '$ExpectedOS' engine within $TimeoutSeconds seconds."
}
Write-Step 'Checking Windows edition and build'
$os = Get-CimInstance Win32_OperatingSystem
Write-Host " $($os.Caption) (build $($os.BuildNumber))"
if ($os.Caption -notmatch 'Windows 1[01] (Pro|Enterprise)') {
throw 'Windows containers through Docker Desktop require Windows 10/11 Pro or Enterprise.'
}
Write-Step 'Checking hardware virtualization'
$computer = Get-CimInstance Win32_ComputerSystem
$processor = Get-CimInstance Win32_Processor | Select-Object -First 1
if (-not $computer.HypervisorPresent -and
$processor.VirtualizationFirmwareEnabled -eq $false) {
throw 'Hardware virtualization is disabled. Enable AMD-V/VT-x in BIOS or UEFI, then restart.'
}
Write-Ok 'Virtualization is available.'
Write-Step 'Enabling Hyper-V and Windows Containers'
$restartRequired = $false
$features = @('Microsoft-Hyper-V-All', 'Containers')
foreach ($featureName in $features) {
$feature = Get-WindowsOptionalFeature -Online -FeatureName $featureName
if ($feature.State -eq 'Enabled') {
Write-Ok "$featureName is already enabled."
continue
}
$result = Enable-WindowsOptionalFeature -Online `
-FeatureName $featureName -All -NoRestart
Write-Ok "$featureName enabled."
if ($result.RestartNeeded) {
$restartRequired = $true
}
}
Set-Service LanmanServer -StartupType Automatic
Start-Service LanmanServer
Write-Ok 'Windows Server service is enabled and running.'
if ($restartRequired) {
Write-Warn2 'Windows must restart before Docker can be installed and tested.'
Write-Host ' Run: Restart-Computer'
Write-Host ' Then run this script again.'
return
}
Write-Step 'Checking WinGet'
$winget = Get-Command winget.exe -ErrorAction SilentlyContinue
if (-not $winget) {
throw 'WinGet was not found. Install or update Microsoft App Installer, then retry.'
}
Write-Ok "Found $($winget.Source)"
$dockerDesktopPath = Join-Path $env:ProgramFiles 'Docker\Docker\Docker Desktop.exe'
$installSettingsPath = 'C:\ProgramData\DockerDesktop\install-settings.json'
if (Test-Path $dockerDesktopPath) {
Write-Step 'Checking the existing Docker Desktop installation'
if (Test-Path $installSettingsPath) {
$installSettings = Get-Content -Raw $installSettingsPath | ConvertFrom-Json
if ($installSettings.noWindowsContainers -eq $true) {
throw @'
This Docker Desktop installation explicitly disables Windows containers.
Back up any Docker data, uninstall Docker Desktop, and rerun this script:
winget uninstall --exact --id Docker.DockerDesktop
The script will not uninstall it automatically because uninstalling can destroy
local Docker containers, images, and volumes.
'@
}
}
Write-Ok 'Docker Desktop is already installed without the known restriction.'
} else {
Write-Step 'Installing Docker Desktop with Windows container integration'
$override = 'install --quiet --accept-license --backend=windows --always-run-service'
$wingetArguments = @(
'install',
'--exact',
'--id', 'Docker.DockerDesktop',
'--source', 'winget',
'--accept-source-agreements',
'--accept-package-agreements',
'--override', $override
)
& $winget.Source @wingetArguments
if ($LASTEXITCODE -ne 0) {
throw "WinGet exited with code $LASTEXITCODE."
}
if (-not (Test-Path $dockerDesktopPath)) {
throw 'Docker Desktop installation completed, but its executable was not found.'
}
Write-Ok 'Docker Desktop installed.'
}
$env:Path = [Environment]::GetEnvironmentVariable('Path', 'Machine') + ';' +
[Environment]::GetEnvironmentVariable('Path', 'User')
$docker = Get-Command docker.exe -ErrorAction SilentlyContinue
if (-not $docker) {
throw 'docker.exe is not on PATH. Open a new Administrator PowerShell and rerun the script.'
}
if ($env:DOCKER_HOST) {
Write-Warn2 "Ignoring DOCKER_HOST='$env:DOCKER_HOST' for this script."
Remove-Item Env:DOCKER_HOST
}
Write-Step 'Starting Docker Desktop'
& docker desktop start | Out-Host
Write-Step 'Selecting the Windows engine'
$engines = (& docker desktop engine ls 2>&1 | Out-String)
if ($engines -notmatch '(?m)^windows\s') {
Write-Host $engines
throw @'
Docker Desktop did not register a Windows engine. Check:
C:\ProgramData\DockerDesktop\install-settings.json
If it contains "noWindowsContainers": true, uninstall Docker Desktop and rerun this script.
'@
}
& docker desktop engine use windows | Out-Host
Wait-DockerServer -ExpectedOS windows
Write-Ok 'Docker is running the Windows engine.'
if ($SkipSmokeTest) {
Write-Warn2 'Smoke test skipped.'
return
}
Write-Step 'Running a disposable Nano Server smoke test'
& docker run --rm --isolation=hyperv `
mcr.microsoft.com/windows/nanoserver:ltsc2022 `
cmd.exe /S /C 'echo Hello from a Windows container & ver'
if ($LASTEXITCODE -ne 0) {
throw "Windows container smoke test exited with code $LASTEXITCODE."
}
Write-Ok 'Windows containers are working.'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment