GCP (nested virt)
GCP is the default ephemeral provider. N2 / C3 / M-series machines support
nested virt; we enable it via --enable-nested-virtualization and Firecracker
runs in the guest.
Status
Section titled “Status”Verified end-to-end 2026-05-06 on n2-standard-4 in us-central1-a. Cycle
≈ 25 min wall, ≈ $0.10 in GCP charges.
Defaults
Section titled “Defaults”INSTANCE_TYPE=n2-standard-4(~$0.19/hr in us-central1)REGION=us-central1-aBOOT_DISK_SIZE=50GB(GCE default 10GB is too small)- Boot disk type
pd-balanced - Image
ubuntu-2404-lts-amd64fromubuntu-os-cloud
Prerequisites
Section titled “Prerequisites”gcloudCLI authenticated:gcloud auth login- A project selected with billing enabled and the Compute API on:
gcloud config set project <id>gcloud services enable compute.googleapis.com- An SSH pubkey at
~/.ssh/id_ed25519.pub(or setSSH_PUBKEY=<path>).
PROVIDER=gcp bash ops/ephemeral/up.sh# ... 5–15 min ...ssh mvm@<ip> 'bash ~/smoke-mvmd.sh'ssh mvm@<ip> 'bash ~/run-tests.sh'PROVIDER=gcp LABEL=<label> bash ops/ephemeral/down.shBugs caught during verification
Section titled “Bugs caught during verification”- GCE doesn’t auto-inject SSH keys to root the way Hetzner does.
providers/gcp.shinjects via--metadata=ssh-keys=root:<pubkey>from${SSH_PUBKEY:-~/.ssh/id_ed25519.pub}. - GCE default boot disk is 10GB, far too small for cloud-init’s apt + rustup + Nix + cargo-tools + mvmd build. Bumped to 50GB.
- Provider-IP reuse leaves stale
~/.ssh/known_hostsentries thataccept-newwon’t override.up.shusesStrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null. - NAT idle timeouts reap the SSH session during long
cloud-init status --wait.up.shusesServerAliveInterval=30 ServerAliveCountMax=240. mvm-hostdlives inmvmd-runtime, not the root crate.cargo build --bin mvm-hostdfrom the workspace root fails.post-deploy.shusescargo build --release --package mvmd-runtime --bin mvm-hostd.mvmd-coordinatorvalidator rejects[autoscale] enabled = false. Template shipsenabled = truewith min=max=1 nodes (functional no-op for a single-node ephemeral host).