Running Windows in a Docker Container? This 50K-Star Project Makes the Impossible Possible
Explore how dockur/windows brings full Windows OS into Docker containers with KVM acceleration, automated installation, and dual-mode remote access. Perfect for testing environments and legacy app support.

Running Full Windows in a Docker Container? This Project Blew My 8-Year Coding Mind!
As a Java veteran tortured by the Spring ecosystem for years, I've seen countless "containerize everything" projects. But when I first stumbled upon dockur/windows, I had to rub my eyes – this thing actually shoves a complete Windows system into a Docker container? Aren't containers supposed to be lightweight and fast-starting? Now they're cramming in multi-GB operating systems? This is like trying to fit an elephant into a refrigerator in three steps.
What Pain Points Does This Thing Actually Solve?
Imagine this scenario: You're leading a testing team needing an isolated environment to run some Windows-only legacy app. Traditional solution? Spin up a VM – slow startup, heavy resource usage, and manual configuration galore. With this project, just one docker run command gives you a ready-to-use Windows environment in minutes.
Or say you're a security researcher frequently creating/destroying clean Windows environments for vulnerability testing. This project lets you manage Windows instances like regular containers – start, stop, delete, even orchestrate multiple Windows nodes with Kubernetes. An experience previously unimaginable.
Technically speaking, this isn't truly "containerizing" Windows (Windows and Linux kernels are entirely different beasts). Instead, it cleverly runs a lightweight KVM virtual machine inside the container, accessible via web interface or RDP. Think of it as Russian nesting dolls: Docker container holds QEMU/KVM, KVM runs Windows, and your browser displays the VM's desktop.
The Brilliance of Architecture Design: Automation That Makes You Doubt Reality
After dissecting this project's implementation, what impressed me most wasn't the technology itself, but how it simplifies complex processes. The entire installation is fully automated – from container startup to Windows desktop access, zero manual intervention required.
Core Startup Configuration Example:
yaml
services:
windows:
image: dockurr/windows
container_name: windows
environment:
VERSION: "11"
devices:
- /dev/kvm
- /dev/net/tun
cap_add:
- NET_ADMIN
ports:
- 8006:8006
- 3389:3389/tcp
- 3389:3389/udp
volumes:
- ./windows:/storage
restart: always
stop_grace_period: 2m
This configuration hides several critical details:
-
/dev/kvm Device Passthrough: Performance's core. KVM (Kernel-based Virtual Machine) is Linux's virtualization module. Without it, VM performance would be disastrous. The host must support and enable KVM – why it won't run on macOS or non-virtualized environments.
-
Dual 3389 Ports: One TCP, one UDP – standard for Windows RDP (Remote Desktop Protocol). While the project provides a web interface on port 8006 for installation/emergency access, official docs recommend native RDP clients for actual work – the experience is leagues better.
-
stop_grace_period Set to 2 Minutes: Often overlooked. Normal containers stop in seconds, but here we allow two minutes because it's running a full OS. Windows needs graceful shutdown time. Kill the process directly? Next boot might encounter disk corruption – I've fallen into this trap for you all.
Quick CLI Startup:
bash
docker run -it --rm --name windows -e "VERSION=11" -p 8006:8006 \
--device=/dev/kvm --device=/dev/net/tun --cap-add NET_ADMIN \
-v "${PWD:-.}/windows:/storage" --stop-timeout 120 \
docker.io/dockurr/windows
Behind this command lies complexity: Downloads Windows ISO (Win11 defaults to 7.2GB), auto-partitions, installs drivers, configures networking, creates users. Finally, visit http://127.0.0.1:8006 to see the installing or ready desktop.
Customization Dimensions: Change Whatever You Want
This project's flexibility stunned even me, an old backend developer. Nearly every parameter adjusts via environment variables – no image modification or rebuild needed.
Multi-Version Support & Environment Variables:
yaml
environment:
VERSION: "11e" # Windows 11 Enterprise
DISK_SIZE: "256G" # Expand disk to 256GB
RAM_SIZE: "8G" # Allocate 8GB RAM
CPU_CORES: "4" # 4 CPU cores
USERNAME: "bill"
PASSWORD: "gates"
LANGUAGE: "Chinese" # Chinese version
Supports versions from antique Windows 2000 to latest Windows 11, plus various Windows Server editions. Curiously checking sizes, I found Windows 11 LTSC (Long-Term Servicing Channel) is 2.5GB smaller than regular – great news for resource-tight scenarios.
Advanced Networking - Macvlan Independent Network:
bash
docker network create -d macvlan \
--subnet=192.168.0.0/24 \
--gateway=192.168.0.1 \
--ip-range=192.168.0.100/28 \
-o parent=eth0 vlan
yaml
services:
windows:
networks:
vlan:
ipv4_address: 192.168.0.100
networks:
vlan:
external: true
This config gives your Windows container a real LAN IP like a physical machine. Other devices access it directly without port mapping. Watch out: Docker host can't access macvlan containers by default – create a second macvlan network as bridge if needed.
Disk Passthrough & Multi-Disk Expansion:
yaml
environment:
DISK2_SIZE: "32G"
DISK3_SIZE: "64G"
volumes:
- ./example2:/storage2
- ./example3:/storage3
yaml
devices:
- /dev/sdb:/disk1
- /dev/sdc1:/disk2
Multi-disk setups suit storage-heavy scenarios. Disk passthrough goes further – mount host's physical disks/partitions directly, offering far better performance than virtual disks.
OEM Script Automation for Post-Install Configuration:
yaml
volumes:
- ./example:/oem
This feature is my favorite. Place an install.bat script and installers in ./example – the container auto-executes after OS installation. Imagine preloading dev tools, configuring environment variables, adjusting system settings. Every startup delivers identical environments – perfect for automated testing.
Performance: Not as Bad as Imagined, But Can't Replace Physical Machines
As someone particular about performance, I investigated this project's limits.
Official docs emphasize host KVM support – performance's key. With KVM enabled, VM CPU/memory access nears native performance, though disk/network incur overhead.
Reviewing user feedback:
- CPU-Intensive Tasks: Solid, reaches 85-90% native performance
- GUI: Web interface (port 8006) shows mediocre quality/high latency, but RDP flows smoothly – sufficient for daily office apps
- Disk I/O: Default virtual disks show average performance; disk passthrough reaches 50-66% native performance
- Network Throughput: Bridge mode is average, macvlan improves somewhat – overall unsuitable for high-throughput network projects