Skip to content

How it works

Jailrun is an orchestration layer. It doesn't reinvent any of the underlying tools — it wires together a set of proven, focused components, each chosen for a reason.

The stack

Layer Tool Role
Virtual machine QEMU Runs FreeBSD with hardware acceleration (HVF on macOS, KVM on Linux, TCG on FreeBSD)
Jail management Bastille Creates, destroys, and manages jail lifecycles
Provisioning Ansible Runs playbooks to install software inside jails and the VM
Configuration UCL Human-friendly config format, native to FreeBSD
Process supervision monit Monitors processes inside jails, restarts on failure, runs healthchecks
Filesystem ZFS + 9p Instant jail clones via ZFS snapshots; host directory sharing via 9p
Networking pf FreeBSD's packet filter handles port forwarding between host and jails

Every component is transparent and accessible. You can inspect, modify, and extend any layer.

Lifecycle

Four commands control the entire lifecycle:

graph LR
  START["jrun start"] --> UP["jrun up"]
  UP --> DOWN["jrun down"]
  DOWN --> STOP["jrun stop"]

jrun start

Boots FreeBSD on your host inside QEMU. On first run it downloads the image and provisions SSH access. If a base config is provided, it runs VM-level playbooks.

jrun up

Reads your config, resolves the dependency graph, and deploys each jail in order. If the port forwarding or mount configuration changed since the last deploy, jrun automatically restarts the VM to apply the new wiring.

jrun down

Removes a jail and cleans up its mounts, ports, DNS entries, and processes without affecting the rest of the stack.

jrun stop

Shuts down the FreeBSD VM gracefully. The VM image and jail state are preserved on disk — jrun start will boot from where you left off.

Platform support

Platform Architecture Acceleration Status
macOS Apple Silicon HVF Tested
macOS Intel HVF Untested
Linux x86_64 KVM Tested
Linux aarch64 KVM Untested
FreeBSD x86_64 TCG Tested
FreeBSD aarch64 TCG Untested