aoitcloud

FreeBSD

Getting started with FreeBSD jails

Jails are FreeBSD's native lightweight virtualisation - process and filesystem isolation without the overhead of a full VM. Here's the concept and a first working example.

10 January 2025 4 min read

Jails are arguably FreeBSD’s signature feature. They’ve been part of the base system since FreeBSD 4.0 in 2000, which makes them older than most of the container technology people associate with Linux today, and the underlying idea is the same one that later inspired those tools: isolate a set of processes so they have their own view of the filesystem, their own network configuration, and their own set of users, all while sharing the host’s kernel.

What a jail actually is

A jail is a restricted environment created with the jail facility built into the FreeBSD kernel. Processes running inside a jail can see only their own filesystem root, their own process list, and (if you configure it that way) their own IP address – they’re unaware of, and can’t interact with, anything outside the jail. This is genuine OS-level virtualisation, not a chroot with a few extra restrictions bolted on: jails also isolate networking and, depending on configuration, resource limits, in a way a plain chroot never did.

It’s a different model from full virtualisation (like running FreeBSD inside VMs on a hypervisor). There’s no separate kernel per jail and no virtual hardware being emulated – every jail shares the host’s single FreeBSD kernel. That’s what makes jails lightweight: starting one is close to instant, and the overhead compared to running the same processes unjailed is minimal.

A basic manual jail with jail.conf

For a small number of jails, FreeBSD’s built-in configuration file, /etc/jail.conf, is perfectly manageable by hand. First, create a filesystem tree for the jail to live in and extract a base system into it – this example creates a jail called webserver:

mkdir -p /jails/webserver
cd /jails/webserver
fetch https://download.freebsd.org/releases/amd64/amd64/15.1-RELEASE/base.txz
tar -xf base.txz -C /jails/webserver --unlink

Then define the jail in /etc/jail.conf:

webserver {
  path = "/jails/webserver";
  host.hostname = "webserver.example.com";
  ip4.addr = "192.0.2.10";
  interface = "vtnet0";
  exec.start = "/bin/sh /etc/rc";
  exec.stop = "/bin/sh /etc/rc.shutdown";
  mount.devfs;
}

Enable and start jails via rc.conf and the service command, the same way you’d enable any other FreeBSD service:

sysrc jail_enable="YES"
service jail start webserver

To get a shell inside the running jail:

jexec webserver /bin/sh

From inside, install packages, configure services, and manage it largely like any other FreeBSD system – because, from the jail’s perspective, it is one.

When you outgrow hand-editing jail.conf

Hand-editing jail.conf and manually extracting base systems is fine for one or two jails, but it gets tedious once you’re managing several, and it’s easy to make mistakes with networking or filesystem paths. For anything beyond a handful of jails, the FreeBSD community has largely converged on Bastille as the modern tool of choice – it automates jail creation, templating, and lifecycle management (start, stop, snapshot, destroy) while still ultimately configuring things through the same jail.conf-based mechanism underneath. It’s available as a package:

pkg install bastille

Worth noting: Bastille is a management layer over FreeBSD’s native jail system, not a separate virtualisation technology of its own – everything it does, you could also do by hand with jail.conf, it just makes doing it repeatedly and at scale far less tedious.

Realistic uses on a single VPS

The most common practical reason to reach for jails on a VPS is separating services that you’d rather not run directly on the host, or that you want to be able to rebuild, back up, or destroy independently of everything else:

  • Running a mail server in one jail and a web server in another, so a misconfiguration or compromise in one doesn’t directly expose the other.
  • Isolating a database server from the application server that talks to it, even though both live on the same physical VPS.
  • Testing a risky upgrade or configuration change inside a throwaway jail before touching your production services.
  • Giving each client or project its own isolated environment on a single VPS, without the overhead of separate virtual machines.

Jails won’t help you run software that needs a different kernel or a different operating system entirely – for that you’d need full virtualisation. But for isolating multiple FreeBSD-native services on one host, they’re hard to beat for how little overhead they add.

Get in touch

Drop our team a message today