* fix(agent): allow guest timeout response grace * fix(discovery): classify terminal discovery timeouts * fix(provision): bound low-resource discovery retries * fix(cli): defer failed app discovery * docs(provision): align discovery retry guidance
Click an app. Word opens. That's it.
Native Linux windows for every Windows app — real icons, real WM_CLASS,
pin-to-taskbar. FreeRDP RemoteApp + dockur/windows. Zero config.
# Latest stable release (default)
curl -fsSL https://raw.githubusercontent.com/kernalix7/winpodx/main/install.sh | bash
# Latest main HEAD (development; may be unstable)
curl -fsSL https://raw.githubusercontent.com/kernalix7/winpodx/main/install.sh | bash -s -- --main
# Uninstall (keeps Windows VM data; pass --purge to wipe everything)
curl -fsSL https://raw.githubusercontent.com/kernalix7/winpodx/main/uninstall.sh | bash -s -- --confirm
Windows About / Task Manager / PowerShell each in their own Linux window, alongside the WinPodX Dashboard (live Pod / RAM / CPU gauges, workspace tiles).
Works on
English · 한국어 · Install · Usage · Features · Architecture · Comparison
Contents: Minimum requirements · Quick install · First-time setup · Launch · Key features · Documentation · Supported distros · Testing · Contributing
Status: Beta
WinPodX is in active development (v0.10.4). Highlights of the recent releases:
- Bare-metal disguise (0.7.0, opt-in): the guest reads like a physical machine to VM-detection software, al-khaser 0.82-verified
- Auto file associations + app management (0.7.1): discovered apps appear in "Open with…", and the GUI gains hide/remove/restore
- Quick app launcher (0.7.1):
winpodx launch— a Start-menu-style picker bindable to a hotkey- URL-scheme links (0.9.0):
mailto:/ app schemes from Linux route to the right Windows app- Reverse-open on the VM itself (0.7.3): the guest
C:is shared so a host app edits the real guest fileThe full history is in the CHANGELOG.
No full-screen RDP. Each Windows app becomes its own Linux window with its real icon — pinnable, alt-tabbable, file-associated, both directions. Drop into a full Windows desktop only when you actually want one (winpodx app run desktop).
WinPodX runs a Windows container (via dockur/windows) in the background and presents Windows apps as native Linux applications through FreeRDP RemoteApp, while a bearer-authed HTTP agent inside the guest handles the host→guest command channel without flashing a PowerShell window. The reverse direction — Linux apps surfaced in the Windows "Open with…" menu — is handled by a host-side listener that consumes JSON requests written by per-slug Rust shims inside the guest. Near-zero external Python dependencies (stdlib only on Python 3.11+; one pure-Python tomli fallback on 3.9/3.10).
Minimum requirements
Before installing, make sure your machine actually supports virtualisation. WinPodX runs Windows in a KVM-backed container; without these three, the install will run to completion but Windows will never boot.
| Requirement | How to check | Fix |
|---|---|---|
| Intel VT-x or AMD-V enabled in BIOS / UEFI | lscpu | grep -i virtualization shows VT-x or AMD-V |
Reboot → firmware setup → enable "Intel Virtualization Technology" / "SVM Mode" / "VT-x". OFF by default on many laptops. |
| kvm kernel module loaded | lsmod | grep kvm lists kvm_intel or kvm_amd |
sudo modprobe kvm_intel (Intel) or sudo modprobe kvm_amd (AMD). Auto-loads on next boot once BIOS allows it. |
Your user is in the kvm group |
id -nG | tr ' ' '\n' | grep kvm returns kvm |
sudo usermod -aG kvm $USER, then log out + back in. |
Hardware: x86_64 or aarch64 CPU with virtualisation extensions, 8 GB+ RAM (12 GB+ recommended), and enough free disk for the configured Windows disk (64 GB by default) plus the install ISO. install.sh aborts with the same diagnostic if /dev/kvm is missing after the package install step — most "install ran fine but Windows never boots" bug reports trace back to one of the rows above. Rootless Podman also needs standalone podman-compose and entries for your user in /etc/subuid and /etc/subgid; winpodx setup-host checks and fixes the group/subid host setup.
Quick install
One-liner (any supported Linux distro):
curl -fsSL https://raw.githubusercontent.com/kernalix7/winpodx/main/install.sh | bash
Or via a native package manager:
# openSUSE Tumbleweed / Leap / Slowroll
sudo zypper addrepo https://download.opensuse.org/repositories/home:/Kernalix7/openSUSE_Tumbleweed/home:Kernalix7.repo
sudo zypper install winpodx
# Fedora 42 / 43 / 44 (dnf5 — Fedora 41+)
sudo dnf config-manager addrepo --from-repofile=https://download.opensuse.org/repositories/home:/Kernalix7/Fedora_43/home:Kernalix7.repo
sudo dnf install winpodx
# Debian / Ubuntu — grab the matching .deb from the latest release
sudo apt install ./winpodx_<version>_all_debian13.deb
# AlmaLinux / Rocky / RHEL 9 / 10 — grab the matching .rpm
sudo dnf install ./winpodx-<version>-0.noarch.el10.rpm
# Arch
yay -S winpodx
# Nix
nix run github:kernalix7/winpodx
# AppImage (distro-agnostic x86_64, single file)
# Download winpodx-x86_64.AppImage from the latest GitHub release
chmod +x winpodx-x86_64.AppImage
./winpodx-x86_64.AppImage setup
After a package-manager / AppImage install: run
winpodx setuponce to generate~/.config/winpodx/winpodx.toml+ compose.yaml and complete first provisioning. The curl one-liner does this for you; package installs ship the binary only soapt install/dnf install/yay -S/ first AppImage launch don't trigger a long Windows ISO download out of the blue. After setup, launch an app withwinpodx app run desktop.The Thin AppImage (0.6.0) bundles Python + Qt + winpodx + FreeRDP only — the container runtime lives on the host (
podman≥ 4 recommended,dockeralso supported) so the AppImage no longer fights a host stack you already have (#357, #363). Pre-0.6.0 fat AppImages bundled the whole podman stack and shadowed the host's. Host-side requirements left: a container runtime via your package manager,/dev/kvm,kvmgroup membership, and/etc/subuid//etc/subgidfor rootless Podman.winpodx setup-hostfixes the kvm / subuid bits via a singlepkexecprompt;winpodx doctorsurfaces anything still missing.Updating. Re-run the same one-liner to pick up the latest release — it detects the existing install and upgrades it in place, keeping your config and Windows VM; a running tray / GUI restarts itself so the new version takes effect. This works unmodified on Bazzite and other rpm-ostree hosts too (no
--main, no VM wipe). Installed via a package manager or the AppImage instead? Update it the same way you installed it — through your package manager, or by grabbing the newer.deb/.rpm/ AppImage from the latest release.
See docs/INSTALL.md for offline / air-gapped builds, source installs, version pinning, updating, and uninstall.
First-time setup
If you used the curl install.sh one-liner, setup and first provisioning already ran -- skip to Launch. For every other install path (package managers, AppImage, source, wheel) run setup once before the first app launch:
# Auto setup -- host-detected defaults, no prompts
winpodx setup
# Interactive wizard -- pick backend, cores, RAM, edition, language, timezone, debloat preset
winpodx setup --customize
Setup writes ~/.config/winpodx/winpodx.toml + compose.yaml, registers the GUI launcher, and confirms the host has FreeRDP + Podman / Docker + KVM. If any of those are missing, the output ends with a per-distro install command (e.g. sudo apt install xfreerdp3 podman podman-compose on Debian / Ubuntu, sudo dnf install ... on Fedora) -- run it and re-run winpodx setup.
Setup provisions the pod, pulls the dockur image, runs the Windows ISO download + Sysprep + OEM apply, then applies guest fixes, discovers apps, and configures reverse-open. winpodx pod wait-ready --logs is available to tail container progress when you start or recover the pod separately:
winpodx app run desktop # Launch after setup; subsequent launches are near-instant
winpodx pod wait-ready --logs # Optional: watch a separate cold-start/recovery live
Run winpodx doctor any time afterwards to re-check host state and surface the next fix command if something drifts:
winpodx doctor # Read-only -- prints what would need fixing
winpodx guest apply-fixes # Re-applies guest-side runtime fixes (RDP timeouts, NIC power-save, etc.)
Launch
winpodx app run word # Launch Word
winpodx app run word ~/doc.docx # Open a file
winpodx app run desktop # Full Windows desktop
winpodx launch # Quick app launcher (Start-menu style picker)
Or just click an app icon in your application menu. winpodx launch opens a searchable picker of your Windows apps — bind it to a desktop-environment custom shortcut (KDE: System Settings → Shortcuts → Custom; GNOME: Settings → Keyboard → Custom Shortcuts) for a system-wide hotkey. See docs/USAGE.md for the full CLI, the Qt6 GUI, health checks, and configuration.
Key features
|
Bare-metal disguise (VM-detection avoidance) — opt-in, off by default
| |
|
Reverse-open
|
Seamless app windows
|
|
Zero-config launch
|
Peripherals & sharing
|
|
Automation & security
|
Operations & resilience
|
See docs/FEATURES.md for deep dives, including multi-session RDP internals, app profile schema, and the reverse-open architecture.
Documentation
| Document | What's inside |
|---|---|
| INSTALL.md | Every install path — one-liner, package managers, AppImage, offline, Nix, source |
| USAGE.md | CLI reference, Qt6 GUI tour, health checks, configuration file |
| FEATURES.md | Reverse-open, multi-session RDP, peripherals, app profiles, auto-discovery |
| ARCHITECTURE.md | How it works (diagram), tech stack, source tree, data flows |
| COMPARISON.md | WinPodX vs winapps / LinOffice / winboat, and WinPodX vs Wine |
| CHANGELOG.md | Full version history |
| CONTRIBUTING.md | Development setup and workflow |
| SECURITY.md | Security disclosure process |
Supported distros
| Distro | Package manager | Status |
|---|---|---|
| openSUSE Tumbleweed / Leap 15.6 / Leap 16.0 / Slowroll | zypper | Tested |
| Fedora 42 / 43 / 44 | dnf | Supported |
| Fedora Silverblue / Kinoite / Sericea / Bluefin / Bazzite (42 / 43 / 44) | rpm-ostree (OBS, --apply-live) |
Supported |
| Debian 12 / 13, Ubuntu 24.04 / 25.04 / 25.10 / 26.04 | apt | Supported |
| AlmaLinux / Rocky / RHEL 9 / 10 | dnf | Supported |
| Arch / Manjaro | pacman + yay -S winpodx |
Supported |
| NixOS (and Nix on any distro) | nix flake | Supported |
Each release uses a v*.*.* packaging tag plus a matching REL-v*.*.* release tag. The package workflows build all channels; AUR publication is credential-gated, and assets attach after the GitHub Release exists — see packaging/ for maintainer details.
Testing
# From repo root (no install needed)
export PYTHONPATH="$PWD/src"
# Parallel — the full 3500+ suite finishes in seconds
python3 -m pytest tests/ -n auto
# Lint + format
ruff check src/ tests/
ruff format --check src/ tests/
# Coverage (CI enforces a floor)
python3 -m pytest tests/ -n auto --cov=winpodx --cov-report=term-missing:skip-covered
Contributing
See CONTRIBUTING.md for development setup, branch naming, commit conventions, and CI expectations.
Security
For security issues, follow the process in SECURITY.md.
Star History
Support
If WinPodX makes your Linux desktop a little nicer:
GitHub Sponsors supports recurring or one-time sponsorship; Ko-fi handles international cards and PayPal; fairy.hada.io is a Korean tipping platform. Bug reports, PRs, and stars on the repo are equally appreciated and free.
License
MIT — Kim DaeHyun (kernalix7@kodenet.io)