Skip to main content
This feature is in early access. Commands, defaults, and behavior may change before general availability. Contact support@macstadium.com with questions or feedback.

Overview

Orka lets you run Android emulators as first-class resources alongside your macOS VMs. The emulator runs on the same physical host Mac as the VM, connected to it via an ADB relay bridge. From inside your VM, you interact with the Android emulator exactly as you would in any other Android CI setup: adb connect and go. This is useful any time you want iOS and Android tests in the same job, without coordinating across separate infrastructure.

How it works

Android emulators cannot run inside macOS VMs because Apple silicon does not support nested virtualization. Orka works around this by running the emulator directly on the host Mac as a separate process. Relay ports are reachable by any VM running on the same physical node: if a node is running two VMs, both can reach either VM’s emulator(s). Per-VM network isolation is planned for a future release. From your VM’s perspective, the emulator is reachable at a bridge IP on a port assigned at deploy time. This IP is currently the same for every emulator (192.168.64.1, the router address of the NAT network that the Apple Virtualization framework creates on the host), but always use the adbRelayIP and adbRelayPort returned by the CLI or API as the source of truth rather than hardcoding them. The emulator lifecycle is tied to the VM: when the VM is deleted, the emulator is cleaned up automatically. You can also manually delete an emulator via the Orka CLI or API before deleting the parent VM.

Prerequisites

  • An Orka cluster (and CLI) running Orka 3.7 or later
  • Your Orka cluster must be provisioned with Apple silicon (M-series) nodes
  • Android SDK and adb installed in your VM image, or installed as part of your CI setup

Deploying an emulator

Emulators are deployed through the Orka CLI or API. The deploy request specifies the target VM name and your configuration options. The emulator starts on the same host node as the VM and enters Pending state while the AVD boots. Once ready, it transitions to Running. Supported configurations: Platform, device profile, and image type values are passed straight through to the Android SDK’s avdmanager and sdkmanager tooling. Any combination those tools support works on a best-effort basis. The only hard constraint is architecture: Orka supports only platforms with an ARM-native system image, since the emulator runs directly on the Apple silicon host. Commonly used values:
  • Platforms: android-35, android-36 (any platform with an ARM system image works)
  • Device profiles: pixel_8, pixel_9, pixel_tablet (any avdmanager-recognized device profile works)
  • Image types: google_apis, google_apis_playstore, default

CLI interface

The Orka CLI manages emulators through orka3 emulator, with three commands: orka3 emulator deploy, orka3 emulator list, and orka3 emulator delete. The orka3 emulator deploy response includes the adbRelayIP and adbRelayPort used to connect to the emulator from the VM.
Common options

API interface

Base URL: /api/v1/namespaces/{namespace} Auth: Authorization: Bearer <token> on every call. RBAC is enforced the same as for VMs.

Emulator instances

Deploy request body Required: vmName (parent VM, must be Running). Optional: platform (default android-36), imageType (default google_apis), deviceProfile (default pixel_9), config (name of a saved template; request fields override the template), generateName (bool, appends a unique suffix to the name).
Deploy is synchronous from the caller’s point of view: it blocks until the emulator reaches Running or Failed, or up to 5 minutes, whichever comes first. An emulator stays Pending while its AVD boots and while the parent VM finishes coming up. If the call times out before the emulator is ready, you get back phase: Pending and a 200, not an error; poll GET until it reaches Running or Failed. When an emulator reaches Failed, errorMessage in the response explains why. Response (same shape for deploy, get, list, and delete):
adbRelayIP and adbRelayPort are how customers actually connect (adb connect <adbRelayIP>:<adbRelayPort>). errorMessage appears only when phase: Failed. Errors: 400 bad or missing vmName, 404 VM or config not found, 409 name collision or VM not running, 403 RBAC, 500 unexpected.

Connecting from inside the VM

Once the emulator is Running, retrieve adbRelayIP and adbRelayPort from the CLI or API response. From inside the macOS VM, connect:
Standard ADB operations work once connected: adb install, adb shell, adb pull, adb push.

Early access scope and known limitations

What is included in early access:
  • Deploy, list, and delete Android emulators via the Orka CLI and API
  • Any platform, device profile, and image type combination supported by avdmanager and sdkmanager, on a best-effort basis, limited only by ARM system image availability
  • Automatic cleanup when the parent VM is deleted
  • Manual emulator delete via the Orka CLI or API
Available platforms and device profiles: Platform and device values are Android SDK identifiers, passed straight through to avdmanager and sdkmanager. This is not a fixed allow-list. Any combination those tools support works on a best-effort basis. The only hard constraint is architecture: Orka supports only platforms with an ARM-native system image, since the emulator runs directly on the Apple silicon host. If a specific platform or device profile fails to deploy, contact support@macstadium.com. Known limitations:
  • Network isolation is scoped to the node, not the VM. Relay ports are reachable by any VM running on the same physical node. For example, if a node is running two VMs, both can reach either VM’s emulator(s). Emulators are not reachable from VMs on other nodes. Per-VM isolation is planned for a future release.
  • Bridged networking is not supported for Android emulators. The emulator relies on the host NAT network to set up the ADB relay, so emulators are available only on NAT-networked VMs (the same limitation as VDI today).
  • Emulators are ephemeral: there is no persistent AVD state between runs. Each deploy creates a fresh emulator.
  • No support yet for packaging custom AVD configurations as Orka images.
  • Android SDK components (roughly 2 to 4 GB per platform and image pair) are downloaded at deploy time if not already cached on the host node. First-run deploys on a node may take longer. There is no pre-caching in early access.
What “early access” means for support: We want your feedback on real workloads. Expect rough edges. Breaking changes are possible before GA. For issues, reach out to support@macstadium.com. The support team handles early access feedback directly and will loop in engineering as needed.