Containers

Run Windows Desktop inside a Docker Container with Dockur

Learn how to run Windows Desktop inside a Docker container effortlessly. Learn how to set up Windows client and Windows Server installations on a Linux Docker host.

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.

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. 

Dockur allows running windows desktops in docker on linux docker hosts
Dockurr allows running windows desktops in docker on linux docker hosts

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?

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
Installing kvm in ubuntu server
Installing kvm in ubuntu server

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
Docker compose code for dockur
Docker compose code for dockurr

Below, we are running a docker-compose up -d command to bring up the container.

Bringing up the docker container
Bringing up the docker 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
Viewing the dockur container running
Viewing the dockurr container running

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.

Extracting the windows 11 image
Extracting the windows 11 image

After the extraction is complete, it will show to be building.

Building windows 11 image
Building windows 11 image

Setup starts with Windows 11 and the order of step configuration below will be familiar.

Setup starts for windows
Setup starts for windows

You will see the normal Windows installation start in the web console.

Copying windows files
Copying windows files

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.

Getting files ready for installation
Getting files ready for installation

After the installation completes, it will automatically login using the docker username.

Windows desktop in docker
Windows desktop in docker

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.

Viewing the windows 11 version with winver
Viewing the windows 11 version with winver

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}
Rdping into the docker container
Rdping into the docker container

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:

win11Windows 11 ProMicrosoftFast6.4 GB
win10Windows 10 ProMicrosoftFast5.8 GB
ltsc10Windows 10 LTSCMicrosoftFast4.6 GB
win81Windows 8.1 ProMicrosoftFast4.2 GB
win7Windows 7 SP1Bob PonyMedium3.0 GB
vistaWindows Vista SP2Bob PonyMedium3.6 GB
winxpWindows XP SP3Bob PonyMedium0.6 GB
2022Windows Server 2022MicrosoftFast4.7 GB
2019Windows Server 2019MicrosoftFast5.3 GB
2016Windows Server 2016MicrosoftFast6.5 GB
2012Windows Server 2012 R2MicrosoftFast4.3 GB
2008Windows Server 2008 R2MicrosoftFast3.0 GB
core11Tiny 11 CoreArchive.orgSlow2.1 GB
tiny11Tiny 11Archive.orgSlow3.8 GB
tiny10Tiny 10Archive.orgSlow3.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.

Docker desktop installation process
Docker desktop installation process

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.

Subscribe to VirtualizationHowto via Email 🔔

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Brandon Lee

Brandon Lee is the Senior Writer, Engineer and owner at Virtualizationhowto.com and has over two decades of experience in Information Technology. Having worked for numerous Fortune 500 companies as well as in various industries, Brandon has extensive experience in various IT segments and is a strong advocate for open source technologies. Brandon holds many industry certifications, loves the outdoors and spending time with family.

Related Articles

17 Comments

    1. 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

  1. Trying this dockurr for ourselves but when windows 11 setup starts it is extremely slow. Waiting to see how it proceeds.

    1. 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

      1. 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.

      2. 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.

          1. 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?

  2. When we add the following to the Docker compose file
    environment:
    VERSION: “win11”
    We get an error about no mapping.
    Please advise?

    Thank you.

    1. 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

      1. 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.

  3. 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.

  4. 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?

    1. 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

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.