Jails are FreeBSD's native containers — lightweight isolated environments where you can run software without it being able to see (or interfere with) the rest of the system. They predate Docker by more than a decade and feel quite different to use.
How are they different from Docker? No daemon to manage, no image registry, no separate userland for networking. A jail is just a chunk of filesystem and a set of restrictions in jail.conf. The trade-off: there's no public registry of pre-built images. You build what you need from the FreeBSD base.
bastille is a friendly front-end that handles the fiddly bits.
Step 1: Install bastille and enable it
sudo pkg install bastille
sudo sysrc bastille_enable="YES"
Step 2: Download a base FreeBSD to clone from
sudo bastille bootstrap 15.0-RELEASE
This downloads a clean copy of the FreeBSD base — the seed for every jail you'll create. It takes a few minutes the first time.
Step 3: Create your first jail
sudo bastille create webby 15.0-RELEASE 10.10.10.10
Three arguments:
webby— the jail's name.15.0-RELEASE— the FreeBSD version to base it on.10.10.10.10— the IP address inside your private jail network.
Step 4: Start it and look around
sudo bastille list # see all jails
sudo bastille start webby
sudo bastille console webby # drop into a shell inside it
You're now in a separate FreeBSD environment. pkg, ls /, all the commands you'd expect — but the processes here can't see anything outside the jail.
Type exit to come back to the host.
Step 5: Install software into the jail
From the host, you don't need to enter the jail to manage it:
sudo bastille pkg webby install nginx
sudo bastille service webby nginx enable
sudo bastille service webby nginx start
The pattern is bastille <verb> <jail-name> <rest of command>. Almost everything you'd do at the prompt has a wrapper.
Step 6: Snapshots and clones
Because jails sit on ZFS, you can snapshot them like boot environments:
sudo bastille zfs webby snapshot good-config
sudo bastille clone webby webby-staging 10.10.10.11
sudo bastille destroy webby-staging
The clone is instant — perfect for testing a config change without risking the working jail.
Why use jails?
- Isolation — a compromised service inside a jail can't reach the host or other jails.
- Low overhead — no virtualisation; jails run at native speed.
- Native — supported by the kernel itself, not bolted on.
Common uses: one jail per service (web, database, mail), throwaway dev environments, or hosting untrusted code.