Windows Server Core in a container — zero-touch install, KVM-accelerated, ready to SSH in minutes.
Windows Server Core in a container — zero-touch install, KVM-accelerated, ready to SSH in minutes.
Out of the box, the VM comes pre-configured with:
git clone and start coding inside it./run.sh --reset reverts the VM to its post-install state in secondsZ:\ in the guest (via WinFsp)undefinedNote: Linux is the primary and well-tested platform. macOS support is experimental and unstable — expect slower builds (no KVM) and missing features (no VirtIO-FS shared directories).
build.sh auto-detects which is availablegenisoimage — for generating the answer ISOvirtiofsd — for shared directory support (VirtIO-FS)# Debian/Ubuntu
sudo apt install qemu-system-x86 genisoimage virtiofsd
# Fedora
sudo dnf install qemu-system-x86-core genisoimage virtiofsd
# Arch
sudo pacman -S qemu-system-x86 cdrtools virtiofsd
mkisofs for ISO generation)virtiofsd is Linux-only)brew install qemu cdrtools
.env with your Windows ISO URL:undefinedcp .env.example .env
# Edit .env — set WIN_ISO_URL to a Windows Server ISO (URL or local path)
# Get a free evaluation ISO from https://www.microsoft.com/en-us/evalcenter/evaluate-windows-server
./build.sh
This auto-detects the best build method: if QEMU is installed locally, it runs directly on the host; otherwise it builds and runs a Docker container. KVM is used when available (/dev/kvm), otherwise falls back to software emulation.
You can force a specific mode:
./build.sh --host # Force host QEMU build
./build.sh --docker # Force Docker build
localhost:5900 (macOS opens Screen Sharing automatically; Linux uses vncviewer)http://localhost:16080 (Linux with noVNC installed)ssh administrator@localhost -p 2222localhost:13389All ports are bound to 127.0.0.1 (localhost only).
All settings are in .env (see .env.example):
| Variable | Default | Description |
|---|---|---|
WIN_ISO_URL |
(required) | Windows ISO URL or local file path |
WIN_ISO_SHA256 |
(empty) | SHA256 checksum for ISO verification |
WIN_PRODUCT_KEY |
(empty) | Product key (eval key used if empty) |
WIN_ADMIN_PASSWORD |
P@ssw0rd! |
Administrator password |
WIN_HOSTNAME |
WINCORE |
VM hostname |
WIN_TIMEZONE |
UTC |
Windows timezone |
DISK_SIZE |
60G |
Virtual disk size |
RAM_MB |
4096 |
VM RAM in MB |
CPU_CORES |
2 |
VM CPU cores |
VNC_DISPLAY |
:0 |
VNC display number |
HOST_RDP_PORT |
13389 |
Host port for RDP |
HOST_SSH_PORT |
2222 |
Host port for SSH |
HOST_NOVNC_PORT |
16080 |
Host port for noVNC web console |
SHARED_DIR |
./shared |
Host directory shared into guest as Z:\ |
SSH_PUBKEY |
(empty) | Path to SSH public key for passwordless login |
The shared/ directory on the host is mounted as Z:\ inside the guest via VirtIO-FS — no network or SCP needed to pass files in and out. Just drop files into ./shared/ and they appear instantly at Z:\ in the VM.
echo "hello from host" > shared/test.txt
ssh administrator@localhost -p 2222 "type Z:\test.txt"
Set SHARED_DIR in .env to change the host path.
undefinedNote: VirtIO-FS requires
virtiofsd, which is Linux-only. On macOS, shared directories are not available — use SCP or RDP file transfer instead.
After a fresh install, the build automatically creates a qcow2 overlay on top of the base disk. All runtime changes go to the overlay while the base image stays pristine.
# Quick-start the VM (boots from overlay)
./run.sh
# Discard all changes and revert to post-install state
./run.sh --reset
The overlay is a thin qcow2 file backed by the base disk — creating or resetting it is instant.
The images/ directory holds the virtual disk, overlay, and downloaded ISOs. In Docker mode, it’s automatically volume-mounted so artifacts persist across container restarts.
To force a clean reinstall (wipes base disk + overlay):
./build.sh --clean
This wipes the virtual disk, overlay, and regenerated config, but preserves downloaded ISOs. Can be combined with --host/--docker.
The build is tuned for fast installation:
cache=unsafe and aio=io_uring (Linux) / aio=threads (macOS) — dramatically faster I/O than IDE during Windows file extractionreagentc /disable during specialize skips RE partition/ResetBase — reclaims ~1.3 GBvirtiofsd (Linux only) — near-native shared filesystem via vhost-user-fs-pci and shared memory (memfd)virtiofs.exe requires WinFsp DLL)During installation you can watch progress via the noVNC web console (opens automatically) or any VNC client on port 5900. The post-install steps show status in the PowerShell window title (e.g. [3/12] Installing OpenSSH Server). Detailed logs are written to C:\setup.log inside the VM.
We use cookies
We use cookies to analyze traffic and improve your experience. You can accept or reject analytics cookies.