MYKOS / DOCUMENTATION · Dashboard · API

Windows, macOS and Ubuntu desktops

Documentation index

MYKOS runs KVM virtual machines inside rootful Podman containers. Windows uses docker.io/dockurr/windows, macOS uses docker.io/dockurr/macos, and Ubuntu uses docker.io/qemux/qemu. Upstream instructions:

For new images, use the unattended image build pipeline. One command installs and provisions the guest, verifies a clean installed boot, captures RAM/device state with matching disks, commits the installed payload under the named local OS image, and leaves one generic base running. The compressed sparse payload is stored in /opt/mykos-image/golden.tar.gz; external immutable state provides fast reflink-based instance starts. Manual Finish remains available when updating older installed images. The memory checkpoint remains paired with its captured disks; the commit updates the image metadata. The unified build also embeds the compressed installed disk/state payload. A new instance restores that checkpoint rather than performing a guest boot. The loader verifies the saved CPU instruction pointer and page-table register before resuming the instance. The pinned image, CPU profile, RAM and vCPU count must remain unchanged; memory checkpoints are intended for this same host.

Live capture requires a reflink-capable filesystem such as XFS with reflink or Btrfs. A memory image contains private guest data: its directory is root-only and it is excluded from RPMs and installer bundles. The capture saves Windows and macOS at the actual desktop/login/session state present during Finish. Existing network connections may need to reconnect after restoring a clone.

Each new instance uses the checkpoint once. Later explicit stop/start operations boot its current disks normally, preventing stale RAM from being applied to changed disks. podman commit alone does not save this QEMU execution state.

Contents

Requirements and networking

Use a Linux x86-64 host with usable /dev/kvm and /dev/net/tun, sufficient memory for each running guest (2048 MiB policy and 2 vCPUs), and at least 32 GiB of free storage for creation. Guest disks default to 64 GiB sparse disks. macOS also requires AVX2. Guest installation and licensing remain the operator's responsibility. Supported current builds run unattended; legacy Windows releases retain their manual setup path.

Each image and instance reserves its own browser-console TCP port in 18006–19005 and native desktop TCP/UDP port in 23000–23999. Reservations persist while stopped. Existing Podman mappings and active TCP/UDP sockets are checked before allocating ports. Guest creation does not alter firewall or router rules. Production requires explicit approval to permit these ranges from its local 192.168.222.0/24 network. The code installer does not open them. On another host, explicitly allow the chosen administrative network before opening the browser console or native login. For example, in its active firewalld zone (replace the source network for that host):

sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.222.0/24" port port="18006-19005" protocol="tcp" accept'
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.222.0/24" port port="23000-23999" protocol="tcp" accept'
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.222.0/24" port port="23000-23999" protocol="udp" accept'

Use the same commands with --permanent to retain the rules across restarts. These examples use the default zone; specify --zone if the LAN interface belongs to a different zone.

By default, ports bind to the host's route-selected LAN IPv4 address, and links use that address. Optional /etc/mykos/config.json settings desktop_bind and desktop_host are IPv4 addresses for binding and connecting respectively. Only use reachable addresses on a trusted administrative network; the upstream browser/VNC consoles provide interactive machine control. Do not expose them to the public Internet without a separately configured access gateway.

Text admin workflow

In the POS menu:

Equivalent commands from either production toolkit's pos directory:

sudo python3 ./vm create win11
sudo python3 ./vm create wns2025
sudo python3 ./vm create mac15
sudo python3 ./vm create ubuntu24.04
# Create only the images you need; each is a running VM consuming RAM.
sudo python3 ./vm list

These commands now run unattended for current Windows/Windows Server, macOS, and Ubuntu versions. No separate Finish step is required. Generated credentials are root-only in /var/lib/mykos/image-builds/OS/credentials.json. Builds and runtime VMs use 2 GiB RAM; Windows/Ubuntu use 12 GiB paging. For details, resuming a failed build and API operations, see Image builds.

For existing images installed manually, Finish and compatibility commands remain:

Update an existing installed image or start an ID-specific instance:

# Existing Windows images require one restart with migratable CPU settings:
sudo python3 ./vm checkpoint-enable win11
sudo python3 ./vm prepare win11
# Upgrade an old disk-only macOS capture without restarting its guest:
sudo python3 ./vm prepare mac15
# Explicitly replace an already prepared memory checkpoint after changes:
# sudo python3 ./vm prepare win11 --replace
sudo python3 ./vm start 01234567 win11
sudo python3 ./vm info 01234567
sudo python3 ./vm stop 01234567
sudo python3 ./vm start 01234567 win11

Supported names: win11, win10, win8e, win7u, winxp, winme, win2k, win98, wns2025, wns2022, wns2019, wns2016, mac15, mac14, mac13, mac12, ubuntu20.04, ubuntu22.04, ubuntu24.04.

Do not mark an installer or recovery screen as a completed guest. Images become available to web staging after capture, including while stopped. Capture requires a running image; successful capture stops and commits it. A failed capture resumes the guest and preserves any previous prepared snapshot. Successful replacement deletes superseded .golden-previous-* snapshots after validating the newly published checkpoint. Only the latest image RAM/disk checkpoint is retained for starting new instances. Each instance discards its copied RAM checkpoint after a successful first restore; later starts use its current disks. New Windows images use CPU_MODEL=host, migratable=on,-invtsc and HV=N with KVM acceleration. The checkpoint-enable operation applies that profile to existing Windows images by restarting their wrapper on the same disks; it retains the stopped original container as *.before-checkpoint-* and rolls back if launching the replacement fails. Never start that retained container while its replacement is running: they reference the same persistent disk. Use resume to start a retained image after an intentional shutdown.

Web and API

The green console-log icon opens that instance's saved console_url. The blue login icon downloads a Windows .rdp connection file, or opens the macOS/Ubuntu vnc:// endpoint. Guest services must be enabled and reachable. Windows 98, ME, and 2000 have no built-in RDP server; use their browser console. No guest credentials are embedded in URLs or RDP files. Desktop access requires an administrator account; Linux shell/VPN operations are not applied to VM wrappers.

The pane ID/Ver plus action starts or resumes an instance. The red trash icon stops it with a two-minute graceful timeout; it does not delete its disk.

API-key clients with admin scope can retrieve endpoints using GET /mykos/api/v2/nodes/{code}/desktop and download the RDP file from GET /mykos/api/v2/nodes/{code}/desktop/rdp. Existing staging and stop APIs dispatch to the desktop worker for these OS names.

Storage, backups and installation

Both toolkit folders use the canonical private registry under /usr/local/share/mykos/pos/.vm/. Guest storage, golden disks and Windows environment files live under /home/mykos-vms/, on production's larger home filesystem. Set desktop_storage in /etc/mykos/config.json before creating images to choose another absolute directory. Do not change this setting after creation without relocating the storage while all guests are stopped. Do not copy live guest disks for backups. Shut down the relevant guests cleanly and back up both directories together with the POS metadata files. Routine code installation preserves these hidden runtime files. Installer code snapshots are not a backup of guest storage.

Install code changes using the usual installer and restart the web service:

sudo python3 /home/mgreen/mykos/bin/mykos-install install --public-origin https://mykol.com
sudo python3 /home/mgreen/mykos/bin/mykos-install verify
sudo systemctl restart mykos-web.service

Installation does not create guests or accept OS license agreements. Start a chosen image explicitly through the menu, complete its installer, capture it, and test one instance before using it for production workloads.

For initial desktop host setup, the installer also provides an explicit network option. It verifies KVM access and storage capacity, creates the private storage directory, snapshots firewalld configuration, and applies only source-restricted runtime and persistent desktop rules. It never opens these ports by default:

sudo python3 /home/mgreen/mykos/bin/mykos-install install --public-origin https://mykol.com --desktop-network 192.168.222.0/24

Preview the plan by adding --dry-run. The option is rejected for actual --root staging installs so tests cannot change the host firewall.

Persistent lifecycle and container snapshots

Start and Stop retain each container's current writable disks, identity and desktop ports. New native RedHat/Linux containers no longer use --rm; the Podman writable layer persists, and Pipework reattaches the saved eth1 MAC on restart. Mounted VPN and backup data remain in place. Existing legacy --rm containers are protected: MYKOS refuses to stop them through these controls until they have been deliberately converted, because stopping them would destroy their writable layer.

Snapshot uses QEMU RAM/device migration plus matching disk copies for Windows, Windows Server, macOS and VM-based Ubuntu. Native Linux uses CRIU with --leave-running, captures its writable layer and mounted data at post-dump while source processes are frozen, and then resumes them. CRIU, the OCI runtime, kernel and workload must support checkpointing. Unsupported workloads fail explicitly; MYKOS does not publish a disk-only snapshot as a successful memory capture.

The installer creates a private snapshots directory under desktop_storage (default /home/mykos-vms/snapshots). Each code has timestamp/random-ID directories containing private metadata and captured state. Intentional snapshots survive RPM updates and automatic image/checkpoint cleanup. Required runtime images are pinned. Native capture adds a scoped action callback to /etc/criu/runc.conf, preserving existing lines; the callback is inert unless MYKOS has a matching live request for that process ID. Runtimes that do not support this callback fail safely. Native restores require the original persistent container, image, and mount configuration. Shared mounted data may have external writers: those writers must be quiesced by the operator for application-level consistency across containers.

The Snapshots pane lists one row per container with its saved states in a dropdown. It hides when empty; the footer leaf override shows two sample rows whose dropdowns and restore actions are disabled. Restore requires confirmation, retains temporary recovery files until verification, and keeps the intentional snapshot available. If recovery itself fails, the job reports the retained recovery location for inspection.

CLI equivalents:

sudo mykos-linux start 01234567
sudo mykos-linux stop 01234567
sudo mykos-snapshot capture 01234567
sudo mykos-snapshot list
sudo mykos-snapshot list 01234567
sudo mykos-snapshot restore 01234567 TIMESTAMP-SNAPSHOT_ID

Each snapshot row also has a red trash icon beside Restore. Delete requires an explicit confirmation, permanently removes only the selected saved state, and leaves the current container and its disks running unchanged. The private snapshot image reference is untagged only after deleting the saved files; other images and snapshots retain their references. CLI: sudo mykos-snapshot delete CODE SNAPSHOT_ID. The OS column shows labels such as macOS 15; Taken follows the chosen saved state.

Snapshots appears immediately after the OS container panes, above rsync Backups.

Host and native Linux root terminals open in a centered popup dialog. Close or Escape disconnects the terminal; the dashboard continues refreshing behind it. VM desktop console/login URLs retain their existing behavior.

Ubuntu image builds use a migratable CPU profile for live-state capture. For an older Ubuntu build blocked by invtsc, run ./vm checkpoint-enable ubuntu22.04 from the installed pos directory (substitute the selected Ubuntu version). The command asks before restarting the build, keeps its installed disk and previous container, and applies CPU_MODEL=host with CPU_FLAGS=migratable=on,-invtsc. After Ubuntu is running normally again, finish the image capture.

Ubuntu networking packages

Before capturing an Ubuntu image, run this in a terminal inside Ubuntu:

sudo apt-get update
sudo apt-get install -y isc-dhcp-client iproute2 net-tools

isc-dhcp-client supplies dhclient. Its runtime dependencies are resolved by APT. Ubuntu 24.04 supplies it in universe; enable that repository first if APT reports no installation candidate. The packaged pos/ubuntu-deps script performs the same setup, validates that it is running inside Ubuntu, and checks availability. Copy it into the guest and run it with sudo bash ubuntu-deps if using the script. The text admin image creation/Finish steps also display the direct APT command.

MYKOS's RHEL host installs its own dhcp-client for pipework. Ubuntu runs as a VM inside a QEMU container: podman exec operates on that wrapper, not Ubuntu. These guest packages do not configure or replace the VM's networking.

For an already captured image, resume its builder with sudo python3.9 ./vm resume ubuntu22.04, install the packages through its console, then recapture with sudo python3.9 ./vm prepare ubuntu22.04 --replace. Substitute the chosen Ubuntu version. Updating an RPM does not modify an existing guest disk; existing instances need the same guest package installation separately. Saved snapshots retain their original software state.

Package references: https://packages.ubuntu.com/en/jammy/isc-dhcp-client and https://packages.ubuntu.com/noble/amd64/isc-dhcp-client.

Permanent container deletion

The red trash icon is separate from start, stop, and snapshot. Type the container ID to permanently remove the selected container and its own MYKOS-managed disks, writable layer and VPN settings. Images, rsync backups, external/shared mounts and intentional snapshots stay in place. Shared storage or unsafe paths block deletion before shutdown. Only administrators can use this operation; API details are in API.md. Stop keeps saved data.

Public HTTPS browser consoles

Image-build and running-container browser console links use /mykos/console/<OS-or-ID>/ on the dashboard's public HTTPS origin. Assets and WebSocket traffic are forwarded by MYKOS to the verified container's published console port. A current administrator browser session is required for every asset and connection; revocation/logout is checked during an open connection. NoVNC settings force the public hostname, TLS and the per-image/per-container WebSocket path, overriding remembered LAN/dev connection settings.

Apache forwards console WebSocket upgrades to MYKOS, where authentication stays in force. Never configure an unauthenticated public proxy straight to VM ports. RPM upgrades and mykos-setup install the WebSocket rule in existing MYKOS TLS vhosts, validate Apache configuration and reload the active service. Configuration backups are saved under /var/backups/mykos-installer/apache-consoles-*. New vhosts should use services/apache-mykos.conf.example, including the console rewrite block. Apache needs proxy, proxy_http, proxy_wstunnel, rewrite and headers.

The API reports the public proxy path as console_url; direct_console_url retains the LAN endpoint for diagnostics. Native RDP/VNC login addresses still require LAN/VPN access; browser consoles need only public HTTPS access and a MYKOS admin session. Guests and their assigned ports are not restarted or changed.

Native snapshot compatibility

MYKOS uses a private CRIU RPC relay for each native snapshot. The filesystem copy runs at the post-dump notification before CRIU resumes source tasks. It does not install shell action scripts in /etc/criu/runc.conf; upgrades remove only the old MYKOS hook line and preserve other operator settings.

RHEL CRIU 3.x cannot capture every systemd workload. MYKOS checks for BPF program descriptors and nested hostname namespaces before seizing processes. Unsupported workloads return a clear error and remain running; no disk-only fallback is published as a memory snapshot. Privileged containers may also expose host kernel mounts that CRIU cannot capture. Do not remove arbitrary sandbox protections to work around these restrictions. A checkpoint-compatible image/runtime is required.

Host Add VPN

The host VPN plus action opens the same pos Add VPN workflow as native containers. Enter the remote name, public address, IPv4 network without /24, and PSK. Confirm creation, then choose whether to push the peer to Meraki using credentials from /etc/mykos/pos.env. The workflow displays the same remote-peer setup instructions and VPN policy as container setup. Host connections are stored under /etc/ipsec.d/mykos-NAME.*; existing names are rejected. New host tunnels are loaded individually, preserving existing tunnels. After creation is confirmed, missing MYKOS-only config/secret includes are appended to the global files with private backups.

Current memory policy

All finished VM images and their instances use 2048 MiB RAM. Unattended macOS installation temporarily requires 4096 MiB for Apple’s second-stage temporary filesystem; it returns to 2048 MiB before the installed-boot check and capture. The image creation menu records the allocation so live state captures remain compatible. Existing 4096 MiB captures require recapturing at 2048 MiB before new instances can resume that state. Existing instances can be cold-resized through vm memory-configure; see BALLOONING.md for recovery, driver and API details.

The Windows/Ubuntu pagefile or swap target is 12 GiB, configured inside the installed guest before capture. The Ubuntu helper rejects the live installer; finish installation, boot the installed OS, apply setup, reboot and verify first. macOS swap stays kernel-managed because a fixed total is not exposed by the stock OS. Its RAM allocation is 2048 MiB. Windows 11 at this allocation is below Microsoft's supported minimum.