One-command development sandboxes on Firecracker microVMs. https://git.thaloco.com/thaloco/banger/
Find a file
Thales Maciel f798e1db33
Stamp shared build metadata into banger binaries
Treat `banger`, `bangerd`, and `banger-vsock-agent` as one release by
stamping the same version, commit SHA, and build timestamp into every
binary through a shared ldflag-backed `internal/buildinfo` package.

Add `banger version`, extend daemon ping/status to report the running
daemon's build tuple, and keep the guest helper linked to the same build
metadata without adding a new public version surface for it.

Validate with `GOCACHE=/tmp/banger-gocache go test ./...`, `make build`,
`./build/bin/banger version`, and `./build/bin/banger daemon status`
after the daemon restarts onto the new binary.
2026-03-22 17:14:06 -03:00
cmd Stamp shared build metadata into banger binaries 2026-03-22 17:14:06 -03:00
docs/reference Reorganize the source checkout layout 2026-03-21 17:22:57 -03:00
examples Add an experimental Alpine image flow 2026-03-21 20:25:55 -03:00
internal Stamp shared build metadata into banger binaries 2026-03-22 17:14:06 -03:00
scripts Wait for real guest vsock health before opencode 2026-03-21 21:14:22 -03:00
.gitignore Reorganize the source checkout layout 2026-03-21 17:22:57 -03:00
AGENTS.md Remove runtime-bundle image dependencies 2026-03-21 18:34:53 -03:00
go.mod Remove the banger TUI 2026-03-19 22:56:16 -03:00
go.sum Remove the banger TUI 2026-03-19 22:56:16 -03:00
Makefile Stamp shared build metadata into banger binaries 2026-03-22 17:14:06 -03:00
README.md Add repo-backed vm run command 2026-03-21 23:34:20 -03:00

banger

banger manages Firecracker development VMs with a local daemon, managed image artifacts, and a localhost web UI.

Requirements

  • Linux with /dev/kvm
  • sudo
  • Firecracker installed on PATH, or firecracker_bin set in config
  • The usual host tools checked by ./build/bin/banger doctor

banger now owns complete managed image sets. A managed image includes:

  • rootfs
  • optional work-seed
  • kernel
  • optional initrd
  • optional modules

There is no runtime bundle anymore.

Build

make build

This writes:

  • ./build/bin/banger
  • ./build/bin/bangerd
  • ./build/bin/banger-vsock-agent

Install

make install

That installs:

  • banger
  • bangerd
  • the banger-vsock-agent companion helper under ../lib/banger/

Config

Config lives at ~/.config/banger/config.toml.

Supported keys:

  • log_level
  • web_listen_addr
  • firecracker_bin
  • ssh_key_path
  • default_image_name
  • auto_stop_stale_after
  • stats_poll_interval
  • metrics_poll_interval
  • bridge_name
  • bridge_ip
  • cidr
  • tap_pool_size
  • default_dns

If ssh_key_path is unset, banger creates and uses:

  • ~/.config/banger/ssh/id_ed25519

default_image_name now only means “use this registered image when vm create omits --image”. The daemon does not auto-register images from host paths.

Core Workflow

Check the host:

./build/bin/banger doctor

Register an existing host-side image stack:

./build/bin/banger image register \
  --name base \
  --rootfs /abs/path/rootfs.ext4 \
  --kernel /abs/path/vmlinux \
  --initrd /abs/path/initrd.img \
  --modules /abs/path/modules

Build a managed image from an existing registered image:

./build/bin/banger image build \
  --name devbox \
  --from-image base \
  --docker

Promote an unmanaged image into daemon-owned managed artifacts:

./build/bin/banger image promote base

Create and use a VM:

./build/bin/banger vm create --image devbox --name testbox
./build/bin/banger vm ssh testbox
./build/bin/banger vm stop testbox

vm create stays synchronous by default, but on a TTY it now shows live progress until the VM is fully ready.

Start a repo-backed VM session and attach opencode automatically:

./build/bin/banger vm run
./build/bin/banger vm run ../some-repo --branch feature/alpine --from HEAD

vm run resolves the enclosing git repository, creates a VM, copies a git checkout plus current tracked and untracked non-ignored files into /root/<repo-name>, and then runs opencode attach from the host against the guest.

Web UI

bangerd serves a local web UI by default at:

  • http://127.0.0.1:7777

See the effective URL with:

./build/bin/banger daemon status

Disable it with:

web_listen_addr = ""

Guest Services

Provisioned images include:

  • banger-vsock-agent
  • guest networking bootstrap
  • mise
  • opencode
  • a default guest opencode service on 0.0.0.0:4096

If host ~/.local/share/opencode/auth.json exists, banger syncs it into the guest at /root/.local/share/opencode/auth.json on VM start. Changes on the host take effect after the VM is restarted.

From the host:

./build/bin/banger vm ports testbox
opencode attach http://<guest-ip>:4096

Manual Helpers

The shell helpers are now explicit manual workflows under ./build/manual.

Rebuild a Debian-style manual rootfs:

make rootfs ARGS='--base-rootfs /abs/path/rootfs.ext4 --kernel /abs/path/vmlinux --initrd /abs/path/initrd.img --modules /abs/path/modules'

The output lands in:

  • ./build/manual/rootfs-docker.ext4
  • ./build/manual/rootfs-docker.work-seed.ext4

Experimental Void Flow

Stage a Void kernel:

make void-kernel

Build the experimental Void rootfs:

make rootfs-void

Register it:

make void-register

That flow uses:

  • ./build/manual/void-kernel/
  • ./build/manual/rootfs-void.ext4
  • ./build/manual/rootfs-void.work-seed.ext4

Experimental Alpine Flow

Stage an Alpine virt kernel:

make alpine-kernel

Build the experimental Alpine rootfs:

make rootfs-alpine

Register it:

make alpine-register

Create a VM from it:

./build/bin/banger vm create --image alpine --name alpine-dev

That flow uses:

  • ./build/manual/alpine-kernel/
  • ./build/manual/rootfs-alpine.ext4
  • ./build/manual/rootfs-alpine.work-seed.ext4

The experimental Alpine flow stages a pinned Alpine release by default. Override that pin with ALPINE_RELEASE=... when running the make alpine-kernel and make rootfs-alpine helpers if you need a different patch release.

Alpine support currently applies to the explicit register-and-run flow above. The generic banger image build --from-image ... path remains Debian/systemd- oriented and should not be treated as an Alpine image builder.

Notes

  • Firecracker is resolved from PATH by default.
  • Managed image delete removes the daemon-owned artifact dir.
  • The companion vsock helper is internal to the install/build layout, not a user-configured runtime path.