bhyve is part of the FreeBSD base system and remains a practical choice when a FreeBSD host needs to run a small number of FreeBSD, Linux, OpenBSD, or Windows guests. This article updates the older FreeBSD 10.1 walkthrough with the workflow documented in the current FreeBSD Handbook. It deliberately uses the base-system example script rather than presenting an untested production framework.
The outcome is a FreeBSD guest connected to the same Layer-2 network as the host through a tap device and bridge. The commands are documentation-verified examples. Substitute the physical interface, guest name, disk location, memory, CPU count, and ISO release for your host.
Prerequisites
Use a supported FreeBSD release, a processor with virtualization support, enough RAM for the host and guest, and local-console access in case a network bridge is configured incorrectly. For Intel systems, inspect dmesg or /var/run/dmesg.boot for EPT and UG on the VT-x line. For AMD systems, look for POPCNT in the Features2 line. The FreeBSD Handbook also documents ARM limitations separately.
Do not attach a bridge to a remote-only host until you have an out-of-band recovery path. Bridging changes the host networking topology and an incorrect physical interface name can disconnect an SSH session.
Prepare the host
Load the hypervisor module:
kldload vmm
Create a tap interface for the guest, then connect it and the host physical interface to a bridge. The Handbook example uses igb0; replace it with the interface shown by ifconfig on your host.
ifconfig tap0 create
sysctl net.link.tap.up_on_open=1
ifconfig bridge0 create
ifconfig bridge0 addm <physical-interface> addm tap0
ifconfig bridge0 up
tap0 is the guest-facing endpoint. bridge0 forwards frames between that endpoint and the host network. The net.link.tap.up_on_open setting causes the tap interface to become active when bhyve opens it. Persisting these settings belongs in the host’s network configuration after testing them locally; the exact rc.conf layout depends on the host and its existing networking policy.
Create the guest storage and installation media
Create a sparse disk image and download a boot-only image for the target FreeBSD release. Use a dedicated directory with capacity planning appropriate to the guest workload.
mkdir -p /vm/guestname
cd /vm/guestname
truncate -s 16G guest.img
fetch https://download.freebsd.org/releases/ISO-IMAGES/<release>/FreeBSD-<release>-RELEASE-amd64-bootonly.iso
The initial 16 GB image is an example, not a sizing recommendation. Plan for the operating system, package cache, logs, application data, and snapshots before choosing storage. A ZFS-backed guest dataset can simplify snapshots and quotas, but its design should match the host’s storage and backup policy.
Install with the supplied bhyve example
FreeBSD ships /usr/share/examples/bhyve/vmrun.sh, which starts a guest and restarts it if bhyve exits. Review its options before use:
sh /usr/share/examples/bhyve/vmrun.sh -h
Start an installation using the bridge tap, disk image, and ISO:
sh /usr/share/examples/bhyve/vmrun.sh \
-c 1 -m 1024M -t tap0 -d guest.img \
-i -I FreeBSD-<release>-RELEASE-amd64-bootonly.iso \
guestname
The -c option sets virtual CPUs, -m sets guest memory, -t selects the tap device, -d selects the virtual disk, -i requests installation media booting, and -I supplies the ISO path. Use values appropriate to the host; do not allocate all host memory or CPU capacity to one guest.
During installation, configure the guest network normally. The expected result is that the guest receives or is assigned an address reachable on the bridged network. If it does not, check the physical interface name, bridge membership, VLAN policy, DHCP reachability, and host firewall rules before changing guest settings.
After installation, start the guest from its disk:
sh /usr/share/examples/bhyve/vmrun.sh \
-c 1 -m 1024M -t tap0 -d guest.img guestname
Verify before automating
Confirm the host recognizes the virtualization module and the bridge includes both interfaces:
kldstat | grep vmm
ifconfig bridge0
ifconfig tap0
From the guest console, verify its address and default route. From a permitted system on the LAN, test the guest’s intended service rather than assuming an ICMP response proves the full application path works. Record the host interface name, guest disk location, resource allocation, and recovery procedure before converting the setup into an unattended service.
For Linux guests, UEFI or grub2-bhyve may be appropriate; follow the current Handbook section for that guest type instead of reusing the legacy Ubuntu 15 instructions.
Make the host configuration durable
The commands above prove the topology, but they do not by themselves describe a complete boot-time design. After testing locally, record the vmm module, tap behavior, bridge membership, and host interface configuration in the mechanism used by your release and operational tooling. Keep the host address on the correct interface for your network design; moving an address onto a bridge without understanding the existing configuration can interrupt management access.
Treat each guest as an operational object with a documented owner, disk location, resource budget, backup policy, and recovery procedure. A sparse image is convenient for a lab, while a dedicated ZFS dataset can make snapshot and quota management clearer. Neither choice replaces a tested backup: snapshots remain on the same storage failure domain unless they are replicated elsewhere.
Troubleshoot one layer at a time
When a guest does not boot, first check the bhyve console and the selected boot media. When it boots but has no network, inspect the host bridge before changing the guest: ifconfig bridge0 should show both the physical interface and the tap member. Confirm that the intended VLAN is available on that physical path and that the upstream network permits the guest MAC address.
If a guest starts and exits immediately, preserve its console output, confirm the disk and ISO paths, and inspect the host resource allocation. Avoid repeatedly restarting a failed guest without understanding the failure; the example script’s restart behavior can obscure the first useful error. For a production service, decide separately how a controlled shutdown, host reboot, and automatic recovery should behave.
Sources
- FreeBSD Handbook, “FreeBSD as a Host with bhyve”: https://docs.freebsd.org/en/books/handbook/virtualization/#virtualization-host-bhyve
- FreeBSD Handbook, “Virtualization”: https://docs.freebsd.org/en/books/handbook/virtualization/