FreeBSD.software
Home/Blog/Best Container/Jail Management Tools for FreeBSD in 2026
comparison2026-03-29

Best Container/Jail Management Tools for FreeBSD in 2026

Compare the best jail management tools for FreeBSD: Bastille, iocage, pot, cbsd, and AppJail. Covers features, networking, templates, ZFS integration, and recommendations.

# Best Container/Jail Management Tools for FreeBSD in 2026

FreeBSD jails provide operating-system-level isolation that predates Docker by over a decade. Creating a single jail by hand with jail.conf is straightforward. Managing ten or fifty jails with consistent networking, ZFS snapshots, updates, and templating is not. That is where jail management tools come in.

This guide compares the five active jail managers available in FreeBSD ports -- Bastille, iocage, pot, cbsd, and AppJail -- plus the option of managing jails manually. Every tool is installable from pkg, every command shown is real, and the comparison reflects the state of each project as of early 2026.

For a full walkthrough of jail fundamentals, see our [FreeBSD jails guide](/blog/freebsd-jails-guide/). If you are evaluating jails against Linux containers, read [jails vs Docker](/blog/freebsd-jails-vs-docker/).

Quick Recommendation

If you want a short answer:

- **Bastille** is the best jail manager for most FreeBSD administrators. It has clean syntax, solid templates, active development, strong community, and sensible defaults. If you manage between 1 and 100 jails on one or a few hosts, start here.

- **pot** is the right choice if you need HashiCorp Nomad orchestration. It was designed from the ground up to work as a Nomad task driver, making it the only jail manager with first-class multi-host scheduling support.

- **cbsd** is the tool for advanced users who want a single framework that manages jails, bhyve VMs, and Xen guests. It has the richest feature set of any jail manager but the steepest learning curve.

- **AppJail** is worth watching. It is the newest of the group, with a Makejail build system inspired by Dockerfiles. Active development, growing community, but less battle-tested than Bastille or cbsd.

- **iocage** remains functional but development has slowed significantly. Existing deployments work fine; new projects should evaluate alternatives first.

- **Manual jails** via jail.conf are perfectly adequate for one to five static jails where you do not need templating, mass updates, or VNET automation.

The rest of this article explains why, with install commands, configuration examples, and a detailed feature comparison.

---

Bastille

Bastille is a shell-based jail manager that emphasizes simplicity, templates, and a workflow inspired by Docker concepts but built entirely on FreeBSD-native primitives. It is written in sh, has no runtime dependencies beyond base FreeBSD, and uses ZFS or UFS transparently.

Install

sh

pkg install bastille

Enable the service:

sh

sysrc bastille_enable=YES

How It Works

Bastille uses a release-based model. You bootstrap a FreeBSD release once, then create jails from that release. Each jail gets its own filesystem tree (a ZFS clone if ZFS is available, a directory copy otherwise). Bastille manages the jail lifecycle -- create, start, stop, destroy, restart -- with consistent subcommands.

sh

bastille bootstrap 14.2-RELEASE update

bastille create webapp 14.2-RELEASE 10.0.0.2

bastille start webapp

The bastille console command drops you into a jail shell. bastille cmd runs a command inside a jail from the host. bastille pkg manages packages across one or all jails.

Templates

Bastille templates are its strongest feature. A template is a set of declarative instructions -- install packages, copy files, enable services, set sysctls -- that you apply to a jail after creation. Templates are stored as plain text and can be version-controlled, shared, and composed.

sh

bastille template webapp bastillebsd/templates/nginx

The template system supports PKG, CP, SYSRC, SERVICE, CMD, MOUNT, RDR, and other directives. Community templates exist for common stacks: NGINX, PostgreSQL, Redis, WordPress, and more.

Networking

Bastille supports three networking modes:

1. **Shared IP (alias-based).** The jail gets an IP alias on the host's interface. Simple, no extra configuration, but the jail shares the host's network stack.

2. **VNET.** Each jail gets its own virtualized network stack with a dedicated epair interface. This gives the jail full networking capabilities including its own routing table, firewall state, and the ability to bind to any port without conflicting with the host.

3. **Loopback.** Jails bound to lo1 with PF rdr rules for port forwarding. Bastille can manage PF redirect rules through its rdr subcommand.

VNET is the recommended approach for production jails that need network isolation. Bastille automates bridge creation and epair pairing.

sh

bastille create --vnet myjail 14.2-RELEASE 192.168.1.50/24

Pros

- Minimal dependencies. Written in sh, works on any FreeBSD install.

- Template system provides reproducible jail builds without custom scripting.

- Active development and responsive maintainer. Regular releases through 2025 and 2026.

- Good documentation and a growing community on Discord and GitHub.

- Supports thick (full copy) and thin (ZFS clone) jails.

- bastille export and bastille import for jail migration.

Cons

- Single-host only. No built-in clustering or multi-host orchestration.

- VNET configuration can require manual PF rules for complex topologies.

- No web UI. Strictly command-line.

- No bhyve or VM management -- jails only.

---

iocage

iocage was for years the most popular FreeBSD jail manager. It introduced many ideas that other tools later adopted: ZFS-first design, templating, release management, and a property-based configuration model. The current version is written in Python and ships as a FreeBSD port.

Install

sh

pkg install py311-iocage

How It Works

iocage uses ZFS datasets for everything. Each jail is a ZFS dataset with properties stored as ZFS user properties. Releases are fetched and stored as base datasets. Jails are created as ZFS clones (by default) for fast provisioning and efficient storage.

sh

iocage fetch -r 14.2-RELEASE

iocage create -n webapp -r 14.2-RELEASE ip4_addr="vnet0|10.0.0.5/24" vnet=on

iocage start webapp

The property system means you configure a jail by setting key-value pairs:

sh

iocage set boot=on webapp

iocage set allow_raw_sockets=1 webapp

iocage get all webapp

Current Status

This is the key consideration with iocage in 2026. The Python rewrite (py3-iocage) has seen limited commit activity over the past two years. The tool works -- existing deployments continue to function on FreeBSD 14.x -- but the pace of new features and bug fixes has slowed. Several long-standing issues in the GitHub tracker remain open.

If you have an existing iocage deployment, there is no urgent reason to migrate. If you are starting fresh, evaluate Bastille or cbsd first and use iocage only if its ZFS property model or existing tooling around it is a specific requirement.

Pros

- Deep ZFS integration. Snapshots, clones, and replication are first-class operations.

- Property-based configuration is powerful and scriptable.

- Mature codebase with years of production use.

- Good VNET support.

- Plugin system for one-command application deployment (though the plugin repo is community-maintained).

Cons

- Development activity has slowed. Response time on issues and PRs is inconsistent.

- Python dependency adds weight compared to shell-based tools.

- Some users report rough edges with VNET on FreeBSD 14.x that have not been patched upstream.

- Plugin repository maintenance is community-dependent and some plugins are outdated.

---

pot

pot is an image-based jail manager designed around the concept of layered, composable jail images. Its distinguishing feature is native integration with HashiCorp Nomad as a task driver, making it the only jail manager purpose-built for multi-host orchestration.

Install

sh

pkg install pot

Initialize:

sh

pot init

How It Works

pot uses a layered filesystem model. A "base" layer contains the FreeBSD release. "Flavors" layer on top of it with additional packages and configuration. Jails are created from these layers, and each layer is a ZFS dataset.

sh

pot create -p webapp -t single -b 14.2 -N public-bridge -f mywebflavor

pot start webapp

The single type creates a jail with its own copy of the base. The multi type shares the base via nullfs mounts, saving disk space when running many jails from the same release.

Nomad Integration

This is pot's primary differentiator. The nomad-pot-driver lets Nomad schedule and manage pot jails as tasks, the same way Nomad manages Docker containers on Linux. You write a Nomad job specification that references a pot image, and Nomad handles placement, health checking, service registration (with Consul), and rescheduling.

hcl

task "web" {

driver = "pot"

config {

image = "https://potluck.honeyguide.net/nginx"

pot = "nginx-server"

tag = "1.0"

}

}

If you are building a multi-host FreeBSD infrastructure with dynamic scheduling, pot plus Nomad is the production-ready path.

Pros

- First-class Nomad integration. No other jail manager offers this.

- Image-based model supports versioned, immutable jail images.

- Potluck repository provides pre-built images for common services.

- Layered ZFS datasets save storage when running many similar jails.

- Active development with a clear architectural vision.

Cons

- Smaller community than Bastille or iocage.

- The layered model has a learning curve if you are used to traditional jail management.

- Documentation is adequate but not as extensive as Bastille's.

- Most useful when combined with Nomad; on a single host, Bastille is simpler.

---

cbsd

cbsd is the most feature-rich jail and VM management framework available for FreeBSD. It manages jails, bhyve virtual machines, and Xen guests from a single toolset. It includes a web interface, distributed node management, and more configuration options than any other jail manager.

Install

sh

pkg install cbsd

Initialize:

sh

env workdir="/usr/jbsd" /usr/local/cbsd/sudoexec/initenv

How It Works

cbsd wraps FreeBSD jail management in a comprehensive framework with its own directory structure, SQLite database for tracking jail metadata, and a large set of subcommands. Creating a jail involves an interactive wizard or command-line flags:

sh

cbsd jcreate jname=webapp ip4_addr=10.0.0.10 ver=14.2

cbsd jstart webapp

cbsd jlogin webapp

cbsd stores jail configurations in its database and generates the underlying jail.conf entries. This means you interact with cbsd commands rather than editing configuration files directly.

bhyve and Xen Support

cbsd is the only jail manager that also manages bhyve VMs and Xen guests. If your infrastructure uses both jails and VMs, cbsd provides a unified management layer:

sh

cbsd bcreate jname=linuxvm vm_os_type=linux vm_os_profile="cloud-CentOS-stream-9-x86_64"

cbsd bstart linuxvm

Web UI (ClonOS)

cbsd offers ClonOS, a web-based management interface for creating and managing jails and VMs through a browser. ClonOS is a separate project built on top of cbsd. It provides a dashboard, resource monitoring, and point-and-click jail/VM management.

Multi-Node Support

cbsd supports distributed operation across multiple FreeBSD hosts. Jails can be migrated between nodes, and cbsd coordinates resource allocation across the cluster. This is more manual than pot's Nomad integration but does not require external orchestration software.

Pros

- Most feature-rich jail manager. Handles jails, bhyve, and Xen.

- Web UI via ClonOS for administrators who prefer a graphical interface.

- Multi-node support for distributed jail management.

- Mature project with years of development.

- Extensive customization options for networking, storage, and resource limits.

- Good ZFS integration with snapshots and replication.

Cons

- Steepest learning curve of any jail manager. The number of subcommands and options is large.

- The SQLite database layer adds complexity compared to simpler tools.

- Documentation exists but is dense and sometimes assumes prior knowledge.

- The framework's own directory structure and conventions can conflict with expectations if you are used to standard jail.conf workflows.

- Heavier footprint than shell-based tools.

---

AppJail

AppJail is the newest serious jail manager for FreeBSD. Its defining feature is Makejail, a build system modeled after Dockerfiles. If you come from the Docker world and want a similar build-then-deploy workflow on FreeBSD jails, AppJail provides the closest equivalent.

Install

sh

pkg install appjail

Enable:

sh

sysrc appjail_enable=YES

How It Works

AppJail manages jails with a command structure similar to other tools, but its Makejail build system is what sets it apart:

sh

appjail quick webapp virtualnet="development:webapp default" overwrite start

A Makejail is a text file with directives that describe how to build a jail:


OPTION start

OPTION resolv

OPTION virtualnet=development:webapp default

PKG nginx

COPY www/ /usr/local/www/

SYSRC nginx_enable=YES

SERVICE nginx start

You build a jail from a Makejail:

sh

appjail makejail -f Makejail

This is conceptually identical to docker build reading a Dockerfile. The Makejail can be committed to version control and shared.

Networking

AppJail has strong virtual networking support. It can create and manage virtual networks that jails attach to, with NAT handled automatically:

sh

appjail network add development 10.0.0.0/24

Jails connected to the same virtual network can communicate directly. External access is handled through NAT or port forwarding.

Pros

- Makejail system provides a Dockerfile-like build workflow.

- Active development with frequent commits and releases.

- Good virtual networking with automatic NAT.

- Growing library of community Makejails.

- Clean command structure.

- Supports images and image registries for pre-built jails.

Cons

- Newest of the major jail managers. Less production mileage than Bastille or cbsd.

- Smaller community, though growing.

- Some features are still maturing.

- Documentation is improving but not yet as comprehensive as Bastille's.

---

Manual Jails with jail.conf

Not every deployment needs a jail manager. If you run a small number of static jails that rarely change, FreeBSD's built-in jail.conf and the jail command may be all you need.

When Manual Makes Sense

- You have 1-5 jails that are set up once and left running.

- You do not need templating, mass updates, or fleet management.

- You want to understand exactly what is happening under the hood with no abstraction layer.

- You are learning jails and want the fundamentals before adopting a tool.

Basic Setup

Create the jail filesystem from a release:

sh

fetch https://download.FreeBSD.org/releases/amd64/14.2-RELEASE/base.txz

mkdir -p /jails/webapp

tar -xf base.txz -C /jails/webapp

Configure /etc/jail.conf:


webapp {

host.hostname = "webapp.local";

ip4.addr = "lo1|10.0.0.2/24";

path = "/jails/webapp";

exec.start = "/bin/sh /etc/rc";

exec.stop = "/bin/sh /etc/rc.shutdown";

mount.devfs;

allow.raw_sockets;

}

Start and manage:

sh

service jail start webapp

jls

jexec webapp /bin/sh

For a complete walkthrough, see our [FreeBSD jails guide](/blog/freebsd-jails-guide/).

When to Move to a Tool

Move to a jail manager when you find yourself writing shell scripts to automate jail creation, templating base configurations, managing ZFS snapshots manually, or coordinating VNET bridge interfaces by hand. At that point a dedicated tool saves time and reduces errors.

---

Feature Comparison Table

| Feature | Bastille | iocage | pot | cbsd | AppJail | Manual |

|---|---|---|---|---|---|---|

| Language | sh | Python | sh | sh/C | sh | N/A |

| ZFS Required | No | Yes | Yes | No | No | No |

| ZFS Snapshots | Yes | Yes | Yes | Yes | Yes | Manual |

| VNET Support | Yes | Yes | Yes | Yes | Yes | Manual |

| Templates/Images | Templates | Plugins | Flavors/Images | Profiles | Makejails | No |

| Web UI | No | No | No | ClonOS | No | No |

| Multi-Node | No | No | Nomad driver | Yes | No | No |

| bhyve VMs | No | No | No | Yes | No | No |

| Build System | Templates | Plugins | Flavors | Profiles | Makejail | Scripts |

| Thin Jails | Yes | Yes | Yes | Yes | Yes | Manual |

| Thick Jails | Yes | Yes | Yes | Yes | Yes | Yes |

| Export/Import | Yes | Yes | Yes | Yes | Yes | Manual |

| Active Development | High | Low | Medium | Medium | High | N/A |

---

ZFS Integration Comparison

All jail managers benefit from ZFS, but they use it differently. For a full background on ZFS, see our [ZFS guide](/blog/zfs-freebsd-guide/).

**Bastille** uses ZFS when available. Jails are created as ZFS clones of the release dataset, making creation fast and storage-efficient. bastille snap and bastille export wrap ZFS snapshot and send operations. Bastille falls back gracefully to UFS -- it is the only major jail manager that works equally well without ZFS.

**iocage** requires ZFS. It was built around ZFS from the start. Jail properties are stored as ZFS user properties. Snapshots, clones, replication, and promotion are core operations exposed directly through iocage subcommands. If you want the deepest ZFS integration, iocage's model is the most tightly coupled.

**pot** requires ZFS for its layered image model. Each layer -- base, flavor, and jail -- is a separate ZFS dataset. Layers are shared via clones, so running 20 jails from the same flavor uses minimal extra disk space. pot's export creates compressed ZFS streams suitable for distribution.

**cbsd** works with both ZFS and UFS but strongly favors ZFS. Its snapshot, migration, and replication features depend on ZFS. cbsd stores metadata in SQLite but uses ZFS datasets for jail filesystems when available.

**AppJail** works with ZFS or UFS. When ZFS is available, it uses datasets and clones for efficiency. Its image system benefits from ZFS snapshots for fast image creation.

---

Networking Comparison

VNET (virtual network stack) support is the most important networking decision for jails. VNET gives each jail its own network stack -- its own interfaces, routing table, and firewall state. Without VNET, jails share the host's network stack and get an IP alias.

For background on VNET and jail networking modes, see our [FreeBSD jails guide](/blog/freebsd-jails-guide/).

**Bastille** supports VNET with --vnet at creation time. It creates epair interfaces and attaches one end to a bridge, the other to the jail. You configure the bridge and PF rules. Bastille also supports shared-IP mode and loopback with PF redirection.

**iocage** has mature VNET support. Setting vnet=on and assigning a vnet_default_interface handles bridge and epair creation automatically. iocage was one of the first tools to make VNET jails easy. It supports multiple VNET interfaces per jail.

**pot** supports VNET through its bridge networking mode. Jails can be connected to private bridges for inter-jail communication or public bridges for external access. pot handles bridge creation and epair management.

**cbsd** offers the most networking options: shared IP, VNET with bridges, VALE switches for high-performance virtual switching, and custom topologies. cbsd can configure complex multi-interface setups with different jails on different VLANs or bridge groups. The tradeoff is configuration complexity.

**AppJail** provides virtual networks as a first-class concept. You create named networks, assign address ranges, and attach jails to them. NAT is configured automatically. This is the most Docker-like networking model.

**Manual jails** support VNET by adding vnet to jail.conf and manually creating bridge and epair interfaces in exec.prestart scripts. It works but requires more shell scripting than any managed tool.

| Networking Feature | Bastille | iocage | pot | cbsd | AppJail |

|---|---|---|---|---|---|

| Shared IP | Yes | Yes | Yes | Yes | Yes |

| VNET | Yes | Yes | Yes | Yes | Yes |

| Auto Bridge Setup | Yes | Yes | Yes | Yes | Yes |

| Multiple Interfaces | Manual | Yes | Yes | Yes | Yes |

| VALE Switch | No | No | No | Yes | No |

| Auto NAT | PF rdr | No | Yes | Yes | Yes |

| Virtual Networks | No | No | Bridge-based | Yes | Yes |

---

Decision Guide

**Choose Bastille if** you want a clean, well-maintained jail manager with good defaults, solid templates, and an active community. It covers the needs of the majority of FreeBSD jail users -- from hobbyists running a few jails on a home server to administrators managing production deployments on single hosts or small clusters.

**Choose pot if** you are building multi-host infrastructure and want to schedule jails the way Nomad schedules Docker containers. pot's Nomad driver is production-quality and provides service discovery, health checking, and automatic rescheduling that no other jail manager offers natively.

**Choose cbsd if** you need to manage both jails and bhyve VMs from one tool, you want a web UI, or you have complex multi-node topologies that require features like VALE switches, live migration, or custom profiles. Be prepared for a steeper learning curve.

**Choose AppJail if** you come from the Docker world and want a Makejail-based build workflow. AppJail's model will feel familiar and its virtual networking is the closest to Docker's among jail managers. Check that its maturity level meets your production requirements.

**Stay with iocage if** you have an existing deployment that works. Migrate to Bastille or cbsd if you need active upstream support or features iocage does not provide.

**Use manual jails if** you have a handful of static jails, you want full control with no abstraction, or you are learning jail fundamentals. Move to a tool when the management overhead of shell scripts exceeds the overhead of learning a jail manager.

---

FAQ

Which jail manager is easiest to learn?

Bastille. Its commands are intuitive (bastille create, bastille start, bastille template), the documentation is clear, and the template system lets you set up complex stacks without writing custom scripts. From installation to a running jail takes about five minutes.

Can I migrate jails between different managers?

Not directly. Each tool stores metadata and organizes filesystems differently. However, every tool ultimately creates a standard FreeBSD jail. You can export the jail's filesystem as a tarball or ZFS snapshot and import it into another tool, then recreate the metadata (networking, properties, mount points) manually. The base filesystem is portable; the management layer is not.

Do I need ZFS to use a jail manager?

Bastille and AppJail work on both ZFS and UFS. cbsd works on both but is better on ZFS. iocage and pot require ZFS. If you are running FreeBSD on a VPS with UFS, Bastille is the clear choice. If you control your storage and can use ZFS, any tool will work and all benefit from ZFS snapshots and clones. See our [ZFS guide](/blog/zfs-freebsd-guide/) for setup instructions.

How do jail managers compare to Docker on Linux?

FreeBSD jails are kernel-level isolation. Docker is a userspace runtime that uses Linux cgroups and namespaces. Jails do not need a daemon -- jail.conf is read by the kernel. The isolation model is different: jails provide stronger default isolation (no shared IPC namespace, no PID namespace leakage) but lack the OCI image ecosystem and the massive tooling around Docker/Kubernetes. AppJail's Makejail system is the closest to Docker's build workflow. pot with Nomad is the closest to Docker with a scheduler. For a detailed comparison, read [jails vs Docker](/blog/freebsd-jails-vs-docker/).

Can I run Linux binaries inside a FreeBSD jail?

Yes, using FreeBSD's Linux compatibility layer (Linuxulator). You enable linux and linux64 modules, install the linux_base package inside the jail, and set allow.mount.linprocfs and allow.mount.linsysfs in the jail configuration. Bastille, cbsd, and AppJail can all manage Linux-compat jails. This does not give you a full Linux kernel -- it translates Linux syscalls to FreeBSD equivalents -- but it runs most Linux binaries including commercial software and many container images.

Is there a jail manager with Kubernetes-like orchestration?

The closest option is pot with HashiCorp Nomad. Nomad provides job scheduling, service discovery (via Consul), health checking, rolling updates, and canary deployments. It is less complex than Kubernetes but covers the core orchestration needs. There is no Kubernetes-native jail runtime; Kubernetes is tightly coupled to Linux containers and OCI images.

How do I update jails managed by these tools?

Each tool has its own update workflow:

- **Bastille:** bastille update TARGET runs freebsd-update inside the jail. bastille upgrade handles release upgrades.

- **iocage:** iocage update TARGET or iocage upgrade for release changes.

- **pot:** Update the base layer and recreate jails from the updated image.

- **cbsd:** cbsd jupgrade for release upgrades, cbsd jset to modify properties.

- **AppJail:** Rebuild from an updated Makejail or update in place with appjail update.