VZ Setup (macOS Apple Silicon)¶
This guide covers setting up the VZ backend, which uses Apple's Virtualization.framework to run Linux VMs on macOS via vfkit.
Prerequisites¶
- macOS 13+ (Ventura) on Apple Silicon (arm64)
- Go 1.24+ (for building from source)
- Docker (for building the rootfs image)
- Homebrew (for installing vfkit)
Intel macOS support is not currently available.
Installation¶
1. Install vfkit¶
Or build from source:
2. Build shed-server¶
3. Build the VZ rootfs¶
The rootfs build script creates an ext4 disk image, extracts the kernel, and extracts the initrd:
This builds the default variant and produces:
~/Library/Application Support/shed/vz/default-rootfs.ext4- Root filesystem~/Library/Application Support/shed/vz/vmlinux- Decompressed kernel~/Library/Application Support/shed/vz/initrd.img- Initial RAM disk
You can build other variants with --variant:
./scripts/build-vz-rootfs.sh --variant base # Minimal image
./scripts/build-vz-rootfs.sh --variant typescript # TypeScript focused
./scripts/build-vz-rootfs.sh --all # All variants
See VZ Image Variants for details on available variants.
You can override the output directory with OUTPUT_DIR:
4. Create directories¶
5. Configure the server¶
Create ~/.config/shed/server.yaml:
name: my-mac
http_port: 8080
ssh_port: 2222
enabled_backends:
- vz
default_backend: vz
vz:
vfkit_path: vfkit
kernel_path: ~/Library/Application Support/shed/vz/vmlinux
initrd_path: ~/Library/Application Support/shed/vz/initrd.img
base_rootfs: ~/Library/Application Support/shed/vz/default-rootfs.ext4
instance_dir: ~/Library/Application Support/shed/vz/instances
socket_dir: ~/.shed/vz/sockets # Must not contain spaces (vfkit limitation)
default_cpus: 2
default_memory_mb: 4096
default_disk_gb: 20
start_timeout: 60s
stop_timeout: 10s
credentials:
git-ssh:
source: ~/.ssh
target: /home/shed/.ssh
readonly: true
git-config:
source: ~/.gitconfig
target: /home/shed/.gitconfig
readonly: true
claude:
source: ~/.claude
target: /home/shed/.claude
readonly: false
env_file: ~/.shed/env
6. Code signing¶
The shed-server binary needs the com.apple.security.virtualization entitlement to use Virtualization.framework:
7. Start the server¶
8. Create a test shed¶
Configuration Reference¶
See VZ Configuration for all available fields.
How It Works¶
The VZ backend launches each VM as a vfkit subprocess. Communication with the guest uses vsock over per-port Unix sockets (one socket per port, named <name>-<port>.sock). This differs from Firecracker, which uses a single multiplexed socket with a CONNECT/OK handshake.
Networking uses NAT provided by Virtualization.framework. The guest obtains an IP via DHCP through systemd-networkd. From the host's perspective, GetNetworkEndpoint always returns 127.0.0.1.
The rootfs is a standard ext4 image, same as Firecracker. Each instance gets its own copy.
Troubleshooting¶
"vfkit not found"
: Install vfkit with brew install vfkit or add it to your PATH.
Code signing errors
: Re-sign the binary: codesign --entitlements internal/vz/entitlements.plist -s - ./bin/shed-server
"Virtualization.framework not available" : Check that you're running macOS 13+ (Ventura or later).
VM fails to boot
: Verify kernel_path, initrd_path, and base_rootfs point to valid files. Check that the rootfs was built successfully. Check the console log at <instance_dir>/<name>/console.log for boot messages.
Health check timeout
: Check that vsock socket files exist in ~/.shed/vz/sockets/. Verify vfkit is running with ps aux | grep vfkit. Check the console log for systemd boot errors.
Permission denied : Ensure the entitlements plist is applied to the binary via code signing.