Warning - If you don't set JAIL, below, this should just error out for being syntactically incorrect, but if you are lucky it might just eat your base system. I thought about adding a molly-guard, but decided not to for the sake of simplicity.

These are how I'm populating a "base" jail, that I can then use (via zfs send/receive) to populate other jails. This is my first time doing it with pkgbase. Note that "base" specifically here refers to a dataset that serves as the basis for other jails I create.

# Set a base from which to work.
JAIL=/var/jail/base

# Create requisite directories.
mkdir $JAIL/dev
mkdir -p $JAIL/etc/pkg
mkdir -p $JAIL/usr/share/keys
mkdir -p $JAIL/var/db/pkg/repos

# Populate requisite files.
cp -r /usr/share/keys $JAIL/usr/share
cp /etc/resolv.conf $JAIL/etc/

# We'll need /dev.
mount -t devfs devfs $JAIL/dev

pkg -r $JAIL update
pkg -r $JAIL install FreeBSD-set-minimal-jail-15.1 pkg

# Post-install clean-up.
pkg -r $JAIL clean -a
sed -i .bak 's/enabled: no/enabled: yes/' $JAIL/etc/pkg/FreeBSD.conf
umount $JAIL/dev

Please tell me if there are improvements that should be included.

Tested with FreeBSD 15.1 on AMD64.

If you want to be lazy, you can script it up. The following includes some defaults for my system, but you don't want to just copy this anyway. Use it as a model to write your own. (Maximum laziness can be achieved by using the names and layouts I like, after which you *can* just use this script unmodified.)

# cat bin/makejail 
#!/bin/sh

# Written in 2026 by Mason Loring Bliss <mason@blisses.org>
#
# To the extent possible under law, the author(s) have dedicated all
# copyright and related and neighboring rights to this software to the
# public domain worldwide. This software is distributed without any
# warranty.
#
# You should have received a copy of the CC0 Public Domain Dedication
# along with this software. If not, see:
#
#     http://creativecommons.org/publicdomain/zero/1.0/

JAIL=/var/jail/$1

if [ -z $1 ]; then
    printf "Supply a jail name.\n"
    exit
fi

if [ -d $JAIL ]; then
    printf "$JAIL already exists\n"
    exit
fi

read -p "Really create $JAIL? [y/N]: " REALLY
REALLY=$(echo $REALLY | tr a-z A-Z)
if [ "x$REALLY" != "xY" ]; then
    exit
fi

# Create a dataset
zfs create tank$JAIL

# Create requisite directories.
mkdir $JAIL/dev
mkdir -p $JAIL/etc/pkg
mkdir -p $JAIL/usr/share/keys
mkdir -p $JAIL/var/db/pkg/repos

# Populate requisite files.
cp -r /usr/share/keys $JAIL/usr/share
cp /etc/resolv.conf $JAIL/etc/

# We'll need /dev.
mount -t devfs devfs $JAIL/dev

pkg -r $JAIL update
pkg -r $JAIL install -y FreeBSD-set-minimal-jail-15.1 pkg

# Post-install clean-up.
pkg -r $JAIL clean -ya
sed -i .bak 's/enabled: no/enabled: yes/' $JAIL/etc/pkg/FreeBSD.conf
umount $JAIL/dev

zfs snap tank$JAIL@$(date +%Y%m%d%H%M%S-initial)


CategoryHowTo

MasonLoringBliss/PkgBaseChroot (last edited 2026-07-05T04:22:26+0000 by MasonLoringBliss)