One-command development sandboxes on Firecracker microVMs. https://git.thaloco.com/thaloco/banger/
Find a file
Thales Maciel aaf49fc1b1
vm run: add -d/--detach + transparent tooling bootstrap
The mise tooling bootstrap was failing silently when --nat wasn't
set: the VM came up, the user landed in ssh, and tools were missing
with no obvious cause. Two coupled fixes:

* `-d`/`--detach`: create + prep + bootstrap, exit without attaching
  to ssh. Reconnect later with `banger vm ssh <name>`. Rejects the
  ambiguous combos `-d --rm` and `-d -- <cmd>`.

* NAT precondition: when the workspace has a .mise.toml or
  .tool-versions, vm run now refuses before VM creation if --nat
  isn't set. Error message points at --nat or --no-bootstrap.

* `--no-bootstrap`: explicit opt-out for users who want a vanilla
  VM with their workspace and no tooling install.

Detached bootstrap runs synchronously (foreground tee'd to the log
file) so the CLI only returns once installs finish. Interactive
mode keeps today's nohup'd background behaviour so the ssh session
starts promptly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 14:51:16 -03:00
.githooks build: add pre-commit hook gating lint + test + build 2026-04-28 15:08:41 -03:00
cmd firecracker: drop sudo sh -c, race chown against SDK probe in Go 2026-04-27 20:14:01 -03:00
configs Generic kernel + init= boot path for OCI-pulled images 2026-04-16 20:12:56 -03:00
docs docs: add release-process runbook 2026-05-01 12:25:36 -03:00
images/golden supply chain: verify signatures and pins across image + kernel builds 2026-04-21 19:38:13 -03:00
internal vm run: add -d/--detach + transparent tooling bootstrap 2026-05-01 14:51:16 -03:00
scripts update: VMs survive banger update and rollback 2026-05-01 12:08:08 -03:00
.gitignore gitignore: exclude the entire build directory 2026-04-26 12:55:11 -03:00
AGENTS.md docs: add release-process runbook 2026-05-01 12:25:36 -03:00
CHANGELOG.md Preserve runtime dir across restart so reconcile re-finds VMs 2026-04-29 17:17:25 -03:00
CONTRIBUTING.md update README.md 2026-05-01 14:10:46 -03:00
cosign.pub updater: embed real cosign public key for v0.1.0 release signing 2026-04-29 12:50:52 -03:00
go.mod Phase 1: imagepull package — pull, flatten, ext4 2026-04-16 17:22:13 -03:00
go.sum Phase 1: imagepull package — pull, flatten, ext4 2026-04-16 17:22:13 -03:00
LICENSE Add LICENSE, update .gitignore, add security note to README 2026-04-14 16:54:33 -03:00
Makefile build: add pre-commit hook gating lint + test + build 2026-04-28 15:08:41 -03:00
mise.toml mise: pin go and shellcheck 2026-04-26 13:11:51 -03:00
README.md vm run: add -d/--detach + transparent tooling bootstrap 2026-05-01 14:51:16 -03:00

banger

One-command development sandboxes on Firecracker microVMs.

Spin up a clean Linux VM with your repo and tooling preloaded, drop into ssh, and tear it down — all from one command. banger is built for the dev loop, not the server use case: guests are short-lived, single-user, reachable at <name>.vm from your host, and disposable.

Quick start

Requirements:

Install:

curl -fsSL https://releases.thaloco.com/banger/install.sh | bash

The installer downloads the signed release, then prompts for sudo for install. Read more about how banger uses sudo

Verify host configuration:

banger doctor

First VM:

The first run may take a couple minutes for the bundle download. Subsequent vm runs are expected to take from 1 to 3 seconds.

banger vm run --name my-vm

This auto-pulls the default image and drops you into an interactive ssh session. Disconnecting an interactive session leaves the VM running, --rm auto-deletes the VM when the session or command exits.

vm run

banger vm run ./my-repo                # copy /my-repo into /root/repo — drops into ssh
banger vm run ./repo -- make test      # workspace + run command, exits with its status
banger vm run --rm -- script.sh        # ephemeral: VM is deleted on exit
banger vm run -d ./repo --nat          # detached: prep + bootstrap, exit (no ssh attach)

If a repository is passed, banger copies your repo's git-tracked files into /root/repo and runs a mise bootstrap from .mise.toml / .tool-versions if either is present. The bootstrap reaches the public internet, so workspaces with mise manifests require --nat; pass --no-bootstrap to skip the install entirely. Untracked files are skipped by default — pass --include-untracked to ship them too, or --dry-run to preview the file list.

In command mode (-- <cmd>), the exit code propagates through banger. In detached mode (-d), banger creates the VM, runs workspace prep + bootstrap synchronously, then exits — no ssh attach. Reconnect later with banger vm ssh <name>.

Other VM verbs

The CLI tries to feel familiar — every command and subcommand has --help. Beyond vm run: vm list shows running VMs (--all for every state), vm ssh <name> reconnects to one, vm exec <name> -- <cmd> runs a command without a shell, vm stop / vm kill shut a VM down (graceful / hard), vm delete removes a stopped one, and vm prune sweeps every non-running VM.

--nat: outbound internet

By default, a guest can't reach the internet. Pass --nat to enable it (host-side MASQUERADE):

banger vm run --nat ./repo -- npm install

--nat works on vm run and vm create. To toggle on an existing VM: banger vm set --nat <name> (or --no-nat to remove it).

Hostnames: <vm>.vm

banger's daemon runs a DNS server for the .vm zone. With host-side DNS routing, curl http://sandbox.vm:3000 works from anywhere on the host — no IP juggling. On systemd-resolved hosts, banger wires this up automatically; everywhere else there's a manual recipe in docs/dns-routing.md.

For ssh sandbox.vm (instead of banger vm ssh sandbox):

banger ssh-config --install

That adds a marker-fenced Include line to ~/.ssh/config. banger ssh-config --uninstall reverses it.

Config

~/.config/banger/config.toml. All keys optional; the two most useful:

[vm_defaults]
vcpu = 4
memory_mib = 4096
disk_size = "16G"

[[file_sync]]
host = "~/.aws"
guest = "~/.aws"

[[file_sync]]
host = "~/.config/gh/hosts.yml"
guest = "~/.config/gh/hosts.yml"

vm_defaults overrides banger's host-derived sizing. file_sync copies host files into the VM's work disk at create time — handy for credentials and dotfiles you want in every sandbox. Full reference: docs/config.md.

Updating

banger update --check        # is a newer release available?
sudo banger update           # download, verify, swap, restart, run doctor

The release tarball is cosign-verified against a public key embedded in the running binary. On any post-swap failure, banger auto-restores the previous install. See docs/privileges.md for the trust model.

Uninstalling

sudo banger system uninstall          # remove services + binaries; keep state
sudo banger system uninstall --purge  # also wipe VMs, images, caches under /var/lib/banger

User config (~/.config/banger/) and SSH key (~/.local/state/banger/ssh/) stay put either way — delete them by hand if you want a full clean slate.

Security

Guest VMs are single-user dev sandboxes, not multi-tenant servers. sshd accepts only the host SSH key (no passwords, no kbd-interactive), and guests are reachable only through the host bridge (172.16.0.0/24). Don't expose the bridge or guest IPs to an untrusted network.

The privileged surface lives entirely in bangerd-root.service and is documented in docs/privileges.md.

Further reading