apple_container and apple_virt are not drop-in replacements for one another.
This page is the authoritative list of what each supports. sandbox_exec confines
a single process rather than booting a guest, so most sandbox commands do not
apply to it at all.
| Capability | apple_virt |
apple_container |
|---|---|---|
| Isolation | Full VM (Virtualization.framework) | Lightweight VM via Apple's container |
| Platform default | No — pass --backend apple_virt |
Yes |
heyvm exec |
Yes | Yes |
heyvm sh |
Yes | Yes |
heyvm ssh |
Yes (sshd on :22) |
No — no SSH server in the guest |
heyvm port-forward |
Yes (SSH tunnel to host 127.0.0.1) |
No — fails with Sandbox has no SSH port |
heyvm create --open-port |
Ignored with a warning — use the guest IP | Yes, at creation time only |
| Reachable from the host | Directly at the guest's NAT IP | Only via a port mapped with --open-port |
| Reachable from another machine | Via heyvm share / the P2P proxy |
Not supported |
heyvm snapshot |
Yes — COW rootfs clone, instant | Requires container commit/import, often absent |
heyvm checkpoint / restore |
No — Linux backends only | No — explicitly rejected |
heyvm fork |
No — Linux backends only | No — Linux backends only |
--start-command on create |
Yes | Yes |
--start-command on restart |
Yes | Yes |
| Custom image build | heyvm images build --backend apple_virt, or the install/ scripts |
Apple's container build → heyvm snapshot |
| Runs in the cloud | No — local only | No — local only |
Choosing a backend
Use apple_virt when you need a reusable custom image, SSH, or to reach a
service from anywhere other than the host process that created it. It is the only
macOS backend with a working heyvm snapshot.
Use apple_container when you want the fastest possible start for running
commands in a throwaway guest, and a single --open-port mapping is enough.
Building a reusable toolchain image
This is the supported macOS path, and it does not involve docker import:
# 1. Start from a base image and provision it
heyvm create --name toolchain-build --backend apple_virt --image alpine-3.21
heyvm exec toolchain-build -- apk add --no-cache ruby nodejs npm postgresql redis
# 2. Bake the result into a reusable image
heyvm snapshot toolchain-build --name my-toolchain
# 3. Use it
heyvm create --name dev-1 --backend apple_virt --image my-toolchain
heyvm snapshot clones the sandbox's rootfs with APFS clonefile and hardlinks
the kernel, so snapshots are near-instant and cost almost no disk until written
to. Images land in ~/.heyo/images/apple_virt/<name>/.
On
apple_container,heyvm snapshotshells out tocontainer commitand falls back tocontainer export+container import. Severalcontainerbuilds ship without thecontainer-importplugin, in which case snapshotting fails withPlugin 'container-import' not found. There is no workaround on that backend — build the image onapple_virtinstead.
Reaching a service inside a sandbox
On apple_virt the guest holds a host-routable NAT IP, so no forwarding step is
needed. The service must bind 0.0.0.0 (or the guest's eth0) rather than
127.0.0.1:
heyvm get <id> # read guest_ip
curl http://<guest-ip>:5000
On apple_container, map the port when you create the sandbox — it cannot be
added afterwards:
heyvm create --name api --open-port 18734:5000
curl http://127.0.0.1:18734
heyvm bindprints a publichttps://<subdomain>.heyo.computerURL for local sandboxes, but the CLI does not currently register that subdomain with the cloud, so requests to it returnEndpoint not found. Use--open-portor the guest IP for same-machine access, andheyvm sharefor off-host access, until this is fixed.
See macOS Backends for what each backend is, and Troubleshooting if a sandbox will not start.