Run Windows Desktop inside a Docker Container with Dockur
I learned about an exciting project via an email from the developer. I would like to share a new project that allows you to run Windows inside a Docker container without jumping through a lot of hoops. What’s more, you can do this using a Linux Docker host with KVM installed. Let’s take a look at this really cool project in the following content to see how we can run Windows in this context.
Table of contents
- What is Dockurr?
- Prerequisites
- Install Kernel Virtual Machine (KVM)
- Pull down Dockurr in a container and spin up Windows in a Docker container
- Connecting RDP to Windows 11 desktop running in the container
- Running different Windows OS images in Docker
- Custom images
- Networking
- CPU and memory
- What use case does this solve?
- Different than traditional Windows containers
- Docker desktop is still a viable solution
- Wrapping up running Windows 11 Desktop in a Docker container
What is Dockurr?
It is a free and open-source project that allows running Windows client and Windows Server desktop installations inside a Docker container environment. It also allows you to do this on a Linux Docker host that would normally only be able to run Linux containers. Using KVM acceleration, it allows you to run Windows containers on a Linux container host without the need to install and start Docker Desktop or other compatibility issues that are typical with mixing OS’es between Linux and Windows.
You can find the project link to the official Github site here: dockur/windows: Windows in a Docker container. (github.com) .
Instead you can run Windows containers simultaneously with Linux containers using the solution after loading a Docker installation, Docker daemon, etc. Typically Docker Desktop is needed to run the Docker Engine and be able to run containers on Windows, or the reverse is true to run Linux on Windows, using something like WSL, WSL2, or Hyper-V.
It also provides a VNC connection to the container during the installation process. It also allows you to connect via Remote Desktop Protocol (RDP) to the Windows installation running in Docker.
What Windows distro configurations are supported?
- Windows 11 Pro
- Windows 10 Pro
- Windows 10 LTSC
- Windows 8.1 Pro
- Windows 7 SP1
- Windows Vista SP2
- Windows XP SP3
- Windows Server 2022
- Windows Server 2019
- Windows Server 2016
- Windows Server 2012 R2
- Windows Server 2008 R2
- Tiny 11 Core
- Tiny 11
- Tiny 10
Prerequisites
As mentioned, you will need:
- A Linux Docker host (so a Windows Docker host is not required)
- You will need to install Kernel Virtual Machine (KVM) on the Docker host
Install Kernel Virtual Machine (KVM)
First, let’s quickly look at installing Kernel Virtual Machine (KVM) that is used to run virtual machines. If you don’t have KVM installed and attempt to run the container, you will receive an error. I am using an Ubuntu Server 22.04 LTS machine running as a Virtual Machine with nested virtualization enabled on the VM, which allows you to enable hardware virtualization. However, you could use Debian, or another distribution that you like to work with.
Run the following from the command line to install KVM. Make sure you are root or in the sudo users permissions group.:
sudo apt install libvirt-clients libvirt-daemon-system libvirt-daemon virtinst bridge-utils qemu qemu-kvm
Pull down Dockurr in a container and spin up Windows in a Docker container
After installing KVM on our Linux Docker host, we can now spin up the Docker container calledย Dockurr, which uses the isolation of KVM. We can do this with some simple Docker compose code. When you spin up the default container configuration, it will pull a Windows 11 Docker image. Note the example Docker compose configuration below:
version: "3"
services:
windows:
image: dockurr/windows
container_name: windows
devices:
- /dev/kvm
cap_add:
- NET_ADMIN
ports:
- 8006:8006
- 3389:3389/tcp
- 3389:3389/udp
stop_grace_period: 2m
restart: on-failure
Below, we are running a docker-compose up -d command to bring up the container.
You an also use a docker run command from the docker CLI to pull the container down as well:
docker run -it --rm --name windows -p 8006:8006 --device=/dev/kvm --cap-add NET_ADMIN --stop-timeout 120 dockurr/windows
After you use the above commands to pull down the Dockurr solution, you can connect to the container on your container host by connecting to your container host in a browser on portย 8006ย for UI access.
You will see the following screens during the install. It will show that itis downloading the image and a few other things as it gets distracted.
The image will show it is downloading, and then extracting the files it needs for the installation in the background.
After the extraction is complete, it will show to be building.
Setup starts with Windows 11 and the order of step configuration below will be familiar.
You will see the normal Windows installation start in the web console.
You will see the installation begin automatically as it does when you have an unattend file, which is likely what is happening under the hood.
After the installation completes, it will automatically login using the docker username.
You may wonder which variant of Windows 11 is installed by default. From the Windows command prompt, you can run a winver command using Windows terminal and it looks to install Version 23H2 OS Build 22631.3155.
Connecting RDP to Windows 11 desktop running in the container
Now, we know we can connect using VNC over port 8006. Let’s see if we can connect using Remote Desktop Protocol (RDP).
Connect to the hostname or IP of your Docker host, port 3389. The login credentials are:
- username: docker
- password: {blank}
Running different Windows OS images in Docker
As mentioned at the outset, you can run a wide range of different Windows operating systems in this tool. How do you specify a different version of Windows to be used instead of the default Windows 11 image?
environment:
VERSION: "win11"
You can use the following designators in the environment variable to note which version of Windows you want to spin up (win11, win10, ltsc10, win7, etc) in the information list below:
win11 | Windows 11 Pro | Microsoft | Fast | 6.4 GB |
win10 | Windows 10 Pro | Microsoft | Fast | 5.8 GB |
ltsc10 | Windows 10 LTSC | Microsoft | Fast | 4.6 GB |
win81 | Windows 8.1 Pro | Microsoft | Fast | 4.2 GB |
win7 | Windows 7 SP1 | Bob Pony | Medium | 3.0 GB |
vista | Windows Vista SP2 | Bob Pony | Medium | 3.6 GB |
winxp | Windows XP SP3 | Bob Pony | Medium | 0.6 GB |
2022 | Windows Server 2022 | Microsoft | Fast | 4.7 GB |
2019 | Windows Server 2019 | Microsoft | Fast | 5.3 GB |
2016 | Windows Server 2016 | Microsoft | Fast | 6.5 GB |
2012 | Windows Server 2012 R2 | Microsoft | Fast | 4.3 GB |
2008 | Windows Server 2008 R2 | Microsoft | Fast | 3.0 GB |
core11 | Tiny 11 Core | Archive.org | Slow | 2.1 GB |
tiny11 | Tiny 11 | Archive.org | Slow | 3.8 GB |
tiny10 | Tiny 10 | Archive.org | Slow | 3.6 GB |
Custom images
In addition to the versions of Windows you can install by default, you can also use custom images for your Windows media. It is as easy as defining the web location of the Windows custom ISO like the following:
environment:
VERSION: "https://example.com/win.iso"
Networking
If you want to connect your Windows containers to a specific network in production, you can do this with some additional configuration. By default, the containers use bridged networking so that it uses the IP address of the Docker host. However, according to the documentation details, you can manually change this:
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
Then, you Docker compose file can use this new network by changing it like the following:
services:
windows:
container_name: windows
..<snip>..
networks:
vlan:
ipv4_address: 192.168.0.100
networks:
vlan:
external: true
CPU and memory
You can also configure the CPU and memory resources, using the following:
environment:
RAM_SIZE: "8G"
CPU_CORES: "4"
What use case does this solve?
In case you are wondering, where you would use this type of solution, running Windows inside a Docker container. It is true, we are adding a layer of complexity to the backend instead of just directly running Windows VMs by adding the Docker container layer on top of that.
However, I think this solution would be great for home labs or developers since it allows you to spin up Windows clients and servers very easily in running containers instead of having to provision full virtual machines. Now, granted, you can have a similar experience of easily provisioning Windows virtual machines with something like Packer and Terraform or provisioning using PowerShell.
But, the containers make this even easier. Also, by using Docker containers for the Windows environments, you are saving a considerable amount of disk space for each new virtual machine you spin up, since they are sharing the Windows image.
Different than traditional Windows containers
As noted, we are using a Linux container host, so we are not using a Windows Server to run Windows containers. Windows containers allow you to containerize Windows-based applications in the same way as Linux applications.
Docker provides the following packaged components for your applications: code, runtime, system tools, libraries, and settings. Since it uses traditional Docker technologies, Windows containers must be run on a Windows Docker host.
Keep in mind too, these are not Windows containers that run the Windows desktop. These are generally Windows Server Core images that run Windows applications which can be pulled from the Microsoft repository.
Docker desktop is still a viable solution
Docker Desktop for Windows is an application that leverages Dockerโs technology to deploy and manage containers on a Windows 10 or Windows 11 system. It integrates easily with your operating system, allowing you to run both Linux and Windows containers.
Installing Docker Desktop is straightforward. You just download the installer from the Docker Hub website. Once downloaded, run the installer and follow the on-screen instructions. If you run into issues with installing or running Docker Desktop, check out my blog post guide here on Docker Desktop.
Wrapping up running Windows 11 Desktop in a Docker container
Running Windows inside Docker containers can have enormous benefits for spinning up multiple virtual machines for lab environments, development, training scenarios, or other use cases. Using KVM underneath the hood, the performance is good since it is true virtualization and not just emulation. The benefits of containerization for Windows-based applications can help with increased productivity, easier scalability, and consistent operating environments for software development and deployment.
In this article, we have seen how the Dockurr solution allows running Windows desktop environments using Docker containers. It is easy to get started using and managing Windows desktops in this way. This could be a viable alternative to running Kubevirt on top of Kubernetes as it has many features and is perfectly legal since it makes use of Microsoft’s trial software. Let me know your feedback in the comments, or post a new thread in the VHT forums.
Do you know if it is possible to transfer the GPU to a Windows 11 container?
Ismar,
Thanks for the comment! That is an interesting question. I am assuming since this is also utilizing KVM that it is possible. I will speak with the developer and see the possibilities there.
Brandon
Trying this dockurr for ourselves but when windows 11 setup starts it is extremely slow. Waiting to see how it proceeds.
Lars,
I found it to be a little slower than booting from an ISO and such as well. However, still pretty cool to be able to run Windows 11 in a dockerized fashion and other Windows client and Server OS’es. Have you ran into any other issues with it so far?
Brandon
When trying to use
environment:
VERSION: “2022”
Windows 11 starts up instead of Windows 2022 being pulled.
Now trying VERSION: “win10” to see how that goes.
We had to remove the windows 11 container complely using rm
because when we ran the docker compose and changed to another windows OS, windows 11 would run not the other OS.
So is this the case that only one container can exist?
Thanks.
Lars,
Thanks for letting me know how things are going in your testing. I have found some quirks as well. Have you ran Server OS’es as of yet?
Brandon
Tried Windows Server 2022 and it installed fast and was quite responsive.
One other thing:
We had to remove the windows 11 container complely using rm
because when we ran the docker compose and changed to another windows OS, windows 11 would run not the other OS.
So is this the case that only one container can exist at a time?
When we add the following to the Docker compose file
environment:
VERSION: “win11”
We get an error about no mapping.
Please advise?
Thank you.
Claire,
Thank you for the comment! Actually you don’t need to add win11 as an environment variable. I am not sure why this variable is listed in the documentation to be honest. If you simply use the default Docker compose code I show, it will pull down Windows 11. Try that and let me know what you find.
Thanks again!
Brandon
We had to remove the windows 11 container complely using rm
because when we ran the docker compose and changed to another windows OS, windows 11 would run not the other OS.
So is this the case that only one container can exist at a time?
Thanks.
I am not the best with yml and I am trying to get win11 to pull a dhcp address from my home network and following the git documentation that says it is possible spits out an error. Here is the error and below is the docker-compose file:
Error
sudo docker compose up -d
validating /home/jamie/docker-win/docker-compose.yml: (root) Additional property devices is not allowed
or device_cgroup_rules or environment for additional properties
File
version: “3”
services:
windows:
image: dockurr/windows
environment:
DHCP: “Y”
devices:
– /dev/vhost-net
#- /dev/kvm
device_cgroup_rules:
– ‘c : rwm’
container_name: windows
cap_add:
– NET_ADMIN
ports:
– 8006:8006
– 3388:3389/tcp
– 3388:3389/udp
stop_grace_period: 2m
restart: on-failure
networks:
win-vlan:
ipv4_address: 192.168.0.100
networks:
win-vlan:
external: true
Am I adding environment,devices,device_cgroup_rules in the correct place? I tried them at the root as well but no joy.
Tried Windows Server 2022 and it installed fast and was quite responsive.
One other thing:
We had to remove the windows 11 container complely using rm
because when we ran the docker compose and changed to another windows OS, windows 11 would run not the other OS.
So is this the case that only one container can exist at a time?
Lars,
Great to note! I am finding several limitations myself. I am going to see if there is a way around this.
Brandon
Appreciate your response. Cheers!
would it work to run Windows containers on a K8S Linux node?
Marcel,
I think in that case it would be more efficient to use something like Kubevirt, since you would benefit from the automation that Kubernetes provides.
Brandon