feat: Add ARM64 architecture auto-detection and image selection

Auto-detect machine architecture via uname and use the correct Docker
image (dockurr/windows for x86, dockurr/windows-arm for ARM64). Block
unsupported versions on ARM with a clear error message, and show
[x86 only] tags in the list command. Compose files now use a
configurable WINDOWS_IMAGE variable with a default fallback.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Michel Abboud 2026-01-29 07:24:03 +00:00
parent d75f6b23b1
commit 6a0b6a1511
22 changed files with 110 additions and 24 deletions

View File

@ -23,3 +23,4 @@
# SAMBA=Y # Enable file sharing (Y/N) # SAMBA=Y # Enable file sharing (Y/N)
# RESTART_POLICY=on-failure # Restart policy (no, on-failure, always, unless-stopped) # RESTART_POLICY=on-failure # Restart policy (no, on-failure, always, unless-stopped)
# DEBUG=N # Debug mode (Y/N) # DEBUG=N # Debug mode (Y/N)
# WINDOWS_IMAGE=dockurr/windows # Docker image (dockurr/windows-arm for ARM64)

View File

@ -25,5 +25,8 @@ SAMBA=Y
# Restart Policy (no, on-failure, always, unless-stopped) # Restart Policy (no, on-failure, always, unless-stopped)
RESTART_POLICY=on-failure RESTART_POLICY=on-failure
# Docker Image (dockurr/windows for x86, dockurr/windows-arm for ARM64)
WINDOWS_IMAGE=dockurr/windows
# Debug # Debug
DEBUG=N DEBUG=N

View File

@ -25,5 +25,8 @@ SAMBA=Y
# Restart Policy (no, on-failure, always, unless-stopped) # Restart Policy (no, on-failure, always, unless-stopped)
RESTART_POLICY=on-failure RESTART_POLICY=on-failure
# Docker Image (dockurr/windows for x86, dockurr/windows-arm for ARM64)
WINDOWS_IMAGE=dockurr/windows
# Debug # Debug
DEBUG=N DEBUG=N

View File

@ -35,6 +35,27 @@ A comprehensive guide to managing Windows Docker containers with `winctl.sh`.
| **Server** | win2025, win2022, win2019, win2016, win2012, win2008, win2003 | | **Server** | win2025, win2022, win2019, win2016, win2012, win2008, win2003 |
| **Tiny** | tiny11, tiny10 | | **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 ### Port Mappings
Each version has unique ports to avoid conflicts: Each version has unique ports to avoid conflicts:
@ -435,6 +456,7 @@ DEBUG=N
| `SAMBA` | Enable file sharing | Y | | `SAMBA` | Enable file sharing | Y |
| `RESTART_POLICY` | Container restart policy | on-failure | | `RESTART_POLICY` | Container restart policy | on-failure |
| `DEBUG` | Debug mode | N | | `DEBUG` | Debug mode | N |
| `WINDOWS_IMAGE` | Docker image | dockurr/windows |
### Restart Policy Options ### Restart Policy Options

View File

@ -1,6 +1,6 @@
services: services:
win10: win10:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: win10 container_name: win10
env_file: ../../.env.modern env_file: ../../.env.modern
environment: environment:
@ -20,7 +20,7 @@ services:
stop_grace_period: 2m stop_grace_period: 2m
win10e: win10e:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: win10e container_name: win10e
env_file: ../../.env.modern env_file: ../../.env.modern
environment: environment:
@ -40,7 +40,7 @@ services:
stop_grace_period: 2m stop_grace_period: 2m
win10l: win10l:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: win10l container_name: win10l
env_file: ../../.env.modern env_file: ../../.env.modern
environment: environment:

View File

@ -1,6 +1,6 @@
services: services:
win11: win11:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: win11 container_name: win11
env_file: ../../.env.modern env_file: ../../.env.modern
environment: environment:
@ -20,7 +20,7 @@ services:
stop_grace_period: 2m stop_grace_period: 2m
win11e: win11e:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: win11e container_name: win11e
env_file: ../../.env.modern env_file: ../../.env.modern
environment: environment:
@ -40,7 +40,7 @@ services:
stop_grace_period: 2m stop_grace_period: 2m
win11l: win11l:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: win11l container_name: win11l
env_file: ../../.env.modern env_file: ../../.env.modern
environment: environment:

View File

@ -1,6 +1,6 @@
services: services:
win7: win7:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: win7 container_name: win7
env_file: ../../.env.legacy env_file: ../../.env.legacy
environment: environment:
@ -20,7 +20,7 @@ services:
stop_grace_period: 2m stop_grace_period: 2m
win7e: win7e:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: win7e container_name: win7e
env_file: ../../.env.legacy env_file: ../../.env.legacy
environment: environment:

View File

@ -1,6 +1,6 @@
services: services:
win81: win81:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: win81 container_name: win81
env_file: ../../.env.legacy env_file: ../../.env.legacy
environment: environment:
@ -20,7 +20,7 @@ services:
stop_grace_period: 2m stop_grace_period: 2m
win81e: win81e:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: win81e container_name: win81e
env_file: ../../.env.legacy env_file: ../../.env.legacy
environment: environment:

View File

@ -1,6 +1,6 @@
services: services:
vista: vista:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: vista container_name: vista
env_file: ../../.env.legacy env_file: ../../.env.legacy
environment: environment:

View File

@ -1,6 +1,6 @@
services: services:
win2k: win2k:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: win2k container_name: win2k
env_file: ../../.env.legacy env_file: ../../.env.legacy
environment: environment:

View File

@ -1,6 +1,6 @@
services: services:
winxp: winxp:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: winxp container_name: winxp
env_file: ../../.env.legacy env_file: ../../.env.legacy
environment: environment:

View File

@ -1,6 +1,6 @@
services: services:
win2003: win2003:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: win2003 container_name: win2003
env_file: ../../.env.legacy env_file: ../../.env.legacy
environment: environment:

View File

@ -1,6 +1,6 @@
services: services:
win2008: win2008:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: win2008 container_name: win2008
env_file: ../../.env.legacy env_file: ../../.env.legacy
environment: environment:

View File

@ -1,6 +1,6 @@
services: services:
win2012: win2012:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: win2012 container_name: win2012
env_file: ../../.env.legacy env_file: ../../.env.legacy
environment: environment:

View File

@ -1,6 +1,6 @@
services: services:
win2016: win2016:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: win2016 container_name: win2016
env_file: ../../.env.modern env_file: ../../.env.modern
environment: environment:

View File

@ -1,6 +1,6 @@
services: services:
win2019: win2019:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: win2019 container_name: win2019
env_file: ../../.env.modern env_file: ../../.env.modern
environment: environment:

View File

@ -1,6 +1,6 @@
services: services:
win2022: win2022:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: win2022 container_name: win2022
env_file: ../../.env.modern env_file: ../../.env.modern
environment: environment:

View File

@ -1,6 +1,6 @@
services: services:
win2025: win2025:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: win2025 container_name: win2025
env_file: ../../.env.modern env_file: ../../.env.modern
environment: environment:

View File

@ -1,6 +1,6 @@
services: services:
tiny10: tiny10:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: tiny10 container_name: tiny10
env_file: ../../.env.legacy env_file: ../../.env.legacy
environment: environment:

View File

@ -1,6 +1,6 @@
services: services:
tiny11: tiny11:
image: dockurr/windows image: ${WINDOWS_IMAGE:-dockurr/windows}
container_name: tiny11 container_name: tiny11
env_file: ../../.env.legacy env_file: ../../.env.legacy
environment: environment:

View File

@ -224,7 +224,7 @@ data/ # VM storage (per-version folders)
| `2003` | Windows Server 2003 | 0.6 GB | | `2003` | Windows Server 2003 | 0.6 GB |
> [!TIP] > [!TIP]
> To install ARM64 versions of Windows use [dockur/windows-arm](https://github.com/dockur/windows-arm/). > To install ARM64 versions of Windows use [dockur/windows-arm](https://github.com/dockur/windows-arm/). The `winctl.sh` script auto-detects your architecture and blocks unsupported versions on ARM. Set `WINDOWS_IMAGE=dockurr/windows-arm` in your `.env.modern` file when running on ARM64. Only Windows 10 and 11 variants are supported on ARM64.
### How do I change the storage location? ### How do I change the storage location?

View File

@ -62,6 +62,11 @@ readonly ALL_VERSIONS=(
tiny11 tiny10 tiny11 tiny10
) )
# Versions supported on ARM64
readonly ARM_VERSIONS=(
win11 win11e win11l win10 win10e win10l
)
# Port mappings (web) # Port mappings (web)
declare -A VERSION_PORTS_WEB=( declare -A VERSION_PORTS_WEB=(
["win11"]=8011 ["win11e"]=8012 ["win11l"]=8013 ["win11"]=8011 ["win11e"]=8012 ["win11l"]=8013
@ -199,6 +204,36 @@ table_header() {
printf '%s\n' " ${DIM}$(printf '─%.0s' {1..66})${RESET}" printf '%s\n' " ${DIM}$(printf '─%.0s' {1..66})${RESET}"
} }
# ==============================================================================
# ARCHITECTURE DETECTION
# ==============================================================================
DETECTED_ARCH=""
detect_arch() {
if [[ -n "$DETECTED_ARCH" ]]; then
return
fi
local machine
machine=$(uname -m)
case "$machine" in
x86_64|amd64) DETECTED_ARCH="amd64" ;;
aarch64|arm64) DETECTED_ARCH="arm64" ;;
*) DETECTED_ARCH="amd64" ;;
esac
}
is_arm_supported() {
local version="$1"
local v
for v in "${ARM_VERSIONS[@]}"; do
if [[ "$v" == "$version" ]]; then
return 0
fi
done
return 1
}
# ============================================================================== # ==============================================================================
# PREREQUISITES CHECKS # PREREQUISITES CHECKS
# ============================================================================== # ==============================================================================
@ -692,6 +727,16 @@ cmd_start() {
validate_version "$v" || exit 1 validate_version "$v" || exit 1
done done
# Check ARM compatibility
detect_arch
if [[ "$DETECTED_ARCH" == "arm64" ]]; then
for v in "${versions[@]}"; do
if ! is_arm_supported "$v"; then
die "${VERSION_DISPLAY_NAMES[$v]} ($v) is not supported on ARM64. Supported: ${ARM_VERSIONS[*]}"
fi
done
fi
# Run prerequisite checks # Run prerequisite checks
check_docker || exit 1 check_docker || exit 1
check_kvm || exit 1 check_kvm || exit 1
@ -1027,6 +1072,7 @@ cmd_rebuild() {
cmd_list() { cmd_list() {
local category="${1:-all}" local category="${1:-all}"
detect_arch
header "Available Windows Versions" header "Available Windows Versions"
local categories=() local categories=()
@ -1062,7 +1108,11 @@ cmd_list() {
else else
resource_tag="${DIM}(2G RAM)${RESET}" resource_tag="${DIM}(2G RAM)${RESET}"
fi fi
printf " %-10s %-28s %s %s\n" "$v" "${VERSION_DISPLAY_NAMES[$v]}" "$resource_tag" "$status" local arch_tag=""
if [[ "$DETECTED_ARCH" == "arm64" ]] && ! is_arm_supported "$v"; then
arch_tag="${RED}[x86 only]${RESET}"
fi
printf " %-10s %-28s %s %s %s\n" "$v" "${VERSION_DISPLAY_NAMES[$v]}" "$resource_tag" "$arch_tag" "$status"
fi fi
done done
done done
@ -1155,7 +1205,14 @@ cmd_monitor() {
} }
cmd_check() { cmd_check() {
detect_arch
run_all_checks run_all_checks
printf '%s\n' " ${BOLD}Architecture:${RESET} ${DETECTED_ARCH}"
if [[ "$DETECTED_ARCH" == "arm64" ]]; then
printf '%s\n' " ${BOLD}ARM64 image:${RESET} dockurr/windows-arm"
printf '%s\n' " ${BOLD}Supported:${RESET} ${ARM_VERSIONS[*]}"
fi
printf '\n'
} }
cmd_refresh() { cmd_refresh() {