Synopsis #
Bastille manages FreeBSD jails, release files, networking, and repeatable templates. It does not replace the jail subsystem: a Bastille container is a FreeBSD jail, and the host remains responsible for its kernel, firewall, storage, and backups.
This procedure creates a conventional private-address jail after running Bastille’s interactive setup. The setup can enable and start PF and change host networking. Use a system console or another recovery path when preparing a remote host.
Check the host first #
Identify the host release, interfaces, firewall state, and ZFS pools:
$ freebsd-version -ku
$ ifconfig -l
# service pf status
$ zpool list
A jail cannot run a newer FreeBSD userland than its host kernel. Use the host’s release for the first jail unless a documented compatibility requirement calls for an older supported release.
If PF already carries production rules, read those rules and the Bastille setup documentation before proceeding. Do not allow an installer to become the first time the firewall configuration is reviewed.
Install and enable Bastille #
Install the official FreeBSD package and enable its startup integration:
# pkg install bastille
# sysrc bastille_enable=YES
Bastille is not a continuously running daemon. Its rc script starts and stops configured jails with the host.
Review the installed configuration before setup:
# less /usr/local/etc/bastille/bastille.conf
# bastille setup
The default setup creates the bastille0 loopback interface, adds PF rules for private jail addresses, prepares storage, and can enable and start PF. Bastille also supports separate bridge, vnet, firewall, and storage setup modes. Use those only after selecting the intended network model.
After setup, confirm the resulting host state rather than assuming it succeeded:
$ ifconfig bastille0
# service pf status
$ sysrc bastille_enable pf_enable
Bootstrap a matching release #
The bootstrap step downloads and verifies the release files from which jails are created. On a 15.1-RELEASE host, bootstrap 15.1 and apply its available updates:
# bastille bootstrap 15.1-RELEASE update
On a 15.0 or 14.4 host, substitute that exact release. Do not copy a newer release name onto an older host.
List the available release after bootstrap:
# bastille list release
Create the jail #
Choose an unused address from the private network configured by bastille setup. This example uses 10.17.89.10/24:
# bastille create firstjail 15.1-RELEASE 10.17.89.10/24
# bastille list jail
Again, substitute the host’s supported release when it is not 15.1. Confirm the jail’s view of the release and outbound network:
# bastille cmd firstjail freebsd-version
# bastille cmd firstjail fetch -qo /dev/null https://www.freebsd.org/
The second command verifies DNS, routing, PF, and HTTPS together. If it fails, inspect those layers separately before adding port-forwarding rules.
Manage software and services #
Use Bastille’s subcommands to keep the administrative boundary visible:
# bastille pkg firstjail install nginx
# bastille sysrc firstjail nginx_enable=YES
# bastille service firstjail nginx start
# bastille service firstjail nginx status
This installs and starts nginx inside the jail. It does not expose port 80 outside the private network. Incoming access requires an intentional PF rule or bastille rdr mapping. Publish only the ports that the service needs.
Use an interactive console only when a targeted subcommand is insufficient:
# bastille console firstjail
Exit the jail shell before changing its host-side network or storage configuration.
Stop or remove the jail #
Stopping preserves the jail and its data:
# bastille stop firstjail
bastille destroy firstjail permanently removes the jail. Confirm its datasets, mounts, templates, and backups before using that command. A ZFS snapshot on the same host does not replace an independent backup.
Choose the next network model deliberately #
The default private network is appropriate for learning and for services reached through explicit redirection. Other workloads may need:
- VNET, when the jail needs its own network stack and an address on the local network;
- bridged VNET, when an existing bridge or isolated network must be selected explicitly;
- an alias or shared interface, when a separate network stack is unnecessary;
- a private NAT network, when outbound access and narrowly published inbound ports are preferred.
These modes change the host’s bridge, epair, address, routing, and firewall responsibilities. A follow-up guide will treat them as an architecture decision rather than a list of flags.
After the first jail works, record its base and package maintenance procedure with Update and upgrade Bastille jails before it becomes a production service.