Skip to content

Conversation

@synacktraa
Copy link

@synacktraa synacktraa commented Nov 7, 2025

Cua.Windows.Test.mp4

Summary

This PR adds a production-ready QEMU-based Windows 11 container to the libs/qemu-docker directory, enabling CUA agents to interact with Windows desktop environments through the CUA computer-server.

Recent Updates (Nov 11, 2025)

Major refactoring to simplify architecture and improve portability:

  • ✅ Migrated to trycua/windows-local:latest as base image (from windowsarena/windows-local)
  • ✅ Removed Azure deployment mode - single deployment path using C:\OEM folder
  • ✅ Dynamic VM IP detection for portable deployment across different machines
  • ✅ Simplified setup - removed all the tools except Git and Python installation

Previous Updates (Nov 9, 2025)

Fixed critical issues from initial implementation:

  • ✅ CUA server installs correctly using isolated Python virtual environment
  • ✅ CUA server runs hidden in background via scheduled task
  • ✅ Golden image creation completes automatically without blocking
  • ✅ Boot from golden image works reliably (added windows.boot marker file)
  • ✅ Container lifecycle properly managed (exits during setup, stays alive during runtime)

What's New

  • Windows 11 in Docker: Enterprise edition running in QEMU/KVM with CUA computer-server
  • Hidden background service: CUA server runs via Windows scheduled task with LogonType S4U
  • Virtual environment isolation: CUA server uses isolated Python venv to prevent dependency conflicts
  • Automated lifecycle: Detects setup vs runtime mode, manages container lifecycle accordingly
  • Dynamic IP detection: Automatically detects VM IP from dnsmasq for portable deployment
  • Port forwarding: Server accessible at localhost:5000, noVNC at localhost:8006

Technical Details

Base Image: Uses trycua/windows-local:latest (forked and simplified from dockurr/windows)

Architecture:

Docker Host → Container (Linux) → QEMU VM (Windows 11) → CUA computer-server

Files Structure

libs/qemu-docker/
└── windows/
    ├── Dockerfile                      # Simplified build using trycua/windows-local bases
    ├── README.md                       # Comprehensive setup and usage guide
    └── src/
        ├── entry.sh                    # Container entrypoint with dynamic VM IP detection
        └── vm/
            ├── image/                  # Place for setup.iso
            └── setup/                  # Windows setup scripts (copied to C:\OEM)
                ├── install.bat         # Entry point for Windows setup
                ├── setup.ps1           # Main setup orchestration (Git + CUA server)
                ├── setup-cua-server.ps1 # CUA server setup with venv isolation
                ├── setup-utils.psm1    # Shared PowerShell utilities (logging, Chocolatey)
                └── on-logon.ps1        # Starts CUA server scheduled task at user logon

Usage Example

# 1. Build the base windows-local image (one-time)
cd libs/qemu-docker/windows
docker build -f /path/to/windows-local/Dockerfile -t windows-local:latest .

# 2. Build CUA Windows image
docker build -f latest.Dockerfile -t cua-windows:latest .

# 3. First run - creates golden image (15-20 min)
docker run -it --rm \
    --device=/dev/kvm \
    --platform linux/amd64 \
    --name cua-windows \
    --mount type=bind,source=/path/to/setup.iso,target=/custom.iso \
    --cap-add NET_ADMIN \
    -v /path/to/storage:/storage \
    -p 8006:8006 \
    -p 5000:5000 \
    -e RAM_SIZE=4G \
    -e CPU_CORES=4 \
    -e DISK_SIZE=20G \
    cua-windows:latest

# 4. Subsequent runs - uses golden image (2-5 min)
docker run -it --rm \
    --device=/dev/kvm \
    --platform linux/amd64 \
    --name cua-windows \
    --cap-add NET_ADMIN \
    -v /path/to/storage:/storage \
    -p 8006:8006 \
    -p 5000:5000 \
    -e RAM_SIZE=4G \
    -e CPU_CORES=4 \
    -e DISK_SIZE=20G \
    cua-windows:latest

# Access
open http://localhost:8006              # noVNC browser
curl http://localhost:5000/status       # Computer-server API

Breaking Changes

None - this is a new addition to the libs directory.

…ation

- Install Python 3.12 via Chocolatey for consistent environment
- Create isolated virtual environment at %USERPROFILE%\.cua-server\venv
- Install cua-computer-server package in venv to prevent conflicts
- Create Windows scheduled task with VBScript hidden launcher
- Use LogonType S4U for background execution without interactive session
- Configure auto-restart loop for service resilience
- Add firewall rule for port 5000

Replaces global pip installation approach that was failing.
- Create Caddy start script with auto-restart loop
- Use VBScript wrapper to launch hidden (window mode 0)
- Configure Windows scheduled task with LogonType S4U
- Run reverse proxy from port 9222 to port 1337 in background
- Enable auto-restart on failure for resilience

Ensures Caddy runs completely hidden without visible windows.
Changes to setup.ps1:
- Replace global pip CUA server install with setup-cua-server.ps1 call
- Add setup-caddy-proxy.ps1 call for proxy configuration
- Start WindowsArena_OnLogon task asynchronously (non-blocking)
- Remove blocking Start-ScheduledTask that prevented setup completion

Changes to on-logon.ps1:
- Replace direct service execution with scheduled task triggers
- Start Caddy-Reverse-Proxy task instead of direct caddy command
- Start CUA-Computer-Server task instead of direct python command
- Both services now run hidden via their respective scheduled tasks

Fixes issues:
- Services no longer run in visible windows
- Setup script no longer blocks indefinitely
- Both services run in background as proper scheduled tasks
- Create windows.boot marker file if missing (fixes boot hang)
- Add /storage directory existence check before file creation
- Detect initial setup mode via /custom.iso presence
- Skip tail -f during setup to allow container exit
- Keep container alive only during normal runtime

Fixes issues:
- Container now exits properly after golden image creation
- Boot from golden image no longer hangs indefinitely
- Automatic distinction between setup and runtime modes
@synacktraa synacktraa marked this pull request as ready for review November 9, 2025 19:09
@synacktraa synacktraa requested a review from f-trycua November 10, 2025 09:36
@f-trycua
Copy link
Collaborator

f-trycua commented Nov 10, 2025

on the subsequent runs, there should be no need to mount again the .iso:

Subsequent runs - uses golden image (2-5 min)

docker run -it --rm
--device=/dev/kvm
--platform linux/amd64
--name cua-windows
--cap-add NET_ADMIN
-v $(pwd)/storage:/storage
-p 8006:8006
-p 5000:5000
-e RAM_SIZE=8G
-e CPU_CORES=4
-e DISK_SIZE=20G
cua-windows:dev

@synacktraa
Copy link
Author

on the subsequent runs, there should be no need to mount again the .iso:

Subsequent runs - uses golden image (2-5 min)

docker run -it --rm \

--device=/dev/kvm \

--platform linux/amd64 \

--name cua-windows \

--cap-add NET_ADMIN \

-v $(pwd)/storage:/storage \

-p 8006:8006 \

-p 5000:5000 \

-e RAM_SIZE=8G \

-e CPU_CORES=4 \

-e DISK_SIZE=20G \

cua-windows:dev

Yes, It is documented correctly in the README - I will update the PR comment.


# Ensure Chocolatey and Python 3.12 are present
try {
$ChocoExe = Resolve-ChocoPath
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we re-installing python? Pheraps you can instead download python through the tool-config.json mechanism.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Installing both Python and Git using choco

- Replace windowsarena/windows-local with trycua/windows-local:latest as base
- Remove Azure deployment mode and related files
- Add dynamic VM IP detection in entry.sh for portable deployment
- Keep only Git and Python installation
- Rename setup-tools.psm1 to setup-utils.psm1 with shared logging utilities
- Capture VM process PID after backgrounding tini
- Install signal handlers (SIGTERM, SIGINT, SIGHUP, SIGQUIT) to forward signals to VM process
- Wait for VM to complete graceful shutdown before exiting
- Ensures Windows receives ACPI shutdown signal and has 110 seconds to shut down properly instead of being killed immediately
@vercel
Copy link

vercel bot commented Nov 15, 2025

@synacktraa is attempting to deploy a commit to the Cua Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants