banger/README.md
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

171 lines
5.7 KiB
Markdown

# 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**:
- Linux x86_64 with KVM
- Systemd
- [Firecracker >= v1.5](https://github.com/firecracker-microvm/firecracker)
Install:
```bash
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](#Security)
Verify host configuration:
```bash
banger doctor
```
First VM:
>The first run may take a couple minutes for the bundle download.
>Subsequent `vm run`s are expected to take from 1 to 3 seconds.
```bash
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`
```bash
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):
```bash
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`](docs/dns-routing.md).
For `ssh sandbox.vm` (instead of `banger vm ssh sandbox`):
```bash
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:
```toml
[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`](docs/config.md).
## Updating
```bash
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`](docs/privileges.md)
for the trust model.
## Uninstalling
```bash
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`](docs/privileges.md).
## Further reading
- [`docs/config.md`](docs/config.md) — full config reference.
- [`docs/dns-routing.md`](docs/dns-routing.md) — `<vm>.vm` host-side resolution.
- [`docs/image-catalog.md`](docs/image-catalog.md) — image bundles and how to publish.
- [`docs/kernel-catalog.md`](docs/kernel-catalog.md) — kernel bundles.
- [`docs/oci-import.md`](docs/oci-import.md) — pulling arbitrary OCI images.
- [`docs/advanced.md`](docs/advanced.md) — `vm create`, scripting, custom rootfs.
- [`docs/privileges.md`](docs/privileges.md) — trust model, capability set, daemon split.
- [`CONTRIBUTING.md`](CONTRIBUTING.md) — building from source, running tests.