mirror of
https://github.com/dockur/windows.git
synced 2026-02-04 07:59:43 +00:00
Cache downloaded ISOs so new instances of the same Windows version skip the 3-6 GB download. Adds `winctl cache` subcommands (save/list/rm/flush) and auto-restores cached ISOs when creating new instances with --new. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1242 lines
27 KiB
Markdown
1242 lines
27 KiB
Markdown
# winctl.sh User Guide
|
|
|
|
A comprehensive guide to managing Windows Docker containers with `winctl.sh`.
|
|
|
|
## Table of Contents
|
|
|
|
- [Overview](#overview)
|
|
- [Prerequisites](#prerequisites)
|
|
- [Quick Start](#quick-start)
|
|
- [Commands Reference](#commands-reference)
|
|
- [Snapshots & Restore](#snapshots--restore)
|
|
- [Multi-Instance Support](#multi-instance-support)
|
|
- [ISO Cache](#iso-cache)
|
|
- [Configuration](#configuration)
|
|
- [ARM64 Setup](#arm64-setup)
|
|
- [Interactive Menus](#interactive-menus)
|
|
- [Common Scenarios](#common-scenarios)
|
|
- [Troubleshooting](#troubleshooting)
|
|
- [Tips & Tricks](#tips--tricks)
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
`winctl.sh` is a management script for running Windows virtual machines inside Docker containers. It provides:
|
|
|
|
- **22 Windows versions** from Windows 2000 to Windows 11
|
|
- **Simple commands** to start, stop, and manage containers
|
|
- **Interactive menus** when you don't specify a version
|
|
- **Snapshot & restore** for backing up and restoring VM data
|
|
- **LAN IP detection** with remote access URLs shown automatically
|
|
- **Port conflict detection** before starting containers
|
|
- **Disk usage monitoring** with per-VM and snapshot breakdowns
|
|
- **Status caching** for fast performance
|
|
- **Resource profiles** optimized for modern and legacy systems
|
|
- **ARM64 auto-detection** with architecture-aware image selection and version filtering
|
|
|
|
### Supported Windows Versions
|
|
|
|
| Category | Versions |
|
|
|----------|----------|
|
|
| **Desktop** | win11, win11e, win11l, win10, win10e, win10l, win81, win81e, win7, win7e |
|
|
| **Legacy** | vista, winxp, win2k |
|
|
| **Server** | win2025, win2022, win2019, win2016, win2012, win2008, win2003 |
|
|
| **Tiny** | tiny11, tiny10 |
|
|
|
|
### ARM64 Support
|
|
|
|
The script auto-detects your CPU architecture. On ARM64 systems (e.g., Apple Silicon, Ampere), only the following versions are supported:
|
|
|
|
| Version | Name |
|
|
|---------|------|
|
|
| win11 | Windows 11 Pro |
|
|
| win11e | Windows 11 Enterprise |
|
|
| win11l | Windows 11 LTSC |
|
|
| win10 | Windows 10 Pro |
|
|
| win10e | Windows 10 Enterprise |
|
|
| win10l | Windows 10 LTSC |
|
|
|
|
To run on ARM64, set the Docker image in your `.env.modern` file:
|
|
|
|
```bash
|
|
WINDOWS_IMAGE=dockurr/windows-arm
|
|
```
|
|
|
|
The `winctl.sh list` command shows `[x86 only]` tags on ARM64 for unsupported versions, and `winctl.sh start` blocks unsupported versions with a clear error message.
|
|
|
|
### Port Mappings
|
|
|
|
Each version has unique ports to avoid conflicts:
|
|
|
|
| Version | Web UI | RDP | Version | Web UI | RDP |
|
|
|---------|--------|-----|---------|--------|-----|
|
|
| win11 | 8011 | 3311 | win2025 | 8025 | 3325 |
|
|
| win10 | 8010 | 3310 | win2022 | 8022 | 3322 |
|
|
| win81 | 8008 | 3308 | win2019 | 8019 | 3319 |
|
|
| win7 | 8007 | 3307 | win2016 | 8016 | 3316 |
|
|
| vista | 8006 | 3306 | win2012 | 8112 | 3212 |
|
|
| winxp | 8005 | 3305 | win2008 | 8108 | 3208 |
|
|
| win2k | 8000 | 3300 | win2003 | 8003 | 3303 |
|
|
| tiny11 | 8111 | 3111 | tiny10 | 8110 | 3110 |
|
|
|
|
---
|
|
|
|
## Prerequisites
|
|
|
|
### Required
|
|
|
|
1. **Docker** - Container runtime
|
|
2. **Docker Compose** - Container orchestration (plugin or standalone)
|
|
3. **KVM** - Hardware virtualization for near-native performance
|
|
|
|
### Check Prerequisites
|
|
|
|
Run the built-in check:
|
|
|
|
```bash
|
|
./winctl.sh check
|
|
```
|
|
|
|
Example output:
|
|
```
|
|
Prerequisites Check
|
|
────────────────────────────────────────────────────────────
|
|
[OK] Docker is available
|
|
[OK] Docker Compose plugin is available
|
|
[OK] KVM is available
|
|
[OK] TUN device is available
|
|
[OK] Memory OK: 16GB available (8GB needed)
|
|
[OK] Disk space OK: 500GB available (128GB needed)
|
|
|
|
[OK] All critical prerequisites passed!
|
|
Architecture: amd64
|
|
LAN IP: 192.168.1.100
|
|
```
|
|
|
|
On ARM64, the output also shows:
|
|
```
|
|
Architecture: arm64
|
|
ARM64 image: dockurr/windows-arm
|
|
Supported: win11 win11e win11l win10 win10e win10l
|
|
LAN IP: 192.168.1.100
|
|
```
|
|
|
|
### Fix Common Issues
|
|
|
|
**KVM not accessible:**
|
|
```bash
|
|
sudo usermod -aG kvm $USER
|
|
newgrp kvm # or log out and back in
|
|
```
|
|
|
|
**Docker not running:**
|
|
```bash
|
|
sudo systemctl start docker
|
|
```
|
|
|
|
---
|
|
|
|
## Quick Start
|
|
|
|
### 1. Start a Windows VM
|
|
|
|
```bash
|
|
# Start Windows 11
|
|
./winctl.sh start win11
|
|
|
|
# Or use interactive menu
|
|
./winctl.sh start
|
|
```
|
|
|
|
### 2. Access the VM
|
|
|
|
After starting, you'll see connection details:
|
|
|
|
```
|
|
Connection Details:
|
|
→ Web Viewer: http://localhost:8011
|
|
→ RDP: localhost:3311
|
|
→ LAN Web: http://192.168.1.100:8011
|
|
→ LAN RDP: 192.168.1.100:3311
|
|
```
|
|
|
|
- **Web Viewer**: Open in browser for quick access
|
|
- **RDP**: Use any RDP client for better performance
|
|
- **LAN URLs**: Shown automatically when a LAN IP is detected — use these to access from other devices on your network
|
|
|
|
### 3. Check Status
|
|
|
|
```bash
|
|
./winctl.sh status
|
|
```
|
|
|
|
### 4. Stop the VM
|
|
|
|
```bash
|
|
./winctl.sh stop win11
|
|
```
|
|
|
|
---
|
|
|
|
## Commands Reference
|
|
|
|
### start
|
|
|
|
Start one or more containers.
|
|
|
|
```bash
|
|
# Start single version
|
|
./winctl.sh start win11
|
|
|
|
# Start multiple versions
|
|
./winctl.sh start win11 win10 winxp
|
|
|
|
# Interactive menu (no version specified)
|
|
./winctl.sh start
|
|
```
|
|
|
|
**What it does:**
|
|
1. Checks prerequisites (Docker, KVM)
|
|
2. Detects architecture and blocks unsupported versions on ARM64
|
|
3. Verifies ports are not already in use
|
|
4. Creates data directory if missing
|
|
5. Checks available resources
|
|
6. Starts the container
|
|
7. Shows connection details (including LAN URLs)
|
|
|
|
---
|
|
|
|
### stop
|
|
|
|
Stop containers with a 2-minute grace period for clean shutdown.
|
|
|
|
```bash
|
|
# Stop single version
|
|
./winctl.sh stop win11
|
|
|
|
# Stop multiple versions
|
|
./winctl.sh stop win11 win10
|
|
|
|
# Stop all running containers
|
|
./winctl.sh stop all
|
|
|
|
# Interactive menu
|
|
./winctl.sh stop
|
|
```
|
|
|
|
**Note:** You'll be asked to confirm before stopping.
|
|
|
|
---
|
|
|
|
### restart
|
|
|
|
Restart containers.
|
|
|
|
```bash
|
|
./winctl.sh restart win11
|
|
```
|
|
|
|
---
|
|
|
|
### status
|
|
|
|
Show status of containers.
|
|
|
|
```bash
|
|
# All containers
|
|
./winctl.sh status
|
|
|
|
# Specific versions
|
|
./winctl.sh status win11 win10
|
|
```
|
|
|
|
Example output:
|
|
```
|
|
VERSION NAME STATUS WEB RDP
|
|
──────────────────────────────────────────────────────────────────
|
|
win11 Windows 11 Pro running 8011 3311
|
|
win10 Windows 10 Pro stopped 8010 3310
|
|
winxp Windows XP Professional not created 8005 3305
|
|
|
|
LAN IP: 192.168.1.100 — use http://192.168.1.100:<web-port> for remote access
|
|
```
|
|
|
|
---
|
|
|
|
### logs
|
|
|
|
View container logs.
|
|
|
|
```bash
|
|
# View logs
|
|
./winctl.sh logs win11
|
|
|
|
# Follow logs in real-time
|
|
./winctl.sh logs win11 -f
|
|
```
|
|
|
|
Press `Ctrl+C` to stop following logs.
|
|
|
|
---
|
|
|
|
### shell
|
|
|
|
Open an interactive bash shell inside the container.
|
|
|
|
```bash
|
|
./winctl.sh shell win11
|
|
```
|
|
|
|
Useful for debugging or accessing container internals.
|
|
|
|
---
|
|
|
|
### stats
|
|
|
|
Show real-time resource usage (CPU, memory, network).
|
|
|
|
```bash
|
|
# All running containers
|
|
./winctl.sh stats
|
|
|
|
# Specific containers
|
|
./winctl.sh stats win11 win10
|
|
```
|
|
|
|
Press `Ctrl+C` to exit.
|
|
|
|
---
|
|
|
|
### build
|
|
|
|
Build the Docker image locally from source.
|
|
|
|
```bash
|
|
./winctl.sh build
|
|
```
|
|
|
|
---
|
|
|
|
### rebuild
|
|
|
|
Destroy and recreate containers. Data in `/storage` is preserved.
|
|
|
|
```bash
|
|
./winctl.sh rebuild win11
|
|
```
|
|
|
|
**Warning:** You must type `yes` to confirm (destructive operation).
|
|
|
|
---
|
|
|
|
### list
|
|
|
|
List available Windows versions.
|
|
|
|
```bash
|
|
# All versions
|
|
./winctl.sh list
|
|
|
|
# By category
|
|
./winctl.sh list desktop
|
|
./winctl.sh list legacy
|
|
./winctl.sh list server
|
|
./winctl.sh list tiny
|
|
```
|
|
|
|
Example output:
|
|
```
|
|
Available Windows Versions
|
|
────────────────────────────────────────────────────────────
|
|
|
|
DESKTOP
|
|
──────────────────────────────────────────────────
|
|
win11 Windows 11 Pro (8G RAM)
|
|
win10 Windows 10 Pro (8G RAM) [running]
|
|
win7 Windows 7 Ultimate (2G RAM)
|
|
```
|
|
|
|
On ARM64, unsupported versions show an `[x86 only]` tag:
|
|
```
|
|
win7 Windows 7 Ultimate (2G RAM) [x86 only]
|
|
```
|
|
|
|
---
|
|
|
|
### inspect
|
|
|
|
Show detailed information about a version.
|
|
|
|
```bash
|
|
./winctl.sh inspect win11
|
|
```
|
|
|
|
Example output:
|
|
```
|
|
Container Details: win11
|
|
────────────────────────────────────────────────────────────
|
|
|
|
Version: win11
|
|
Name: Windows 11 Pro
|
|
Category: desktop
|
|
Status: running
|
|
Web Port: 8011
|
|
RDP Port: 3311
|
|
Resources: modern
|
|
Compose: compose/desktop/win11.yml
|
|
Web URL: http://localhost:8011
|
|
RDP: localhost:3311
|
|
LAN Web: http://192.168.1.100:8011
|
|
LAN RDP: 192.168.1.100:3311
|
|
```
|
|
|
|
---
|
|
|
|
### monitor
|
|
|
|
Real-time dashboard showing all containers.
|
|
|
|
```bash
|
|
# Default 5-second refresh
|
|
./winctl.sh monitor
|
|
|
|
# Custom refresh interval (10 seconds)
|
|
./winctl.sh monitor 10
|
|
```
|
|
|
|
Press `Ctrl+C` to exit.
|
|
|
|
---
|
|
|
|
### check
|
|
|
|
Run prerequisites check.
|
|
|
|
```bash
|
|
./winctl.sh check
|
|
```
|
|
|
|
---
|
|
|
|
### refresh
|
|
|
|
Force refresh the status cache.
|
|
|
|
```bash
|
|
./winctl.sh refresh
|
|
```
|
|
|
|
The cache is stored at `~/.cache/winctl/status.json` and auto-refreshes when:
|
|
- Cache is older than 7 days
|
|
- Cached data becomes stale
|
|
- After start/stop/restart/rebuild operations
|
|
|
|
---
|
|
|
|
### open
|
|
|
|
Open the web viewer in your default browser.
|
|
|
|
```bash
|
|
./winctl.sh open win11
|
|
```
|
|
|
|
If the container is not running, you'll be prompted to start it first.
|
|
|
|
---
|
|
|
|
### pull
|
|
|
|
Pull the latest Docker image.
|
|
|
|
```bash
|
|
./winctl.sh pull
|
|
```
|
|
|
|
Automatically selects `dockurr/windows` or `dockurr/windows-arm` based on detected architecture. Shows whether the image was updated or already up to date.
|
|
|
|
---
|
|
|
|
### disk
|
|
|
|
Show disk usage per VM data directory.
|
|
|
|
```bash
|
|
# All VMs
|
|
./winctl.sh disk
|
|
|
|
# Specific versions
|
|
./winctl.sh disk win11 win10
|
|
```
|
|
|
|
Example output:
|
|
```
|
|
Disk Usage
|
|
────────────────────────────────────────────────────────────
|
|
|
|
VERSION SIZE STATUS
|
|
────────────────────────────────────
|
|
win11 45.2G running
|
|
win10 32.1G stopped
|
|
────────────────────────────────────
|
|
Total: 77.3G
|
|
|
|
Snapshots: 12.5G (2 snapshots)
|
|
win11 12.5G (2 snapshots)
|
|
```
|
|
|
|
---
|
|
|
|
### snapshot
|
|
|
|
Back up a VM's data directory.
|
|
|
|
```bash
|
|
# Auto-named with timestamp
|
|
./winctl.sh snapshot win11
|
|
|
|
# Custom name
|
|
./winctl.sh snapshot win11 before-update
|
|
```
|
|
|
|
The snapshot is saved to `snapshots/<version>/<name>/`. The container is stopped during the copy and restarted automatically.
|
|
|
|
---
|
|
|
|
### restore
|
|
|
|
Restore a VM's data directory from a snapshot.
|
|
|
|
```bash
|
|
# Interactive snapshot selection
|
|
./winctl.sh restore win11
|
|
|
|
# Restore specific snapshot
|
|
./winctl.sh restore win11 before-update
|
|
```
|
|
|
|
If no snapshot name is given, a list of available snapshots is shown for selection. Requires typing `yes` to confirm (destructive: replaces current data).
|
|
|
|
---
|
|
|
|
### clean
|
|
|
|
Remove stopped containers and optionally purge their data directories.
|
|
|
|
```bash
|
|
# Remove stopped containers only
|
|
./winctl.sh clean
|
|
|
|
# Also delete data directories for stopped containers
|
|
./winctl.sh clean --data
|
|
```
|
|
|
|
Requires typing `yes` to confirm. Shows freed disk space on completion.
|
|
|
|
---
|
|
|
|
## Snapshots & Restore
|
|
|
|
`winctl.sh` supports snapshot and restore for VM data directories, stored under `snapshots/`.
|
|
|
|
### Creating a Snapshot
|
|
|
|
```bash
|
|
# Snapshot with auto-generated timestamp name
|
|
./winctl.sh snapshot win11
|
|
|
|
# Snapshot with custom name
|
|
./winctl.sh snapshot win11 before-update
|
|
```
|
|
|
|
The container is stopped during the copy to ensure data consistency, then restarted automatically.
|
|
|
|
### Listing Snapshots
|
|
|
|
```bash
|
|
# Via disk command
|
|
./winctl.sh disk
|
|
|
|
# Or browse directly
|
|
ls snapshots/win11/
|
|
```
|
|
|
|
### Restoring a Snapshot
|
|
|
|
```bash
|
|
# Interactive selection
|
|
./winctl.sh restore win11
|
|
|
|
# Direct restore
|
|
./winctl.sh restore win11 before-update
|
|
```
|
|
|
|
**Warning:** Restore replaces all current data for the version. The container is stopped during restore and restarted automatically.
|
|
|
|
### Snapshot Directory Structure
|
|
|
|
```
|
|
snapshots/
|
|
├── win11/
|
|
│ ├── 20260129-143022/ # Auto-named
|
|
│ └── before-update/ # Custom-named
|
|
└── win10/
|
|
└── 20260128-091500/
|
|
```
|
|
|
|
---
|
|
|
|
## Multi-Instance Support
|
|
|
|
Run multiple instances of the same Windows version with auto-managed ports and a JSON registry.
|
|
|
|
### Creating an Instance
|
|
|
|
```bash
|
|
# Create winxp-1 with auto-allocated ports
|
|
./winctl.sh start winxp --new
|
|
|
|
# Create winxp-lab with a custom name
|
|
./winctl.sh start winxp --new lab
|
|
|
|
# Create winxp-lab and clone data from base winxp
|
|
./winctl.sh start winxp --new lab --clone
|
|
```
|
|
|
|
The `--new` flag:
|
|
1. Allocates unique ports (web: 9000+, RDP: 4000+)
|
|
2. Generates a compose file in `instances/<name>.yml`
|
|
3. Creates a data directory at `data/<name>/`
|
|
4. Registers the instance in `instances/registry.json`
|
|
5. Starts the container
|
|
|
|
### Managing Instances
|
|
|
|
Instances work transparently with all existing commands:
|
|
|
|
```bash
|
|
# Stop an instance
|
|
./winctl.sh stop winxp-lab
|
|
|
|
# Restart an instance
|
|
./winctl.sh restart winxp-lab
|
|
|
|
# View logs
|
|
./winctl.sh logs winxp-lab -f
|
|
|
|
# Open shell
|
|
./winctl.sh shell winxp-lab
|
|
|
|
# Inspect details
|
|
./winctl.sh inspect winxp-lab
|
|
|
|
# Open web viewer
|
|
./winctl.sh open winxp-lab
|
|
|
|
# Snapshot and restore
|
|
./winctl.sh snapshot winxp-lab before-update
|
|
./winctl.sh restore winxp-lab before-update
|
|
```
|
|
|
|
### Listing Instances
|
|
|
|
```bash
|
|
# List all instances
|
|
./winctl.sh instances
|
|
|
|
# Filter by base version
|
|
./winctl.sh instances winxp
|
|
```
|
|
|
|
Example output:
|
|
```
|
|
Instances
|
|
────────────────────────────────────────────────────────────
|
|
|
|
INSTANCE BASE STATUS WEB RDP CREATED
|
|
──────────────────────────────────────────────────────────────────────────────
|
|
winxp-1 winxp running 9000 4000 2026-01-30
|
|
winxp-lab winxp stopped 9001 4001 2026-01-30
|
|
```
|
|
|
|
### Destroying an Instance
|
|
|
|
```bash
|
|
./winctl.sh destroy winxp-lab
|
|
```
|
|
|
|
This will:
|
|
1. Stop and remove the container
|
|
2. Delete the compose file
|
|
3. Prompt to delete the data directory
|
|
4. Remove the instance from the registry
|
|
|
|
### How It Works
|
|
|
|
- **Port allocation**: Web ports start at 9000, RDP at 4000, auto-incrementing to avoid conflicts
|
|
- **Naming**: Instances are named `<version>-<suffix>` (e.g., `winxp-1`, `winxp-lab`)
|
|
- **Registry**: All instances are tracked in `instances/registry.json`
|
|
- **Compose files**: Generated in `instances/<name>.yml` with relative paths to env files and data
|
|
- **No collisions**: Base versions never contain hyphens; instances always do
|
|
|
|
### Instance Directory Structure
|
|
|
|
```
|
|
instances/
|
|
├── registry.json # Instance registry
|
|
├── winxp-1.yml # Generated compose file
|
|
└── winxp-lab.yml # Generated compose file
|
|
|
|
data/
|
|
├── winxp/ # Base version data
|
|
├── winxp-1/ # Instance data
|
|
└── winxp-lab/ # Instance data (cloned from base)
|
|
```
|
|
|
|
---
|
|
|
|
## ISO Cache
|
|
|
|
Windows ISOs are large (3-6 GB) and re-downloaded every time a new container is created for the same version. The ISO cache saves downloaded ISOs so new instances can skip the download.
|
|
|
|
### How It Works
|
|
|
|
1. Start a VM and wait for the ISO to download
|
|
2. Cache the ISO: `./winctl.sh cache save winxp`
|
|
3. Create new instances — cached ISOs are auto-restored: `./winctl.sh start winxp --new`
|
|
|
|
When creating a new instance with `--new`, winctl checks `cache/<version>/` for ISOs and copies them into the new instance's data directory before starting the container. The container sees the ISO on startup and skips the download.
|
|
|
|
### Caching an ISO
|
|
|
|
```bash
|
|
# Cache ISOs from an existing VM's data directory
|
|
./winctl.sh cache save winxp
|
|
./winctl.sh cache save win11
|
|
```
|
|
|
|
The ISOs are copied from `data/<name>/` to `cache/<base-version>/`.
|
|
|
|
### Listing Cached ISOs
|
|
|
|
```bash
|
|
./winctl.sh cache list
|
|
```
|
|
|
|
Shows all cached ISOs grouped by version with file sizes and a total.
|
|
|
|
### Removing Cached ISOs
|
|
|
|
```bash
|
|
# Remove cached ISOs for a specific version
|
|
./winctl.sh cache rm winxp
|
|
|
|
# Remove all cached ISOs
|
|
./winctl.sh cache flush
|
|
```
|
|
|
|
Both commands require typing `yes` to confirm.
|
|
|
|
### Auto-Restore
|
|
|
|
When creating a new instance with `--new` (without `--clone`), winctl automatically checks the cache:
|
|
|
|
```bash
|
|
# If cache/winxp/ has ISOs, they are copied to data/winxp-1/ before start
|
|
./winctl.sh start winxp --new
|
|
```
|
|
|
|
This is skipped when using `--clone`, since cloning copies all data from the base version including any ISOs.
|
|
|
|
### Cache Directory Structure
|
|
|
|
```
|
|
cache/
|
|
├── winxp/
|
|
│ └── custom.iso
|
|
├── win11/
|
|
│ └── win11x64.iso
|
|
└── win10/
|
|
└── win10x64.iso
|
|
```
|
|
|
|
> **Note:** The cache stores processed ISOs from the container's data directory, not raw downloads.
|
|
|
|
---
|
|
|
|
## Configuration
|
|
|
|
### Environment Files
|
|
|
|
Two pre-configured environment files control VM resources:
|
|
|
|
| File | RAM | CPU | Disk | Used By |
|
|
|------|-----|-----|------|---------|
|
|
| `.env.modern` | 8G | 4 | 128G | Win 10/11, Server 2016+ |
|
|
| `.env.legacy` | 2G | 2 | 32G | Win 7/8, Vista, XP, 2000, Server 2003-2012, Tiny |
|
|
|
|
### Customizing Resources
|
|
|
|
Edit `.env.modern` or `.env.legacy`:
|
|
|
|
```bash
|
|
# Resources
|
|
RAM_SIZE=8G
|
|
CPU_CORES=4
|
|
DISK_SIZE=128G
|
|
|
|
# Credentials
|
|
USERNAME=docker
|
|
PASSWORD=admin
|
|
|
|
# Display
|
|
WIDTH=1280
|
|
HEIGHT=720
|
|
|
|
# Other
|
|
LANGUAGE=en
|
|
REGION=en-US
|
|
KEYBOARD=en-US
|
|
DHCP=N
|
|
SAMBA=Y
|
|
RESTART_POLICY=on-failure
|
|
DEBUG=N
|
|
```
|
|
|
|
### Available Settings
|
|
|
|
| Setting | Description | Default |
|
|
|---------|-------------|---------|
|
|
| `RAM_SIZE` | Memory allocation | 8G/2G |
|
|
| `CPU_CORES` | CPU cores | 4/2 |
|
|
| `DISK_SIZE` | Virtual disk size | 128G/32G |
|
|
| `USERNAME` | Windows username | docker |
|
|
| `PASSWORD` | Windows password | admin |
|
|
| `LANGUAGE` | Installation language | en |
|
|
| `REGION` | Region setting | en-US |
|
|
| `KEYBOARD` | Keyboard layout | en-US |
|
|
| `WIDTH` | Display width | 1280 |
|
|
| `HEIGHT` | Display height | 720 |
|
|
| `DHCP` | Use DHCP networking | N |
|
|
| `SAMBA` | Enable file sharing | Y |
|
|
| `RESTART_POLICY` | Container restart policy | on-failure |
|
|
| `DEBUG` | Debug mode | N |
|
|
| `WINDOWS_IMAGE` | Docker image | dockurr/windows |
|
|
|
|
### Restart Policy Options
|
|
|
|
| Value | Description |
|
|
|-------|-------------|
|
|
| `no` | Never restart automatically |
|
|
| `on-failure` | Restart only if container exits with error (default) |
|
|
| `always` | Always restart regardless of exit status |
|
|
| `unless-stopped` | Always restart unless manually stopped |
|
|
|
|
**Note:** With `on-failure` (default), shutting down Windows from inside will stop the container. With `unless-stopped` or `always`, the container will restart after Windows shutdown.
|
|
|
|
---
|
|
|
|
## ARM64 Setup
|
|
|
|
If you're running on an ARM64 system (e.g., Apple Silicon Mac, Ampere server), follow these steps:
|
|
|
|
### 1. Set the Docker image
|
|
|
|
Edit `.env.modern` (and `.env.legacy` if needed):
|
|
|
|
```bash
|
|
WINDOWS_IMAGE=dockurr/windows-arm
|
|
```
|
|
|
|
### 2. Check your setup
|
|
|
|
```bash
|
|
./winctl.sh check
|
|
```
|
|
|
|
Verify the output shows `Architecture: arm64` and lists supported versions.
|
|
|
|
### 3. Start a supported version
|
|
|
|
Only Windows 10 and 11 variants work on ARM64:
|
|
|
|
```bash
|
|
./winctl.sh start win11 # Works
|
|
./winctl.sh start win10 # Works
|
|
./winctl.sh start winxp # Blocked with error
|
|
```
|
|
|
|
### 4. View compatible versions
|
|
|
|
```bash
|
|
./winctl.sh list
|
|
```
|
|
|
|
Unsupported versions are tagged `[x86 only]` on ARM64 systems.
|
|
|
|
### Supported ARM64 Versions
|
|
|
|
| Version | Name |
|
|
|---------|------|
|
|
| win11 | Windows 11 Pro |
|
|
| win11e | Windows 11 Enterprise |
|
|
| win11l | Windows 11 LTSC |
|
|
| win10 | Windows 10 Pro |
|
|
| win10e | Windows 10 Enterprise |
|
|
| win10l | Windows 10 LTSC |
|
|
|
|
All other versions (Win 8.1, 7, Vista, XP, 2000, all Server editions, Tiny) are x86 only.
|
|
|
|
---
|
|
|
|
## Interactive Menus
|
|
|
|
When you don't specify a version, `winctl.sh` shows interactive menus.
|
|
|
|
### Category Selection
|
|
|
|
```
|
|
Select Category
|
|
────────────────────────────────────────────────────────────
|
|
|
|
1) Desktop (Win 11, 10, 8.1, 7)
|
|
2) Legacy (Vista, XP, 2000)
|
|
3) Server (2025, 2022, 2019, 2016, 2012, 2008, 2003)
|
|
4) Tiny (Tiny11, Tiny10)
|
|
5) All versions
|
|
6) Select individual versions
|
|
|
|
Select [1-6]:
|
|
```
|
|
|
|
### Version Selection
|
|
|
|
```
|
|
Select Version(s)
|
|
────────────────────────────────────────────────────────────
|
|
|
|
1) win11 Windows 11 Pro [running]
|
|
2) win11e Windows 11 Enterprise
|
|
3) win11l Windows 11 LTSC
|
|
4) win10 Windows 10 Pro [stopped]
|
|
|
|
a) Select all
|
|
q) Cancel
|
|
|
|
Select (numbers separated by spaces, or 'a' for all):
|
|
```
|
|
|
|
- Enter numbers separated by spaces: `1 3 4`
|
|
- Enter `a` for all versions
|
|
- Enter `q` to cancel
|
|
|
|
---
|
|
|
|
## Common Scenarios
|
|
|
|
### Scenario 1: Set Up a Development Environment
|
|
|
|
```bash
|
|
# Start Windows 10 for development
|
|
./winctl.sh start win10
|
|
|
|
# Access via web browser
|
|
# Open http://localhost:8010
|
|
|
|
# Or connect via RDP for better performance
|
|
# Use RDP client to connect to localhost:3310
|
|
```
|
|
|
|
### Scenario 2: Test Software on Multiple Windows Versions
|
|
|
|
```bash
|
|
# Start multiple versions
|
|
./winctl.sh start win11 win10 win7
|
|
|
|
# Check they're all running
|
|
./winctl.sh status
|
|
|
|
# Access each via their ports:
|
|
# - Win11: http://localhost:8011
|
|
# - Win10: http://localhost:8010
|
|
# - Win7: http://localhost:8007
|
|
|
|
# Stop all when done
|
|
./winctl.sh stop win11 win10 win7
|
|
```
|
|
|
|
### Scenario 3: Run Legacy Software on Windows XP
|
|
|
|
```bash
|
|
# Start Windows XP
|
|
./winctl.sh start winxp
|
|
|
|
# Access via http://localhost:8005
|
|
# Login: docker / admin
|
|
|
|
# Transfer files via the Shared folder on desktop
|
|
```
|
|
|
|
### Scenario 4: Monitor Resource Usage
|
|
|
|
```bash
|
|
# See real-time stats for all running VMs
|
|
./winctl.sh stats
|
|
|
|
# Or use the dashboard
|
|
./winctl.sh monitor
|
|
```
|
|
|
|
### Scenario 5: Increase Resources for a VM
|
|
|
|
1. Stop the container:
|
|
```bash
|
|
./winctl.sh stop win11
|
|
```
|
|
|
|
2. Edit `.env.modern`:
|
|
```bash
|
|
RAM_SIZE=16G
|
|
CPU_CORES=8
|
|
```
|
|
|
|
3. Start again:
|
|
```bash
|
|
./winctl.sh start win11
|
|
```
|
|
|
|
### Scenario 6: Running on ARM64
|
|
|
|
```bash
|
|
# Set the ARM64 image (one-time setup)
|
|
# Edit .env.modern and set: WINDOWS_IMAGE=dockurr/windows-arm
|
|
|
|
# Check architecture is detected
|
|
./winctl.sh check
|
|
|
|
# List versions to see what's available
|
|
./winctl.sh list
|
|
|
|
# Start a supported version
|
|
./winctl.sh start win11
|
|
```
|
|
|
|
### Scenario 7: Fresh Start (Reset VM)
|
|
|
|
```bash
|
|
# This destroys the container but keeps data
|
|
./winctl.sh rebuild win11
|
|
|
|
# For a complete reset, also delete the data:
|
|
rm -rf data/win11/*
|
|
./winctl.sh start win11
|
|
```
|
|
|
|
### Scenario 8: Snapshot Before a Risky Change
|
|
|
|
```bash
|
|
# Create a snapshot before installing something
|
|
./winctl.sh snapshot win11 before-update
|
|
|
|
# Do your work...
|
|
# If something goes wrong, restore:
|
|
./winctl.sh restore win11 before-update
|
|
```
|
|
|
|
### Scenario 9: Clean Up Disk Space
|
|
|
|
```bash
|
|
# Check disk usage
|
|
./winctl.sh disk
|
|
|
|
# Remove stopped containers
|
|
./winctl.sh clean
|
|
|
|
# Remove stopped containers AND their data
|
|
./winctl.sh clean --data
|
|
```
|
|
|
|
### Scenario 10: Quick Access from Browser
|
|
|
|
```bash
|
|
# Open web viewer directly in your browser
|
|
./winctl.sh open win11
|
|
|
|
# Or pull latest image before starting
|
|
./winctl.sh pull
|
|
./winctl.sh start win11
|
|
```
|
|
|
|
### Scenario 11: Access from Another Device on LAN
|
|
|
|
```bash
|
|
# Check your LAN IP
|
|
./winctl.sh check
|
|
|
|
# Start a VM — LAN URLs are shown automatically
|
|
./winctl.sh start win11
|
|
# → LAN Web: http://192.168.1.100:8011
|
|
# → LAN RDP: 192.168.1.100:3311
|
|
|
|
# Use the LAN URL from any device on the same network
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Container Won't Start
|
|
|
|
**Check prerequisites:**
|
|
```bash
|
|
./winctl.sh check
|
|
```
|
|
|
|
**Check logs:**
|
|
```bash
|
|
./winctl.sh logs win11
|
|
```
|
|
|
|
**Common issues:**
|
|
- KVM not accessible → Add user to kvm group
|
|
- Port already in use → `start` auto-detects port conflicts; stop the conflicting service or container
|
|
- Not enough disk space → Run `./winctl.sh disk` to check usage, or free up space
|
|
|
|
### Slow Performance
|
|
|
|
- Ensure KVM is working (hardware virtualization)
|
|
- Increase RAM_SIZE and CPU_CORES in env file
|
|
- Use RDP instead of web viewer for better performance
|
|
|
|
### Can't Connect via RDP
|
|
|
|
1. Wait for Windows to fully boot (check web viewer first)
|
|
2. RDP might be disabled in Windows → Enable via web viewer
|
|
3. Check firewall settings in Windows
|
|
|
|
### Web Viewer Not Loading
|
|
|
|
```bash
|
|
# Check if container is running
|
|
./winctl.sh status win11
|
|
|
|
# Check container logs
|
|
./winctl.sh logs win11
|
|
|
|
# Restart the container
|
|
./winctl.sh restart win11
|
|
```
|
|
|
|
### Cache Issues
|
|
|
|
Force refresh the status cache:
|
|
```bash
|
|
./winctl.sh refresh
|
|
```
|
|
|
|
---
|
|
|
|
## Tips & Tricks
|
|
|
|
### 1. Use Aliases
|
|
|
|
Add to your `~/.bashrc`:
|
|
```bash
|
|
alias wctl='./winctl.sh'
|
|
alias wstart='./winctl.sh start'
|
|
alias wstop='./winctl.sh stop'
|
|
alias wstatus='./winctl.sh status'
|
|
```
|
|
|
|
### 2. Quick Access Bookmarks
|
|
|
|
Bookmark your commonly used VMs:
|
|
- Windows 11: http://localhost:8011
|
|
- Windows 10: http://localhost:8010
|
|
|
|
### 3. File Sharing
|
|
|
|
Each VM has a "Shared" folder on the desktop that maps to the host. Use this to transfer files.
|
|
|
|
### 4. Snapshots
|
|
|
|
Use the built-in snapshot and restore commands:
|
|
```bash
|
|
./winctl.sh snapshot win11 my-backup
|
|
./winctl.sh restore win11 my-backup
|
|
```
|
|
|
|
Snapshots are stored in `snapshots/<version>/<name>/`.
|
|
|
|
### 5. Running Multiple VMs
|
|
|
|
Check your available resources before starting multiple VMs:
|
|
```bash
|
|
# Each modern VM needs 8GB RAM
|
|
# Each legacy VM needs 2GB RAM
|
|
|
|
# Example: Running win11 + win10 + winxp = 8+8+2 = 18GB RAM needed
|
|
```
|
|
|
|
### 6. Headless Operation
|
|
|
|
For servers, you can start VMs and access only via RDP:
|
|
```bash
|
|
./winctl.sh start win2022
|
|
# Connect via RDP to localhost:3322
|
|
```
|
|
|
|
---
|
|
|
|
## File Structure
|
|
|
|
```
|
|
.
|
|
├── winctl.sh # Management script
|
|
├── .env.modern # Modern systems config (8G RAM)
|
|
├── .env.legacy # Legacy systems config (2G RAM)
|
|
├── compose/
|
|
│ ├── desktop/ # Win 11, 10, 8.1, 7
|
|
│ ├── legacy/ # Vista, XP, 2000
|
|
│ ├── server/ # Server 2003-2025
|
|
│ └── tiny/ # Tiny10, Tiny11
|
|
├── instances/
|
|
│ ├── registry.json # Instance registry
|
|
│ ├── winxp-1.yml # Generated compose files
|
|
│ └── winxp-lab.yml
|
|
├── data/
|
|
│ ├── win11/ # Win11 VM storage
|
|
│ ├── win10/ # Win10 VM storage
|
|
│ ├── winxp-1/ # Instance VM storage
|
|
│ ├── winxp-lab/ # Instance VM storage
|
|
│ └── ... # Other VM storage
|
|
├── snapshots/
|
|
│ ├── win11/ # Win11 snapshots
|
|
│ │ ├── 20260129-143022/
|
|
│ │ └── before-update/
|
|
│ └── ... # Other version snapshots
|
|
├── cache/
|
|
│ ├── winxp/ # Cached winxp ISOs
|
|
│ ├── win11/ # Cached win11 ISOs
|
|
│ └── ... # Other cached ISOs
|
|
└── ~/.cache/winctl/
|
|
└── status.json # Status cache
|
|
```
|
|
|
|
---
|
|
|
|
## Getting Help
|
|
|
|
```bash
|
|
# Show all commands
|
|
./winctl.sh help
|
|
|
|
# Check system requirements
|
|
./winctl.sh check
|
|
|
|
# List all versions
|
|
./winctl.sh list
|
|
```
|
|
|
|
For issues, visit: https://github.com/dockur/windows/issues
|