diff --git a/.gitignore b/.gitignore
index d60f370..fa5e0cb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,4 +8,5 @@
# Secrets: real values + the local overlay inventory.
# Copy deploy/secrets.example -> deploy/secrets and fill it in.
.env
+.local/
deploy/secrets/
diff --git a/README.md b/README.md
index bf6bbfd..81b0763 100644
--- a/README.md
+++ b/README.md
@@ -52,6 +52,11 @@ it writes the per-host `provision:` blocks and creates the containers. To target
VMs or bare metal instead, change the `provision:` blocks (or drop them); the
role and `expanso-edge.yml` don't change.
+For a local macOS VM lab, see [Local Virtualization With
+Lima](docs/local-virtualization-lima.md). It shows how to install Lima, create
+five Ubuntu VMs, add a gitignored Jetpack SSH overlay, and run the same
+`expanso-edge.yml` deploy playbook against those VMs.
+
Re-runs are idempotent: existing hosts are reused, the agent restarts only when
the version actually changes, and a node is bootstrapped exactly once (its
credentials file is the guard).
diff --git a/docs/local-virtualization-lima.md b/docs/local-virtualization-lima.md
new file mode 100644
index 0000000..78ec266
--- /dev/null
+++ b/docs/local-virtualization-lima.md
@@ -0,0 +1,191 @@
+# Local Virtualization With Lima
+
+Use this path when you want local Linux VMs that the Jetpack deploy role can
+reach over SSH. Lima is the recommended local virtualization layer on macOS,
+including Apple Silicon, because it can run ARM Linux guests directly and has a
+scriptable CLI.
+
+In this repo, "Jetpack" means the `riffcc/jetpack` automation used by the
+`jetp` CLI. Lima does not emulate NVIDIA Jetson JetPack, CUDA, or Jetson GPU
+hardware. For Jetson-specific validation, use real Jetson hardware or another
+GPU-capable Linux host.
+
+## Install Lima
+
+Install Lima with Homebrew:
+
+```bash
+brew install lima
+limactl --version
+limactl start --list-templates | grep '^ubuntu-lts$'
+```
+
+The examples below use the `ubuntu-lts` template because the Expanso Edge role
+supports Debian/Ubuntu and maps both `x86_64` and `aarch64` Linux guests to the
+right Expanso release artifact.
+
+## Install Jetpack On The Mac
+
+Install the Jetpack CLI on the Mac that will run the playbook. Jetpack is the
+controller; it connects to the Lima VMs over SSH. You do not need to install
+Jetpack inside every VM.
+
+Until prebuilt Jetpack binaries are published, build it from source:
+
+```bash
+git clone https://github.com/riffcc/jetpack.git ~/code/jetpack
+cd ~/code/jetpack
+cargo install --path .
+```
+
+Current upstream source builds a `jetpack` binary, while this repo's commands
+use the `jetp` CLI name. If `jetp` is not present after install, add a local
+symlink:
+
+```bash
+if ! command -v jetp >/dev/null 2>&1 && command -v jetpack >/dev/null 2>&1; then
+ ln -sf "$(command -v jetpack)" "$HOME/.cargo/bin/jetp"
+fi
+
+jetp --version
+```
+
+## Create Five Local VMs
+
+Create five Ubuntu VMs with stable SSH ports. The VM names match the committed
+`edge` inventory host names, so the same Jetpack deploy playbook can target
+them. Lima's `--memory` and `--disk` values are GiB.
+
+```bash
+case "$(uname -m)" in
+ arm64) lima_arch=aarch64 ;;
+ x86_64) lima_arch=x86_64 ;;
+ *)
+ echo "unsupported host architecture: $(uname -m)" >&2
+ exit 1
+ ;;
+esac
+
+for node in 01 02 03 04 05; do
+ port=$((60021 + 10#$node))
+ name="expanso-edge-$node"
+
+ limactl create \
+ --tty=false \
+ --name "$name" \
+ --arch "$lima_arch" \
+ --cpus 2 \
+ --memory 4 \
+ --disk 20 \
+ --ssh-port "$port" \
+ template:ubuntu-lts
+
+ limactl start "$name"
+done
+```
+
+Check the VMs:
+
+```bash
+limactl list
+
+for node in 01 02 03 04 05; do
+ port=$((60021 + 10#$node))
+ ssh \
+ -o StrictHostKeyChecking=accept-new \
+ -i ~/.lima/_config/user \
+ -p "$port" \
+ "$USER@127.0.0.1" \
+ 'hostname; uname -m; systemctl --version | head -n 1'
+done
+```
+
+## Add A Jetpack Overlay
+
+The committed inventory still documents the Proxmox LXC provisioning example.
+For Lima, do not run `deploy/playbooks/provision-proxmox-lxc.yml`. Instead,
+start the VMs with Lima and add a gitignored secrets overlay that tells Jetpack
+how to SSH into each VM.
+
+```bash
+cp -r deploy/secrets.example deploy/secrets
+mkdir -p deploy/secrets/host_vars
+
+for node in 01 02 03 04 05; do
+ port=$((60021 + 10#$node))
+ host="expanso-edge-$node"
+
+ cat > "deploy/secrets/host_vars/$host" <
+- Lima installation: