🌐 Language
English | 简体中文 | 繁體中文 | 日本語 | 한국어 | हिन्दी | ไทย | Français | Deutsch | Español | Italiano | Русский | Português | Nederlands | Polski | العربية | فارسی | Türkçe | Tiếng Việt | Bahasa Indonesia | অসমীয়া
# 💻 Windows in Docker Container Discover an innovative and efficient method of deploying Windows OS (x64) on your linux system using the power of Vagrant VM, libvirt, and docker-compose. Together, these technologies help you containerize Windows OS, enabling you to manage a Windows instance just as you would any Docker container. This seamless integration into existing workflows significantly enhances convenience and optimizes resource allocation. ⭐ **Don't forget to star the project if it helped you!** ## 📋 Prerequisites Ensure your system meets the following requirements: - **Docker:** Version 20 or higher [(Install Docker)](https://www.docker.com/) - **Host OS:** Linux - **Virtualization Enabled:** - Check with: - `lscpu | grep -i Virtualization` - Output indicates: - `VT-x` → Intel virtualization is supported & enabled. - `AMD-V` → AMD virtualization is supported & enabled. - If virtualization is not enabled, enable it in the BIOS/UEFI settings. - **`cgroup: host`** in the compose file is required: libvirt and the daemons it spawns need full cgroup access, otherwise the container fails to start on cgroup v2 hosts. ## 🚀 Deployment Guide 1. Create/Update the environmental file `.env` ``` # Vagrant image settings MEMORY=8000 # MiB (~8 GB) CPU=4 DISK_SIZE=100 # GiB ``` 2. Create `docker-compose.yml` ```yaml services: win10: image: docker.io/vaggeliskls/windows-in-docker-container:latest platform: linux/amd64 env_file: .env stdin_open: true tty: true privileged: true cgroup: host restart: always ports: - 3389:3389 - 2222:2222 ``` 3. Create `docker-compose.override.yml` when you want your VM to be persistent ```yaml services: win10: volumes: - libvirt_data:/var/lib/libvirt - vagrant_data:/root/.vagrant.d - vagrant_project:/app/.vagrant - libvirt_config:/etc/libvirt volumes: libvirt_data: name: libvirt_data vagrant_data: name: vagrant_data vagrant_project: name: vagrant_project libvirt_config: name: libvirt_config ``` 4. Run: `docker compose up -d` > **First boot takes several minutes** — the Vagrant box is already baked into the image, but the VM still has to boot and run the provisioning script (Chocolatey install, disk resize, registry tweaks). Follow progress with `docker compose logs -f`. > When you want to destroy everything `docker compose down -v` ![windows screenshot](https://github.com/vaggeliskls/windows-in-docker-container/blob/main/images/screen-1.png?raw=true ) ## 🌐 Access ### Remote Desktop (RDP) For debugging or testing, you can connect to the VM using **Remote Desktop** on port `3389`. #### Software for Remote Desktop Access | OS | Software | |----------|----------------| | **Linux** | [`rdesktop`](https://github.com/rdesktop/rdesktop) → `rdesktop :3389` or [`Remmina`](https://remmina.org/) | | **MacOS** | [Microsoft Remote Desktop](https://apps.apple.com/us/app/microsoft-remote-desktop/id1295203466?mt=12) | | **Windows** | Built-in **Remote Desktop Connection** | --- ### SSH You can connect via SSH using either the **administrator** or **Vagrant** user credentials. ```bash ssh @ -p 2222 ``` ## 🔑 User Login Default users based on the Vagrant image are: 1. Administrator - Username: Administrator - Password: vagrant 2. User - Username: vagrant - Password: vagrant ## ⚠️ Limitations - **Linux host only** — depends on `/dev/kvm` and libvirt; macOS and Windows hosts are not supported. - **Eval license** — the underlying box ships an evaluation copy of Windows Server 2022. Activation expires per Microsoft's eval terms. - **No synced folders** — `rsync`, `smb`, and `nfs` are all unwired in the [Vagrantfile](Vagrantfile) (rsync needs a Windows-side install before provisioning runs; SMB synced folders aren't supported with a Linux host; in-container NFS hits `no support in current kernel`). - **Performance** — without nested KVM available to Docker (e.g. on a cloud VM that doesn't expose KVM), the guest falls back to plain QEMU and is several times slower. ## 🔧 Troubleshooting - **`KVM acceleration is not available`** in logs → the host isn't exposing `/dev/kvm`. Check virtualization is enabled in BIOS, the `kvm` module is loaded (`lsmod | grep kvm`), and `/dev/kvm` exists on the host. The startup script falls back to QEMU automatically; expect a large slowdown. - **Port 3389 / 2222 already in use** → another RDP/SSH service is bound on the host. Stop it, or change the host-side port mapping in `docker-compose.yml`. - **Container exits immediately** → almost always a cgroup or privilege problem. Confirm `privileged: true` and `cgroup: host` are set, then check `docker compose logs win10`. - **`vagrant up` hangs at "Waiting for domain to get an IP address"** → libvirt's default NAT network isn't running. Restart the container, or run `virsh net-start default` from inside it. ## 📚 Further Reading and Resources - [Windows Vagrant Tutorial](https://github.com/SecurityWeekly/vulhub-lab) - [Vagrant image: peru/windows-server-2022-standard-x64-eval](https://app.vagrantup.com/peru/boxes/windows-server-2022-standard-x64-eval) - [Vagrant by HashiCorp](https://www.vagrantup.com/) - [Windows Virtual Machine in a Linux Docker Container](https://medium.com/axon-technologies/installing-a-windows-virtual-machine-in-a-linux-docker-container-c78e4c3f9ba1) - [GPU inside a container](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html)