Back to all posts
6 min read

Blackship vs The Galaxy: FreeBSD Jail Managers Compared

Blackship vs The Galaxy: FreeBSD Jail Managers Compared

Every few months, someone asks on the FreeBSD forums: “Which jail manager should I use?” The answers are always the same: “CBSD if you want everything. Bastille if you want simple. iocage if… wait, is iocage still maintained?”

Here’s the actual breakdown.

The Contenders

Docker/Podman (Linux-first, FreeBSD adapters)

What they are: OCI container runtimes that can use jails as their isolation primitive on FreeBSD.

The good: You get the entire Docker/OCI ecosystem. Images from Docker Hub. Compose files. The tooling your team already knows.

The brutal truth: You’re running Linux container tooling on a BSD system. Podman uses ocijail under the hood. Containerd uses runj. Both work, but you’re adding abstraction layers on top of jails instead of using jails directly. Also, no VNET support in OCI containers on FreeBSD. No ZFS integration beyond basic image layers.

Use when: Your team speaks Docker and you need portability over performance.

Bastille

What it is: Shell-based jail automation. Zero dependencies. Docker-like templates called “Bastillefile”.

The good: Simple, well-documented, active development. Recent versions (1.0+) handle both -V and -B VNET jails dynamically. Dual-stack networking (IPv4+IPv6). DHCP support. The naming convention for epairs (e0a_jailname, e0b_jailname) is genuinely smart.

The brutal truth: It’s shell scripts. For simple jails, that’s fine. For complex orchestration with health checks, circuit breakers, and dependency graphs? You’ll be layering scripts on top of scripts.

Use when: You want straightforward jail management without learning a new paradigm.

CBSD

What it is: The everything tool. Jails, bhyve VMs, QEMU, Xen. Web UI. Clustering. CARP/HAST integration.

The good: If you need it, CBSD probably has it. People run 150+ VMs with it. Rock solid. SQLite backend. Great support from the maintainer (Ole). Been around since 2013.

The brutal truth: It’s massive. Users are split into two camps: “CBSD is awesome” and “CBSD is too complicated.” The learning curve is real. If you just need jails, you’re carrying a lot of VM infrastructure you’ll never use.

Use when: You’re building a full virtualization platform with jails AND bhyve VMs, or you need clustering features.

iocage

What it was: The ZFS-first jail manager that everyone loved around 2016-2018.

The brutal truth: Development stalled. The Python rewrite fragmented the community. People still use it, but “is iocage maintained?” is a legitimate question.

Use when: You have legacy iocage jails and migration would be painful.

pot

What it is: Lightweight jail manager focused on simplicity.

The good: Minimal, does what it says.

The brutal truth: Limited feature set compared to CBSD or even Bastille.

Use when: You want minimal and your needs are minimal.

Blackship: What’s Different

I built Blackship because existing tools fell into two camps:

  1. Too simple: No dependency management, no health checks, no state machine lifecycle
  2. Too complex: Web UIs and clustering when I just need jails

Blackship is the middle ground. Here’s what it actually does differently:

State Machine Lifecycle

Every jail has explicit states: Stopped → Starting → Running → Stopping → Failed. Invalid transitions are rejected at runtime with clear errors. No more “is this jail actually running or in some weird half-state?”

blackship up web
# Stopped → Starting → (hooks run) → Running

blackship down web
# Running → Stopping → (hooks run) → Stopped

Dependency Graphs (petgraph)

Define dependencies. Blackship figures out the order.

[[jails]]
name = "app"
depends_on = ["cache", "database"]

[[jails]]
name = "cache"

[[jails]]
name = "database"

Start order: database → cache → app Stop order: app → cache → database

Not rocket science, but you’d be surprised how many tools don’t do this.

Circuit Breakers + Exponential Backoff

The Warden supervisor doesn’t just restart crashed jails blindly. It uses:

  • Exponential backoff (1s → 2s → 4s → … → 60s max)
  • Circuit breaker (after 5 failures, stop trying for 5 minutes)
  • Per-jail restart state tracking

No more restart loops hammering your system.

Jailfile Templates

Docker-like build syntax:

FROM 15.0-RELEASE

ARG NGINX_VERSION=1.24
RUN pkg install -y nginx-${NGINX_VERSION}
RUN sysrc nginx_enable=YES

COPY nginx.conf /usr/local/etc/nginx/nginx.conf
EXPOSE 80/tcp
CMD /usr/local/sbin/nginx -g 'daemon off;'

Or TOML if you prefer:

[metadata]
name = "nginx-jail"
from = "15.0-RELEASE"

[[instructions]]
type = "run"
command = "pkg install -y nginx"

ZFS First-Class

Not bolted on. Designed around ZFS.

# Snapshot before risky operation
blackship snapshot create web pre-update

# Something broke?
blackship down web
blackship snapshot rollback web pre-update --force
blackship up web

# Clone for testing
blackship clone web@pre-update web-test

# Export with ZFS send (fast)
blackship export web -o backup.zfs --zfs-send

VNET + PF Integration

Bridge-based networking with epair interfaces. PF anchors for port forwarding (no editing /etc/pf.conf).

blackship network create default --subnet 10.0.1.0/24 --gateway 10.0.1.1 --bridge blackship0
blackship expose web -p 80
blackship expose web -p 443 -I 192.168.1.100  # Bind to specific IP

Health Checks That Matter

All command-based. Exit 0 = healthy. Simple.

[[jails.healthcheck.checks]]
name = "http"
command = "curl -sf http://localhost:8080/health"
target = "jail"
interval = 30
timeout = 10
retries = 3

The Honest Comparison Table

FeatureDocker/PodmanBastilleCBSDBlackship
FreeBSD NativeAdapter layerYesYesYes
VNET SupportNoYesYesYes
ZFS IntegrationBasicManualYesFirst-class
Dependency OrderingComposeNoManualAutomatic
State MachineImplicitNoNoExplicit
Health ChecksYesManualYesBuilt-in
Circuit BreakerNoNoNoYes
Jailfile/TemplateDockerfileBastillefileTemplatesJailfile
bhyve VMsNoNoYesNo
Web UIPortainerNoYesNo
ComplexityMediumLowHighMedium

When to Use What

Use Docker/Podman if your team already knows Docker and you need image portability.

Use Bastille if you want simple jail management with minimal learning curve.

Use CBSD if you’re building a full virtualization platform with jails + VMs + clustering.

Use Blackship if you want:

  • State machine lifecycle with clean transitions
  • Automatic dependency ordering
  • Circuit breaker protection against restart loops
  • ZFS-first design without the VM overhead
  • Docker-like build templates without the Docker abstraction layer

The Real Difference

Most jail managers treat jails as file systems with networking attached. Start the jail, hope for the best, restart on crash.

Blackship treats jails as state machines with lifecycle hooks, health monitoring, and resilience patterns. The same patterns you’d use for production microservices, applied to FreeBSD jails.

That’s the pitch. Use what fits your workflow.

cargo install blackship

GitHub | Docs

🔗 Interstellar Communications

No transmissions detected yet. Be the first to establish contact!

• Link to this post from your site• Share your thoughts via webmention• Join the IndieWeb conversation

Related Posts