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>
171 lines
5.7 KiB
Markdown
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.
|