Documentation Index
Fetch the complete documentation index at: https://tally.wharflab.com/llms.txt
Use this file to discover all available pages before exploring further.
This guide sets up a standalone BuildKit daemon for Windows containers and connects docker buildx to it with the remote driver.
It is based on a working setup validated on April 1, 2026 with real Windows container builds.
Known-good versions
containerd v1.7.30
buildkit v0.29.0
buildx v0.33.0
Do not use containerd v2.2.2 for this setup. In our Windows validation, buildkitd failed to start against it with:
unknown service containerd.services.leases.v1.Leases
Prerequisites
- Windows with Docker Desktop installed
- Docker Desktop switched to Windows containers
- An elevated PowerShell session
- Windows container prerequisites enabled (
Hyper-V, Windows Containers, and the default nat network)
Install standalone BuildKit
Run this in an elevated PowerShell window:
$ErrorActionPreference = 'Stop'
$containerdVersion = '1.7.30'
$buildkitVersion = 'v0.29.0'
$buildxVersion = 'v0.33.0'
$arch = 'amd64'
$temp = Join-Path $env:TEMP 'buildkit-win-upgrade'
New-Item -ItemType Directory -Force -Path $temp | Out-Null
Set-Location $temp
Write-Host 'Checking nat network...'
$nat = Get-HnsNetwork | Where-Object { $_.Name -eq 'nat' }
if ($null -eq $nat) {
throw "NAT network not found. Make sure Windows Containers / Hyper-V are enabled and Docker is in Windows containers mode."
}
$gateway = $nat.Subnets[0].GatewayAddress
$subnet = $nat.Subnets[0].AddressPrefix
Write-Host 'Installing CNI config...'
$cniConfPath = "$env:ProgramFiles\containerd\cni\conf"
$cniBinDir = "$env:ProgramFiles\containerd\cni\bin"
$cniVersion = '0.3.0'
New-Item -ItemType Directory -Force -Path $cniConfPath, $cniBinDir | Out-Null
curl.exe -fSL "https://github.com/microsoft/windows-container-networking/releases/download/v$cniVersion/windows-container-networking-cni-amd64-v$cniVersion.zip" -o "windows-container-networking-cni-amd64-v$cniVersion.zip"
tar.exe xvf "windows-container-networking-cni-amd64-v$cniVersion.zip" -C $cniBinDir
$natConfig = @"
{
"cniVersion": "$cniVersion",
"name": "nat",
"type": "nat",
"master": "Ethernet",
"ipam": {
"subnet": "$subnet",
"routes": [
{
"gateway": "$gateway"
}
]
},
"capabilities": {
"portMappings": true,
"dns": true
}
}
"@
Set-Content -Path "$cniConfPath\0-containerd-nat.conf" -Value $natConfig
Write-Host 'Installing containerd...'
curl.exe -fSL "https://github.com/containerd/containerd/releases/download/v$containerdVersion/containerd-$containerdVersion-windows-$arch.tar.gz" -o "containerd-$containerdVersion-windows-$arch.tar.gz"
tar.exe xvf "containerd-$containerdVersion-windows-$arch.tar.gz"
if (Get-Service containerd -ErrorAction SilentlyContinue) {
Stop-Service containerd -ErrorAction SilentlyContinue
.\bin\containerd.exe --unregister-service
}
.\bin\containerd.exe --register-service
Start-Service containerd
Write-Host 'Installing BuildKit...'
curl.exe -fSL "https://github.com/moby/buildkit/releases/download/$buildkitVersion/buildkit-$buildkitVersion.windows-$arch.tar.gz" -o "buildkit-$buildkitVersion.windows-$arch.tar.gz"
tar.exe xvf "buildkit-$buildkitVersion.windows-$arch.tar.gz"
$buildkitPath = "$env:ProgramFiles\buildkit"
New-Item -ItemType Directory -Force -Path $buildkitPath | Out-Null
Copy-Item -Path ".\bin\*" -Destination $buildkitPath -Force
if (Get-Service buildkitd -ErrorAction SilentlyContinue) {
Stop-Service buildkitd -ErrorAction SilentlyContinue
& "$buildkitPath\buildkitd.exe" --unregister-service
}
Write-Host 'Registering buildkitd service...'
& "$buildkitPath\buildkitd.exe" --register-service `
--addr "npipe:////./pipe/buildkitd" `
--containerd-cni-config-path="$cniConfPath\0-containerd-nat.conf" `
--containerd-cni-binary-dir="$cniBinDir"
Start-Service buildkitd
Write-Host 'Installing buildx plugin...'
$pluginsDir = "$env:USERPROFILE\.docker\cli-plugins"
New-Item -ItemType Directory -Force -Path $pluginsDir | Out-Null
curl.exe -fSL "https://github.com/docker/buildx/releases/download/$buildxVersion/buildx-$buildxVersion.windows-$arch.exe" -o "$pluginsDir\docker-buildx.exe"
Write-Host 'Waiting for buildkitd...'
for ($i = 0; $i -lt 30; $i++) {
Start-Sleep -Seconds 2
& "$buildkitPath\buildctl.exe" --addr "npipe:////./pipe/buildkitd" debug info *> $null
if ($LASTEXITCODE -eq 0) { break }
}
& "$buildkitPath\buildctl.exe" --addr "npipe:////./pipe/buildkitd" debug info
Write-Host 'Creating buildx builder...'
docker buildx rm buildkit-windows 2>$null
docker buildx create --name buildkit-windows --driver remote "npipe:////./pipe/buildkitd" --use
docker buildx inspect --bootstrap buildkit-windows
docker buildx version
Allow non-admin clients to use the BuildKit pipe
If buildctl works in the elevated shell but fails in a normal shell with Access is denied, re-register buildkitd like this:
Stop-Service buildkitd
& "$env:ProgramFiles\buildkit\buildkitd.exe" --unregister-service
& "$env:ProgramFiles\buildkit\buildkitd.exe" --register-service `
--addr "npipe:////./pipe/buildkitd" `
--group "Users" `
--containerd-cni-config-path="$env:ProgramFiles\containerd\cni\conf\0-containerd-nat.conf" `
--containerd-cni-binary-dir="$env:ProgramFiles\containerd\cni\bin"
Start-Service buildkitd
Verify the builder
Run these in a normal PowerShell session:
docker buildx version
docker buildx inspect buildkit-windows --bootstrap
& "$env:ProgramFiles\buildkit\buildctl.exe" --addr "npipe:////./pipe/buildkitd" debug info
Expected checks:
docker buildx version shows v0.33.0
docker buildx inspect buildkit-windows --bootstrap shows Driver: remote
- the node reports
BuildKit version: v0.29.0
buildctl debug info succeeds through \\.\pipe\buildkitd
Smoke test with a real Windows build
$testDir = Join-Path $env:TEMP 'buildkit-win-test'
New-Item -ItemType Directory -Force -Path $testDir | Out-Null
@'
FROM mcr.microsoft.com/windows/nanoserver:ltsc2025
RUN cmd /S /C echo upgraded-buildkit> C:\buildkit.txt
'@ | Set-Content -Path (Join-Path $testDir 'Dockerfile')
docker buildx build --builder buildkit-windows --platform windows/amd64 --progress plain --load -t bk-win-test $testDir
docker run --rm bk-win-test cmd /S /C type C:\buildkit.txt
If the setup is healthy, the container prints:
Troubleshooting
buildkitd fails to start with unknown service containerd.services.leases.v1.Leases
- You are likely using an incompatible
containerd version such as 2.2.2.
- Reinstall
containerd v1.7.30.
buildx inspect buildkit-windows --bootstrap times out
- Check that the
buildkitd service is running.
- Check that
buildctl debug info works from the same shell.
- If only the elevated shell works, re-register
buildkitd with --group "Users".
buildctl says Access is denied
- The named pipe permissions are too restrictive.
- Re-register
buildkitd with --group "Users" as shown above.
Windows build starts but fails during execution
- Make sure Docker Desktop is actually in Windows containers mode.
- Confirm the builder reports
Platforms: windows/amd64.
- Re-run the smoke test before debugging your own Dockerfile.