One-command development sandboxes on Firecracker microVMs. https://git.thaloco.com/thaloco/banger/
Find a file
Thales Maciel f1b17f6f8e
install: surface ssh-config --install in next-steps blurb
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 17:57:26 -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 daemon: cut vm stop latency 2026-05-03 17:51:22 -03:00
scripts install: surface ssh-config --install in next-steps blurb 2026-05-03 17:57:26 -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 release: prep v0.1.9 changelog 2026-05-01 19:38:27 -03:00
CONTRIBUTING.md port smoke to go 2026-05-01 19:34:44 -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 port smoke to go 2026-05-01 19:34:44 -03:00
mise.toml mise: pin go and shellcheck 2026-04-26 13:11:51 -03:00
README.md update README.md 2026-05-01 15:24:31 -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 are optional:

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

[[file_sync]]
host = "~/.config/git/config"
guest = "~/.config/git/config"

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

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