VZ Operations (macOS Apple Silicon)¶
This guide covers day-to-day operations with the VZ backend.
VZ support is currently Apple Silicon-only.
Basic Operations¶
Create a shed¶
# Basic creation
shed create myproject --backend=vz
# With a git repository
shed create myproject --backend=vz --repo=git@github.com:user/repo.git
# With a local directory (mounted via VirtioFS)
shed create myproject --backend=vz --local-dir=/path/to/project
# With custom resources
shed create myproject --backend=vz --cpus=4 --memory=8192
Start and stop¶
Delete¶
List sheds¶
Local Directory Mounting¶
When using --local-dir, the host directory is shared with the VM via VirtioFS and mounted at /home/shed/<basename> inside the guest, where <basename> is the last path segment of the host directory. Changes on either side are immediately visible to the other, and the shed lands there on login.
shed create myproject --backend=vz --local-dir=~/projects/myapp
shed console myproject
# Inside the VM: lands in /home/shed/myapp, the contents of ~/projects/myapp
To mount additional reference directories alongside the primary one, repeat --add-dir (valid only with --local-dir). Each is mounted at /home/shed/<basename> as a sibling:
shed create myproject --backend=vz \
--local-dir=~/projects/myapp \
--add-dir=~/projects/shared-lib
# /home/shed/myapp and /home/shed/shared-lib are both VirtioFS-backed
No two mounted directories may share a basename, and dotfile basenames are rejected. --local-dir/--add-dir are mutually exclusive with --repo. If the VirtioFS mount fails (e.g., the guest kernel lacks CONFIG_VIRTIO_FS), the create or start operation will fail with an error.
Mounts¶
All mounts configured under the mounts: section of server.yaml are bound into VZ VMs via VirtioFS. Changes are immediately visible on both sides, similar to Docker bind mounts.
Read-only mounts (readonly: true) are enforced as read-only at the mount level. Writable mounts (readonly: false) reflect changes immediately in both directions.
Configure mounts in server.yaml:
The legacy credentials: key is still honored as a fallback when mounts: is absent.
Provisioning¶
Provisioning hooks execute in the VM via vsock, identically to Firecracker. Mounts are bound via VirtioFS before hooks run.
For the full sequence of operations during create, start, stop, and delete (including how VZ differs from other backends), see Shed Lifecycle. For hook configuration, see Provisioning.
Inspecting VMs¶
Metadata¶
Each instance stores metadata at:
vfkit process¶
Socket files¶
Each VM creates per-port Unix sockets:
ls ~/.shed/vz/sockets/
# myproject-1024.sock (console)
# myproject-1026.sock (message bus: health, plugins)
Networking¶
VZ uses NAT networking provided by Apple's Virtualization.framework. The guest obtains an IP address via DHCP through systemd-networkd.
From the host, shed commands communicate with the VM over vsock (Unix sockets), not TCP. shed list and the API still report a 127.0.0.1 IP for running VZ sheds (so the field has a sensible value in JSON output), but service traffic itself routes through DialService's vsock TCP-proxy hop rather than that IP.
Docker Inside VZ¶
Docker is pre-installed in the VZ rootfs image. It starts automatically via systemd:
Debugging¶
Manual health check¶
# Connect to the message bus socket (health checks use system:health namespace)
nc -U ~/.shed/vz/sockets/myproject-1026.sock
View console log¶
Each VM writes boot and console output to a log file:
Check vfkit process¶
View instance metadata¶
macOS-Specific Notes¶
- Code signing: The shed-server binary must be signed with the
com.apple.security.virtualizationentitlement. - No
/proc: Process identification usesps -p <pid> -o comm=instead of reading/proc/<pid>/cmdline. - Console device: VZ uses
hvc0(virtio console) instead of Firecracker'sttyS0. - vfkit subprocess model: Each VM runs as a separate vfkit process. Stopping a VM sends SIGTERM, then SIGKILL after timeout.
- Socket naming: Per-port sockets follow the pattern
<name>-<port>.sockin the socket directory.