| name | gcloud-vm |
| description | Provision, start, reach, and use Google Cloud VMs for nub — for any real-OS work the local macOS host and Docker can't do (real Linux-kernel enforcement, real Windows/AppContainer/MSVC, a clean multi-GB build box). Invoke whenever you think "I need a Linux box" or "I need a Windows box" — you can START the existing `nub-linux`/`nub-win` instances OR CREATE a fresh one on demand with `gcloud compute instances create`. Encodes the load-bearing gotchas: IPs change on every restart (never trust a hardcoded one), SSH user is `nub` with key `~/.ssh/nub-vm`, a RUNNING box can be a wedged box (read the serial console), size any nub-building Linux box at ≥16 GB, and prefer cross-compiling on the Mac + scp'ing the artifact over building on the VM. Auth expiry needs an interactive `! gcloud auth login` you cannot run yourself. |
Google Cloud VMs for nub
You have gcloud and can create/start/stop VMs yourself. Stop forgetting this — any time a
task needs a real OS the Mac host + Docker can't give you (real Linux-kernel Landlock/seccomp/netns
enforcement, real Windows AppContainer/MSVC, a clean high-RAM build box, a genuinely-clean first-run
environment), spin up or start a VM. Project pullfrog, the existing boxes live in us-central1-a
(NOTE: the gcloud default compute zone is us-west1-a, so always pass --zone us-central1-a
explicitly for the existing instances).
The two standing instances
| Name | OS | Purpose |
|---|
nub-linux | Ubuntu 24.04 LTS, e2-standard-4 (4 vCPU / 16 GB), 30 GB disk | Linux-kernel enforcement (Landlock/seccomp/bwrap/netns); it has a path-bound AppArmor bwrap-userns profile + apparmor_restrict_unprivileged_userns=1 reproducing a locked-down 24.04 host |
nub-win | Windows Server 2022 | Windows AppContainer / DACL / MSVC — the only place real-MSVC FFI/runtime behavior surfaces (windows-gnu on the Mac is the cross-compile proxy, not a runtime) |
They are usually TERMINATED (stopped) to save billing. Start what you need; stop it when done.
gcloud compute instances list
gcloud compute instances start nub-linux --zone us-central1-a
gcloud compute instances stop nub-linux --zone us-central1-a
SSH — user nub, key ~/.ssh/nub-vm, and the IP is DYNAMIC
Creating a NEW VM on demand
When you want an isolated/ephemeral box (a clean first-run env, a second Linux box so you don't
contend with nub-linux, a specific image), create one — don't wait for permission:
gcloud compute instances create nub-linux-tmp \
--zone us-central1-a --project pullfrog \
--machine-type e2-standard-4 \
--image-family ubuntu-2404-lts-amd64 --image-project ubuntu-os-cloud \
--boot-disk-size 30GB
gcloud compute instances create nub-win-tmp \
--zone us-central1-a --project pullfrog \
--machine-type e2-standard-4 \
--image-family windows-2022 --image-project windows-cloud \
--boot-disk-size 50GB
gcloud compute instances add-metadata nub-linux-tmp --zone us-central1-a \
--metadata ssh-keys="nub:$(cat ~/.ssh/nub-vm.pub)"
Delete an ephemeral box when done (gcloud compute instances delete <name> --zone us-central1-a --quiet) — a created VM keeps billing its disk even when stopped.
The gotchas that have actually bitten (each cost a cycle)
Related
- Memory:
nub-vm-ssh-access (the SSH facts; its hardcoded IPs are stale by design — always re-read).
ci-adhoc-test skill — the branch-scoped CI route for macOS/Windows probes when you want CI rather
than a VM (no PR needed). Use a VM when you need an interactive box or a create-from-scratch env; use
ci-adhoc-test when a committed probe on a real runner is enough.
- The Docker section of AGENTS.md — for Linux-only checks that DON'T need a real cloud kernel (a VM is
for real-kernel enforcement and Windows; Docker is the lighter local option where it suffices).